chetan dev
chetan dev

Reputation: 621

How to crop images using bounding box

How do i crop an image while rendering to browser using the bounding box returned by aws rekognition indexFaces api? below is the bounding box example

 Face: {
   BoundingBox: {
    Height: 0.16555599868297577, 
    Left: 0.30963000655174255, 
    Top: 0.7066670060157776, 
    Width: 0.22074100375175476
   }, 
   Confidence: 100, 
   FaceId: "29a75abe-397b-5101-ba4f-706783b2246c", 
   ImageId: "147fdf82-7a71-52cf-819b-e786c7b9746e"
  }, 
  Similarity: 97.04154968261719 }

Upvotes: 1

Views: 2360

Answers (1)

R. Patel
R. Patel

Reputation: 63

I have faced the same issue. You have to perform some calculations on BoundingBox values. Note the estimated orientation returned in the response's OrientationCorrection field. It is the key value here. You have to find Top and Left from those confusing values. Here is the hint:

If OrientationCorrection = ROTATE_0

Left = image.width*BoundingBox.Left
Top = image.height*BoundingBox.To

If OrientationCorrection = ROTATE_90

Left = image.height * (1 - (BoundingBox.Top + .BoundingBox.Height))
Top = image.width * BoundingBox.Left

If OrientationCorrection = ROTATE_180

Left = image.width - (image.width*(BoundingBox.Left + BoundingBox.Width))
Top = image.height * (1 - (BoundingBox.Top + BoundingBox.Height))

If OrientationCorrection = ROTATE_270

Left = image.height * BoundingBox.top
Top = image.width * (1 - BoundingBox.Left - BoundingBox.Width)

Here is sample code of python which I have used.

import boto3
import io
from PIL import Image

# Calculate positions from from estimated rotation 
def ShowBoundingBoxPositions(imageHeight, imageWidth, box, rotation): 
    left = 0
    top = 0

    if rotation == 'ROTATE_0':
        left = imageWidth * box['Left']
        top = imageHeight * box['Top']

    if rotation == 'ROTATE_90':
        left = imageHeight * (1 - (box['Top'] + box['Height']))
        top = imageWidth * box['Left']

    if rotation == 'ROTATE_180':
        left = imageWidth - (imageWidth * (box['Left'] + box['Width']))
        top = imageHeight * (1 - (box['Top'] + box['Height']))

    if rotation == 'ROTATE_270':
        left = imageHeight * box['Top']
        top = imageWidth * (1- box['Left'] - box['Width'] )

    print('Left: ' + '{0:.0f}'.format(left))
    print('Top: ' + '{0:.0f}'.format(top))
    print('Face Width: ' + "{0:.0f}".format(imageWidth * box['Width']))
    print('Face Height: ' + "{0:.0f}".format(imageHeight * box['Height']))


if __name__ == "__main__":

    photo='input.png'
    client=boto3.client('rekognition')


    #Get image width and height
    image = Image.open(open(photo,'rb'))
    width, height = image.size

    print ('Image information: ')
    print (photo)
    print ('Image Height: ' + str(height)) 
    print('Image Width: ' + str(width))    


    # call detect faces and show face age and placement
    # if found, preserve exif info
    stream = io.BytesIO()
    if 'exif' in image.info:
        exif=image.info['exif']
        image.save(stream,format=image.format, exif=exif)
    else:
        image.save(stream, format=image.format)    
    image_binary = stream.getvalue()

    response = client.detect_faces(Image={'Bytes': image_binary}, Attributes=['ALL'])

    print('Detected faces for ' + photo)    
    for faceDetail in response['FaceDetails']:
        print ('Face:')
        if 'OrientationCorrection'  in response:
            print('Orientation: ' + response['OrientationCorrection'])
            ShowBoundingBoxPositions(height, width, faceDetail['BoundingBox'], response['OrientationCorrection'])

        else:
            print ('No estimated orientation. Check Exif data')

        print('The detected face is estimated to be between ' + str(faceDetail['AgeRange']['Low']) 
            + ' and ' + str(faceDetail['AgeRange']['High']) + ' years')
        print()

It will return the Top, Left, Height, Width of the face in the image. If you use python than you can easily crop image with PIL like this.

from PIL import Image
image = Image.open(open("Main_Image", 'rb'))
area = (Left, Top, Left + Width, Top + Height)
face = image.crop(area)
face.show()

It will show the cropped face from the image.
Happy Coding

Upvotes: 2

Related Questions