Home > Back-end >  AWS rekognition Request has invalid image format
AWS rekognition Request has invalid image format

Time:10-07

I get this error when i try to compare two images from my s3 bucket, i follow the functions rules to get an image from S3Object with correct name and s3 bucket name but i throws the Invalid image format exception. Maybe it has to be as a base64 or bytebuffer? i dont understand then why there is a function to get from S3Object.

My code is simple and as follows:

String reference = "reference.jpg";
        String target = "selfie.jpg";
        String bucket = "pruebas";
        
        CompareFacesRequest request = new CompareFacesRequest()
                .withSourceImage(new Image().withS3Object(new S3Object()
                        .withName(reference).withBucket(bucket)))
                .withTargetImage(new Image().withS3Object(new S3Object()
                        .withName(target).withBucket(bucket)))
                .withSimilarityThreshold(similarityThreshold);

        AmazonRekognition rekognitionClient = AmazonRekognitionClientBuilder.standard()
                .withRegion(Regions.US_EAST_1).build();
        CompareFacesResult compareFacesResult= rekognitionClient.compareFaces(request);

The exception is thrown in compareFaces(request) the last line.

this is main part of the error:

Exception in thread "main" com.amazonaws.services.rekognition.model.InvalidImageFormatException: Request has invalid image format (Service: AmazonRekognition; Status Code: 400; Error Code: InvalidImageFormatException; 

The images are in AWS S3 and my credentials for rekognition have permission to read from S3. So in that part is not the error.

UPDATE CODE:

public static void main(String[] args) throws FileNotFoundException {
        Float similarityThreshold = 70F;

        String reference = "reference.jpg";
        String target = "target.jpg";
        String bucket = "pruebas";

        ProfileCredentialsProvider credentialsProvider = ProfileCredentialsProvider.builder().profileName("S3").build();
        Region region = Region.US_EAST_1;
        S3Client s3 = S3Client.builder()
                .region(region)
                .credentialsProvider(credentialsProvider)
                .build();

        byte[] sourceStream = getObjectBytes(s3, bucket,reference);
        byte[] tarStream = getObjectBytes(s3, bucket, target);

        SdkBytes sourceBytes = SdkBytes.fromByteArrayUnsafe(sourceStream);
        SdkBytes targetBytes = SdkBytes.fromByteArrayUnsafe(tarStream);
        Image souImage = Image.builder()
                .bytes(sourceBytes)
                .build();

        Image tarImage = Image.builder()
                .bytes(targetBytes)
                .build();

        CompareFacesRequest request = CompareFacesRequest.builder()
                .sourceImage(souImage)
                .targetImage(tarImage)
                .similarityThreshold(similarityThreshold).build();

        RekognitionClient rekognitionClient = RekognitionClient.builder()
                .region(Region.US_EAST_2).build();


        CompareFacesResponse compareFacesResult= rekognitionClient.compareFaces(request);
        List<CompareFacesMatch> faceDetails = compareFacesResult.faceMatches();
        for (CompareFacesMatch match: faceDetails){
            ComparedFace face= match.face();
            BoundingBox position = face.boundingBox();
            System.out.println("Face at "   position.left().toString()
                      " "   position.top()
                      " matches with "   face.confidence().toString()
                      "% confidence.");

        }
        List<ComparedFace> uncompared = compareFacesResult.unmatchedFaces();

        System.out.println("There was "   uncompared.size()
                  " face(s) that did not match");
        System.out.println("Source image rotation: "   compareFacesResult.sourceImageOrientationCorrection());
        System.out.println("target image rotation: "   compareFacesResult.targetImageOrientationCorrection());
    }

    public static byte[] getObjectBytes (S3Client s3, String bucketName, String keyName) {

        try {
            GetObjectRequest objectRequest = GetObjectRequest
                    .builder()
                    .key(keyName)
                    .bucket(bucketName)
                    .build();

            ResponseBytes<GetObjectResponse> objectBytes = s3.getObjectAsBytes(objectRequest);
            return objectBytes.asByteArray();

        } catch (S3Exception e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
        return null;
    }

CodePudding user response:

Try using AWS SDK for Java V2 - not the old V1 lib. Using V2 is strongly recommended over V1 and is best practice.

Here is the V2 code that works fine to compare faces. In this example, notice that you have to get the image into a SdkBytes object. It does not matter where the image is located as long as you get it into SDKBytes. The image can be in an S3 bucket, the local file system. etc.

You can find this V2 Reckonation example in the AWS Github repo here:

enter image description here

UPDATE

I normally do not touch V1 code at all; however, i was curious. This code worked....

package aws.example.rekognition.image;


import com.amazonaws.regions.Regions;
import com.amazonaws.services.rekognition.AmazonRekognition;
import com.amazonaws.services.rekognition.AmazonRekognitionClientBuilder;
import com.amazonaws.services.rekognition.model.Image;
import com.amazonaws.services.rekognition.model.BoundingBox;
import com.amazonaws.services.rekognition.model.CompareFacesMatch;
import com.amazonaws.services.rekognition.model.CompareFacesRequest;
import com.amazonaws.services.rekognition.model.CompareFacesResult;
import com.amazonaws.services.rekognition.model.ComparedFace;
import java.util.List;

import com.amazonaws.services.rekognition.model.S3Object;

public class CompareFacesBucket {

    public static void main(String[] args) throws Exception{
        Float similarityThreshold = 70F;
        AmazonRekognition rekognitionClient = AmazonRekognitionClientBuilder.standard()
            .withRegion(Regions.US_WEST_2)
            .build();


        String reference = "Lam1.jpg";
        String target = "Lam2.jpg";
        String bucket = "<MyBucket>";

        CompareFacesRequest request = new CompareFacesRequest()
            .withSourceImage(new Image().withS3Object(new S3Object()
                .withName(reference).withBucket(bucket)))
            .withTargetImage(new Image().withS3Object(new S3Object()
                .withName(target).withBucket(bucket)))
            .withSimilarityThreshold(similarityThreshold);

        // Call operation
        CompareFacesResult compareFacesResult = rekognitionClient.compareFaces(request);

        // Display results
        List <CompareFacesMatch> faceDetails = compareFacesResult.getFaceMatches();
        for (CompareFacesMatch match: faceDetails){
            ComparedFace face= match.getFace();
            BoundingBox position = face.getBoundingBox();
            System.out.println("Face at "   position.getLeft().toString()
                  " "   position.getTop()
                  " matches with "   face.getConfidence().toString()
                  "% confidence.");

        }
        List<ComparedFace> uncompared = compareFacesResult.getUnmatchedFaces();

        System.out.println("There was "   uncompared.size()
              " face(s) that did not match");
        System.out.println("Source image rotation: "   compareFacesResult.getSourceImageOrientationCorrection());
        System.out.println("target image rotation: "   compareFacesResult.getTargetImageOrientationCorrection());
    }
}

Output:

enter image description here

The last thing that i can think of as my V1 code works with JPG images and yours does not is your JPG image files may be corrupt or something. I would like to test this code with your images.

  • Related