Classify images on basics of similarity

后端 未结 1 557
温柔的废话
温柔的废话 2021-01-17 01:05

I have 30 ,40 pictures of humans , Which I want to get in Python code . And make group of similar pics . Like 5 pic of john and 10 of peter . like this . I am new in Image

1条回答
  •  醉梦人生
    2021-01-17 01:18

    I would suggest you to do the thing with AWS Rekognition. It's pretty simple. You can achieve what you want in 3 simple steps:

    1. Uploading images with metadata: means you are uploading images of person with their names to s3 to store their info to be referenced later

    2. Indexing of photos : this means adding info tags to faces , this info is stored in dynamodb and this is done with index_faces api

    3. Comparision of photos with indexed faces : this will be achieved with rekognition search_faces_by_image api

    Now part 1 code: batch uploading with metadata

    import boto3
    
    s3 = boto3.resource('s3')
    
    # Get list of objects for indexing
    images=[('image01.jpeg','Albert Einstein'),
          ('image02.jpeg','Candy'),
          ('image03.jpeg','Armstrong'),
          ('image04.jpeg','Ram'),
          ('image05.jpeg','Peter'),
          ('image06.jpeg','Shashank')
          ]
    
    # Iterate through list to upload objects to S3   
    for image in images:
        file = open(image[0],'rb')
        object = s3.Object('rekognition-pictures','index/'+ image[0])
        ret = object.put(Body=file,
                        Metadata={'FullName':image[1]}
                        )
    

    Now part 2 code: Indexing

    from __future__ import print_function
    
    import boto3
    from decimal import Decimal
    import json
    import urllib
    
    print('Loading function')
    
    dynamodb = boto3.client('dynamodb')
    s3 = boto3.client('s3')
    rekognition = boto3.client('rekognition')
    
    
    # --------------- Helper Functions ------------------
    
    def index_faces(bucket, key):
    
        response = rekognition.index_faces(
            Image={"S3Object":
                {"Bucket": bucket,
                "Name": key}},
                CollectionId="family_collection")
        return response
    
    def update_index(tableName,faceId, fullName):
        response = dynamodb.put_item(
            TableName=tableName,
            Item={
                'RekognitionId': {'S': faceId},
                'FullName': {'S': fullName}
                }
            ) 
    
    # --------------- Main handler ------------------
    
    def lambda_handler(event, context):
    
        # Get the object from the event
        bucket = event['Records'][0]['s3']['bucket']['name']
        key = urllib.unquote_plus(
            event['Records'][0]['s3']['object']['key'].encode('utf8'))
    
        try:
    
            # Calls Amazon Rekognition IndexFaces API to detect faces in S3 object 
            # to index faces into specified collection
    
            response = index_faces(bucket, key)
    
            # Commit faceId and full name object metadata to DynamoDB
    
            if response['ResponseMetadata']['HTTPStatusCode'] == 200:
                faceId = response['FaceRecords'][0]['Face']['FaceId']
    
                ret = s3.head_object(Bucket=bucket,Key=key)
                personFullName = ret['Metadata']['fullname']
    
                update_index('family_collection',faceId,personFullName)
    
            # Print response to console
            print(response)
    
            return response
        except Exception as e:
            print(e)
            print("Error processing object {} from bucket {}. ".format(key, bucket))
           raise e
    

    Now part 3 code : Compare

    import boto3
    import io
    from PIL import Image
    
    rekognition = boto3.client('rekognition', region_name='eu-west-1')
    dynamodb = boto3.client('dynamodb', region_name='eu-west-1')
    
    image = Image.open("group1.jpeg")
    stream = io.BytesIO()
    image.save(stream,format="JPEG")
    image_binary = stream.getvalue()
    
    
    response = rekognition.search_faces_by_image(
            CollectionId='family_collection',
            Image={'Bytes':image_binary}                                       
            )
    
    for match in response['FaceMatches']:
       print (match['Face']['FaceId'],match['Face']['Confidence'])
    
        face = dynamodb.get_item(
            TableName='family_collection',  
            Key={'RekognitionId': {'S': match['Face']['FaceId']}}
            )
    
        if 'Item' in face:
            print (face['Item']['FullName']['S'])
        else:
            print ('no match found in person lookup')
    

    with above compare function you will get the names of faces in photos , then you can decide what you want to do next, like storing photos with same names to a different folder by renaming the photos, this will give photos of different people in different folders

    Prerequisites:

    create a rekognition collection named family_collection

    aws rekognition create-collection --collection-id family_collection --region eu-west-1 
    

    create a dynamodb table named family_collection

    aws dynamodb create-table --table-name family_collection \
    --attribute-definitions AttributeName=RekognitionId,AttributeType=S \
    --key-schema AttributeName=RekognitionId,KeyType=HASH \
    --provisioned-throughput ReadCapacityUnits=1,WriteCapacityUnits=1 \
    --region eu-west-1
    

    0 讨论(0)
提交回复
热议问题