0

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 processing thing. So my question is which algo is best for this . And I want to do this on AWS lambda function . Any help would be highly appreciated.

P.S (Its my first ever task in this field. Kindly ignore mistakes of tell me to improve them Thanks)

gamer
  • 603
  • 4
  • 20

1 Answers1

1

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
Mausam Sharma
  • 852
  • 5
  • 10
  • hi , Wao thanks for help . its so beautifuly explained . can I ask one thing more ? where these code are to be write ? In lambda function ? and when they will trigger ? thank you so much again – gamer May 17 '18 at 20:26
  • ya , you will write these codes in lambda functions , the indexing function and comparision function will run in lambda , and the photo uploading code you have to run in local machine as you will use it to upload images from your computer in one single go. – Mausam Sharma May 18 '18 at 03:25
  • ya the trigger, lambda will get triggered as soon as you upload any of your image to s3 bucket but beware of one thing that PIL or PILLOW is an image processing python library which is not a standard python library found in lambda environment , hence you will need a custom deployment package and then deploy it . here is how you will do it : **https://docs.aws.amazon.com/lambda/latest/dg/with-s3-example-deployment-pkg.html#with-s3-example-deployment-pkg-python** – Mausam Sharma May 18 '18 at 03:35
  • thanks for reply .Okay got it . I want to upload images from local machine to dropbox then from dropbox to S3 . So I have to change that 'Uploading images with metadata' function on local machine. ? – gamer May 18 '18 at 05:53
  • Should I use 2 databases as 1 in local web application and 1 on aws live server such as dynamodb ? – gamer Jun 04 '18 at 10:19
  • No, dynamodb is enough , u don't need anything else – Mausam Sharma Jun 05 '18 at 06:20
  • And last thing I have to create separate lambda functions for indexing and Compare ? as I have only one editor on aws lambda console – gamer Jun 05 '18 at 12:02
  • can I have your any contact ? need few minutes of you if possible ? – gamer Jun 05 '18 at 21:08
  • DM me on Twitter , @mausam1997 – Mausam Sharma Jun 06 '18 at 03:16
  • there is no option to send you DM , I just followed you from this id @Touseefnoor kindly msg me please – gamer Jun 06 '18 at 05:08
  • and in this answer there is no way define to save my uploaded data to dynamodb ? like I am getting "errorType": "ResourceNotFoundException", "errorMessage": "An error occurred (ResourceNotFoundException) when calling the IndexFaces operation: The collection id: athlete_collection does not exist" – gamer Jun 06 '18 at 07:28