0
votes

Helo everyone,

I am trying to run a face detection on one image based on a collection created from portrait images of few people. the approach used is as below:

  1. Create Collection name "DATABASE"
  2. Index faces from individual pictures and store them in collection "DATABASE".
  3. run index faces on target image and store all faces in a separate collection "toBeDetected".
  4. Use SearchFaces API call to identify all the faces from the target images against Database collection.

however when i try to do that i get invalid parameter exception. I am very new to this and have tried to find the solution to the problem however i have nothing yet. Please help. I have attached the code as below.

public class FRInvoker {

    public static final String COLLECTION_ID_DATABASE = "collectionDatabase";
//  public static final String COLLECTION_ID_TARGET = "toBeDetected";
public static Map<String, String> names = new HashMap<>(); 
private static AmazonRekognition amazonRekognition;


//Configure Credentials
public FRInvoker() {
    AWSCredentials credentials;
    try {
        credentials = new BasicAWSCredentials("XXXXXXXXXXXXXXXXXXXXX", "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
    } catch (Exception e) {
        throw new AmazonClientException("Cannot load the credentials from the credential profiles file. "
                + "Please make sure that your credentials file is at the correct "
                + "location (/Users/userid/.aws/credentials), and is in a valid format.", e);
    }

    amazonRekognition = AmazonRekognitionClientBuilder.standard().withRegion(Regions.US_WEST_2)
            .withCredentials(new AWSStaticCredentialsProvider(credentials)).build();
}



public static void main(String[] args) {
    FRInvoker invoker = new FRInvoker();
    invoker.invokeSystem();
}


private void invokeSystem(){
    AddFacesToRekognitionCollection faceRecognition = new AddFacesToRekognitionCollection(amazonRekognition);
    faceRecognition.addFacesToRecognition(amazonRekognition);

    DetectMultipleFaceHelper detectMultipleFaceHelper = new DetectMultipleFaceHelper(); 
    detectMultipleFaceHelper.detectAllPossibleFaces(amazonRekognition);

    MatchAllFacesInCollection matchFacesInCollection = new MatchAllFacesInCollection();
    matchFacesInCollection.matchAllFacesInTargetCollection(amazonRekognition);
}
}

RekognitionCollectionCreateHelper

public class RekognitionCollectionCreateHelper {

        public void createCollections(AmazonRekognition amazonRekognition, String collectionName) {
            DeleteCollectionRequest request = new DeleteCollectionRequest().withCollectionId(collectionName);
            amazonRekognition.deleteCollection(request);

            try {
                amazonRekognition.createCollection(new CreateCollectionRequest().withCollectionId(collectionName));
            } catch (com.amazonaws.services.rekognition.model.ResourceAlreadyExistsException e) {
                System.out.println(collectionName + "Already Exists");
                System.out.println("Listing Existing Collections : \n");
                this.printCollectionList(amazonRekognition);
            }
        }

        private ListCollectionsResult callListCollections(String paginationToken, int limit,
                AmazonRekognition amazonRekognition) {
            ListCollectionsRequest listCollectionsRequest = new ListCollectionsRequest().withMaxResults(limit)
                    .withNextToken(paginationToken);
            return amazonRekognition.listCollections(listCollectionsRequest);
        }

        private void printCollectionList(AmazonRekognition amazonRekognition){
            int limit = 1;
            ListCollectionsResult listCollectionsResult = null;
            String paginationToken = null;
            do {
                if (listCollectionsResult != null) {
                    paginationToken = listCollectionsResult.getNextToken();
                }
                listCollectionsResult = callListCollections(paginationToken, limit, amazonRekognition);

                List<String> collectionIds = listCollectionsResult.getCollectionIds();
                for (String resultId : collectionIds) {
                    System.out.println(resultId);
                }
            } while (listCollectionsResult != null && listCollectionsResult.getNextToken() != null);
        }

        public void printContentOfCollection(AmazonRekognition amazonRekognition, String collectionName){
            ObjectMapper objectMapper = new ObjectMapper();
            ListFacesResult listFacesResult = null;
              System.out.println("Faces in collection " + collectionName);

              String paginationToken = null;
              do {
                 if (listFacesResult != null) {
                    paginationToken = listFacesResult.getNextToken();
                 }

                 ListFacesRequest listFacesRequest = new ListFacesRequest()
                         .withCollectionId(collectionName)
                         .withMaxResults(1)
                         .withNextToken(paginationToken);

                 listFacesResult =  amazonRekognition.listFaces(listFacesRequest);
                 List<Face> faces = listFacesResult.getFaces();
                 for (Face face: faces) {
                    try {
                        System.out.println(objectMapper.writerWithDefaultPrettyPrinter()
                           .writeValueAsString(face));
                    } catch (JsonProcessingException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                 }
              } while (listFacesResult != null && listFacesResult.getNextToken() !=
                 null);
        }

    }

AddFacesToRekognitionCollection

public AddFacesToRekognitionCollection(AmazonRekognition amazonRekognition) {
            RekognitionCollectionCreateHelper newCollectionCreator = new 
RekognitionCollectionCreateHelper();
    //      newCollectionCreator.deleteAllAwsCollections(amazonRekognition);
            newCollectionCreator.createCollections(amazonRekognition, FRInvoker.COLLECTION_ID_DATABASE);
        }

        public void addFacesToRecognition(AmazonRekognition amazonRekognition) {
            File[] files = getAllImageFiles();
            for (int i = 0; i < files.length; i++) {
                Image image = new 
Image().withBytes(AddFacesToRekognitionCollection.getImageBytes(files[i]));
                String externalImageId = files[i].getName();
                IndexFacesResult indexFacesResult = callIndexFaces(FRInvoker.COLLECTION_ID_DATABASE, externalImageId, "ALL", image,
                        amazonRekognition);
                List<FaceRecord> faceRecords = indexFacesResult.getFaceRecords();
                for (FaceRecord faceRecord : faceRecords) {
                    System.out.println("Image name: " + files[i].getName() + " ::::::::: Faceid is " + faceRecord.getFace().getFaceId());
                    FRInvoker.names.put(faceRecord.getFace().getFaceId(), files[i].getName());
                }
            }

        }


        //Private Helper Methods
        public static ByteBuffer getImageBytes(File file) {
            ByteBuffer imageBytes = null;
            try (InputStream inputStream = new FileInputStream(file)) {
                imageBytes = ByteBuffer.wrap(IOUtils.toByteArray(inputStream));
            } catch (IOException e) {
                e.printStackTrace();
            }
            return imageBytes;
        }

        private IndexFacesResult callIndexFaces(String collectionId, String externalImageId, String attributes, Image image,
                AmazonRekognition amazonRekognition) {
            IndexFacesRequest indexFacesRequest = new IndexFacesRequest().withImage(image).withCollectionId(collectionId);
            return amazonRekognition.indexFaces(indexFacesRequest);

        }

        public static File[] getAllImageFiles() {
            File dir = new File(System.getProperty("user.dir") + "/imageDatabase/");
            System.out.println(dir.getAbsolutePath());
            File[] files = dir.listFiles(new FilenameFilter() {
                public boolean accept(File dir, String name) {
                    return name.toLowerCase().endsWith(".jpg") || name.toLowerCase().endsWith(".png");
                }
            });
            return files;
        }

        //Private Helper Methods
    }

MatchAllFacesInCollection

public class MatchAllFacesInCollection {

        public void matchAllFacesInTargetCollection(AmazonRekognition amazonRekognition) {

            ListFacesRequest request = new ListFacesRequest().withCollectionId(FRInvoker.COLLECTION_ID_TARGET)
                    .withMaxResults(50);
            ListFacesResult response = amazonRekognition.listFaces(request);
            for (Face face : response.getFaces()) {
                SearchFacesRequest searchFaceRequest = new SearchFacesRequest()
                        .withCollectionId(FRInvoker.COLLECTION_ID_DATABASE).withFaceId(face.getFaceId())
                        .withMaxFaces(1).withFaceMatchThreshold(90f);
                SearchFacesResult searchFaceResponse = null;
                try{
                    searchFaceResponse = amazonRekognition.searchFaces(searchFaceRequest);
                    System.out.println(searchFaceResponse.getFaceMatches().get(0).getFace().getFaceId() + " matches best with Highest Matching rate of" + 
                            searchFaceResponse.getFaceMatches().get(0).getSimilarity());
                }catch(com.amazonaws.services.rekognition.model.InvalidParameterException e){
                    e.printStackTrace();
                    System.out.println("Face Not Found :::::: " + face.getFaceId());
                }
            }
        }
    }

DetectMultipleFaceHelper

public class DetectMultipleFaceHelper {

public void detectAllPossibleFaces(AmazonRekognition amazonRekognition) {

    RekognitionCollectionCreateHelper collectionCreaterHelper = new RekognitionCollectionCreateHelper();

    collectionCreaterHelper.createCollections(amazonRekognition, FRInvoker.COLLECTION_ID_TARGET);

    IndexFacesRequest request = new IndexFacesRequest().withCollectionId(FRInvoker.COLLECTION_ID_TARGET)
            .withImage(new Image().withBytes(AddFacesToRekognitionCollection.getImageBytes(new File(System.getProperty("user.dir") + "/ImageToRekognize/target.jpg"))));
    amazonRekognition.indexFaces(request);
}

}

com.amazonaws.services.rekognition.model.InvalidParameterException: faceId was not found in the collection. (Service: AmazonRekognition; Status Code: 400; Error Code: InvalidParameterException; Request ID: e28de8f9-d5b4-11e7-b9db-4fe55f28a54b) Face Not Found :::::: 1becc904-b4b8-417a-92bf-7ade964838c0 at com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleErrorResponse(AmazonHttpClient.java:1638) at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeOneRequest(AmazonHttpClient.java:1303) at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:1055) at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:743) at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:717) at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:699) at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:667) at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:649) at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:513) at com.amazonaws.services.rekognition.AmazonRekognitionClient.doInvoke(AmazonRekognitionClient.java:1458) at com.amazonaws.services.rekognition.AmazonRekognitionClient.invoke(AmazonRekognitionClient.java:1434) at com.amazonaws.services.rekognition.AmazonRekognitionClient.executeSearchFaces(AmazonRekognitionClient.java:1309) at com.amazonaws.services.rekognition.AmazonRekognitionClient.searchFaces(AmazonRekognitionClient.java:1285) at com.siemens.aws.recognition.MatchAllFacesInCollection.matchAllFacesInTargetCollection(MatchAllFacesInCollection.java:23) at com.siemens.aws.recognition.FRInvoker.invokeSystem(FRInvoker.java:79) at com.siemens.aws.recognition.FRInvoker.main(FRInvoker.java:67)

Please help. Thank you!

1

1 Answers

1
votes

I had the same problem, and my solution was to add the indexed faces from the target image to the same collection as the source faces.

The algoritm:

  1. Index faces from source images (mugshots) to collection X and use a unique identifier for ExternalImageId
  2. Index faces in target image (group photo), adding them to collection X and using a common value for ExternalImageId for all found faces ("fromtargetimage")
  3. Loop through the result from the previous operation
  4. Use SearchFaces operation with a request where image = target image, CollectionId = collection X and faceId = faceId for current element in loop.
  5. Among the faces returned from the previous operation, fetch the first which does not have ExternalId = "fromtargetimage"
  6. The ExternalId of the current element in the loop has the information which identifies the person, add that person to a list of found faces and continue looping

After this is done you can use delete faces operation to remove all faces where ExternalId = "fromtargetimage", only keeping the original source image faces.