Facial recognition using Amazon Rekognition on Python
Tags: aws, python, facialrecognition
Published: 2023-03-20 21:21:06

AWS offers a powerful facial recognition service called Amazon Rekognition. In this tutorial, we'll use Python and the AWS SDK to create a simple app that uses the Rekognition service to detect faces in an image.

To get started, you'll need an AWS account and access to the AWS Console. Once you're logged in, navigate to the **Security Credentials** in the right nav bar and create an user with the **AmazonRekognitionFullAccess** permission. Then, create the access key and copy the secret key as well.

Next, you'll need to install the AWS SDK for Python (Boto3) using the following command:

```powershell
pip install boto3
```

Once you've installed Boto3, you can import the necessary libraries in your Python script:

```python
import boto3
from PIL import Image, ImageDraw, ImageFont
```

To use the Rekognition service, you'll need to create a Boto3 client and specify the region:

```python
rekognition = boto3.client('rekognition', aws_access_key_id='<YOUR_ACCESS_KEY>',
aws_secret_access_key='<YOUR_SECRET_KEY>',
                           region_name='us-east-1')
```

For this example, we're going to use the Arial font. You can use whatever you want, first you must download the TTF file for that font.

```python
font = ImageFont.truetype('arial.ttf', 30)
```

Now, we're going to read the image and call the **detect_faces** method.

```python
with open(image_name, 'rb') as image_data:
        response_content = image_data.read()

rekognition_response = rekognition.detect_faces(
        Image={'Bytes': response_content}, Attributes=['ALL'])
```

This is the summarized response from above request.

```json
{
   "FaceDetails":[
      {
         "BoundingBox":{
            "Width":0.1575244814157486,
            "Height":0.26773321628570557,
            "Left":0.7044062614440918,
            "Top":0.35157522559165955
         },
         "AgeRange":{
            "Low":22,
            "High":30
         },
         "Smile":{
            "Value":true,
            "Confidence":96.33894348144531
         },
         "Eyeglasses":{
            "Value":false,
            "Confidence":97.71277618408203
         },
         "Sunglasses":{
            "Value":false,
            "Confidence":99.9967269897461
         },
         "Gender":{
            "Value":"Male",
            "Confidence":99.95927429199219
         },
         "Beard":{
            "Value":true,
            "Confidence":99.96766662597656
         },
         "Mustache":{
            "Value":true,
            "Confidence":88.09671783447266
         },
         "EyesOpen":{
            "Value":true,
            "Confidence":98.2445297241211
         },
         "MouthOpen":{
            "Value":true,
            "Confidence":95.4747314453125
         },
         "Emotions":[
            {
               "Type":"HAPPY",
               "Confidence":99.83971405029297
            },
            {
               "Type":"SURPRISED",
               "Confidence":6.266087532043457
            },
            {
               "Type":"FEAR",
               "Confidence":5.88023567199707
            },
            {
               "Type":"SAD",
               "Confidence":2.1496529579162598
            },
            {
               "Type":"CONFUSED",
               "Confidence":0.06452298164367676
            },
            {
               "Type":"CALM",
               "Confidence":0.018650680780410767
            },
            {
               "Type":"ANGRY",
               "Confidence":0.012820698320865631
            },
            {
               "Type":"DISGUSTED",
               "Confidence":0.011646679602563381
            }
         ],
         "Pose":{
            "Roll":-27.842042922973633,
            "Yaw":-6.863317012786865,
            "Pitch":6.0284576416015625
         },
         "Quality":{
            "Brightness":93.38902282714844,
            "Sharpness":92.22801208496094
         },
         "Confidence":99.99991607666016
      }
   ],
   "ResponseMetadata":{
      "RequestId":"dd18647f-736c-44a9-aaa3-6c9782c657c7",
      "HTTPStatusCode":200,
      "HTTPHeaders":{
         "x-amzn-requestid":"dd18647f-736c-44a9-aaa3-6c9782c657c7",
         "content-type":"application/x-amz-json-1.1",
         "content-length":"23339",
         "date":"Mon, 20 Mar 2023 20:50:38 GMT"
      },
      "RetryAttempts":0
   }
}
```

With the above response, we're going to draw the faces and write the emotions in the image.

```python
image = Image.open(image_name)
image_width, image_height = image.size
draw = ImageDraw.Draw(image)

line_width = 3
for item in rekognition_response.get('FaceDetails'):
    bounding_box = item['BoundingBox']
    width = image_width * bounding_box['Width']
    height = image_height * bounding_box['Height']
    left = image_width * bounding_box['Left']
    top = image_height * bounding_box['Top']

    left = int(left)
    top = int(top)
    width = int(width) + left
    height = int(height) + top

    draw.rectangle(((left, top), (width, height)),
                    outline='red', width=line_width)

    face_emotion_confidence = 0
    face_emotion = None
    for emotion in item.get('Emotions'):
        if emotion.get('Confidence') >= face_emotion_confidence:
            face_emotion_confidence = emotion['Confidence']
            face_emotion = emotion.get('Type')

    draw.text((left, top), face_emotion, 'white', font=font)
```

This is the result calling **image** variable:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oxn1ooor3jdr11l15wyh.png)

This is the full code:

```python
import boto3
from PIL import Image, ImageDraw, ImageFont

rekognition = boto3.client('rekognition', aws_access_key_id='<YOUR_ACCESS_KEY>',
                           aws_secret_access_key='<YOUR_SECRET_KEY>',
                           region_name='us-east-1')

font = ImageFont.truetype('arial.ttf', 30)

def detect_faces_and_emotions(image_name: str):
    with open(image_name, 'rb') as image_data:
        response_content = image_data.read()

    rekognition_response = rekognition.detect_faces(
        Image={'Bytes': response_content}, Attributes=['ALL'])

    print(rekognition_response)
    
    image = Image.open(image_name)
    image_width, image_height = image.size
    draw = ImageDraw.Draw(image)

    line_width = 3
    for item in rekognition_response.get('FaceDetails'):
        bounding_box = item['BoundingBox']
        width = image_width * bounding_box['Width']
        height = image_height * bounding_box['Height']
        left = image_width * bounding_box['Left']
        top = image_height * bounding_box['Top']

        left = int(left)
        top = int(top)
        width = int(width) + left
        height = int(height) + top

        draw.rectangle(((left, top), (width, height)),
                    outline='red', width=line_width)

        face_emotion_confidence = 0
        face_emotion = None
        for emotion in item.get('Emotions'):
            if emotion.get('Confidence') >= face_emotion_confidence:
                face_emotion_confidence = emotion['Confidence']
                face_emotion = emotion.get('Type')

        draw.text((left, top), face_emotion, 'white', font=font)

    return image

result_1 = detect_faces_and_emotions('people.jpg')
result_1
```

In this [repository](https://github.com/cristofima/Python-Amazon-Rekognition) you can find the code, font file and the images.

And that's it! With just a few lines of Python code and the power of AWS Rekognition, you can create a facial recognition app that is capable of detecting faces with its emotions in an image.

**Thanks for reading**

Thank you very much for reading, I hope you found this article interesting and may be useful in the future. If you have any questions or ideas that you need to discuss, it will be a pleasure to be able to collaborate and exchange knowledge together.