AWS Rekognition API for Celebrity Recognition
Prerequisite
-
Setup IAM user on AWS, see create an IAM user
-
Install AWS CLI and SDKs eg. boto3, see set up the AWS CLI and AWS SDKs
Setup
import boto3
import json
from six.moves.urllib.request import urlopen
from six import BytesIO
import numpy as np
from PIL import Image
from PIL import ImageColor
from PIL import ImageDraw, ExifTags, ImageColor
from PIL import ImageFont
from PIL import ImageOps
import tempfile
import matplotlib.pyplot as plt
Define utility function
def recognize_celebrities(photo):
client=boto3.client('rekognition')
with open(photo, 'rb') as image:
response = client.recognize_celebrities(Image={'Bytes': image.read()})
return response
def download_image(img_url):
open_image = urlopen(img_url)
image_data = open_image.read()
image_data = BytesIO(image_data)
pil_image = Image.open(image_data)
imgWidth, imgHeight = pil_image.size
pil_image = ImageOps.fit(pil_image, (imgWidth,imgHeight), Image.ANTIALIAS)
pil_image_rgb = pil_image.convert("RGB")
pil_image_rgb.save("celeb.jpg", format="JPEG", quality=90)
def display_image(image):
fig = plt.figure(figsize=(15, 15))
plt.grid(False)
plt.imshow(image)
Download test image
download_image("https://upload.wikimedia.org/wikipedia/commons/2/2c/Lady_Gaga_interview_2016.jpg")
detect_img_path='celeb.jpg'
image = Image.open(detect_img_path)
display_image(image)
test image: Why Lady Gaga? because she is so talented, brilliant, incredible, amazing, show stopping, spectacular, never the same, totally unique, completely not ever been done before, unafraid to reference or not reference, put it in a blender, shit on it, vomit on it, eat it, give birth to it.
OK, joking aside. Let’s continue :3
Invoke the model via AWS Rekognition API
detect_img_path='celeb.jpg'
response = recognize_celebrities(detect_img_path)
json_response = json.dumps(response, indent=4)
print(json_response)
we will receive a JSON formatted response like this
{
"CelebrityFaces": [
{
"Urls": [
"www.imdb.com/name/nm3078932"
],
"Name": "Lady Gaga",
"Id": "4Fn1Te4k",
"Face": {
"BoundingBox": {
"Width": 0.4975884258747101,
"Height": 0.3868750035762787,
"Left": 0.18006430566310883,
"Top": 0.18000000715255737
},
"Confidence": 99.99113464355469,
"Landmarks": [
{
"Type": "eyeLeft",
"X": 0.3336140513420105,
"Y": 0.33852386474609375
},
{
"Type": "eyeRight",
"X": 0.48979300260543823,
"Y": 0.33140549063682556
},
{
"Type": "nose",
"X": 0.36879873275756836,
"Y": 0.4117993116378784
},
{
"Type": "mouthLeft",
"X": 0.357170045375824,
"Y": 0.46853089332580566
},
{
"Type": "mouthRight",
"X": 0.4952928423881531,
"Y": 0.4677777886390686
}
],
"Pose": {
"Roll": -2.1802918910980225,
"Yaw": -24.470903396606445,
"Pitch": 0.10077361017465591
},
"Quality": {
"Brightness": 80.43765258789062,
"Sharpness": 96.63640594482422
}
},
"MatchConfidence": 72.0
}
],
"UnrecognizedFaces": [],
"OrientationCorrection": "ROTATE_0",
"ResponseMetadata": {
"RequestId": "36aabe95-3fe3-40ff-85e2-e637544b0564",
"HTTPStatusCode": 200,
"HTTPHeaders": {
"content-type": "application/x-amz-json-1.1",
"date": "Mon, 19 Apr 2021 09:56:57 GMT",
"x-amzn-requestid": "36aabe95-3fe3-40ff-85e2-e637544b0564",
"content-length": "850",
"connection": "keep-alive"
},
"RetryAttempts": 0
}
}
Check the JSON response
for celebrity in response['CelebrityFaces']:
print ('Name: ' + celebrity['Name'])
print ('Match Confidence: ' + '{:.2f}'.format(celebrity['MatchConfidence']))
print ('Info')
for url in celebrity['Urls']:
print (' ' + url)
Now we can see the result more clearly. The result include Match Confidence which indicate how much the model is confidence that the recognized face is the celebrity. The result also the info website.
Name: Lady Gaga
Match Confidence: 72.00
Info
www.imdb.com/name/nm3078932
Draw a bounding box on the image
def draw_boxes(image_path, response):
image = Image.open(image_path)
draw = ImageDraw.Draw(image)
imgWidth, imgHeight = image.size
color = '#00d400'
font = ImageFont.truetype("/usr/share/fonts/truetype/lato/Lato-Regular.ttf",70)
for celebFace in response['CelebrityFaces']:
faceDetail = celebFace["Face"]
box = faceDetail['BoundingBox']
left = imgWidth * box['Left']
top = imgHeight * box['Top']
width = imgWidth * box['Width']
height = imgHeight * box['Height']
points = (
(left,top),
(left + width, top),
(left + width, top + height),
(left , top + height),
(left, top)
)
display_str = celebFace['Name'] +" "+ str(celebFace['MatchConfidence'])+"%"
text_width, text_height = font.getsize(display_str)
margin = np.ceil(0.05 * text_height)
text_bottom = top
draw.line(points, fill=color, width=5)
draw.rectangle([(left, text_bottom - text_height - 2 * margin),
(left + text_width, text_bottom)],
fill=color)
draw.text((left + margin, text_bottom - text_height - margin),
display_str,
fill="black",
font=font)
return image
detect_img = "celeb.jpg"
draw_image = draw_boxes(detect_img, response)
if display:
display_image(draw_image)
Paw up little monster, we did it!!! Now let’s try with other image shall we?
download_image("https://pbs.twimg.com/media/BhxWutnCEAAtEQ6?format=jpg")
detect_img_path='celeb.jpg'
response = recognize_celebrities(detect_img_path)
for celebrity in response['CelebrityFaces']:
print ('Name: ' + celebrity['Name'])
print ('Match Confidence: ' + '{:.2f}'.format(celebrity['MatchConfidence']))
print ('Info')
for url in celebrity['Urls']:
print (' ' + url)
detect_img = "celeb.jpg"
draw_image = draw_boxes(detect_img, response)
if display:
display_image(draw_image)
Name: Bradley Cooper
Match Confidence: 100.00
Info
www.imdb.com/name/nm0177896
Name: Ellen DeGeneres
Match Confidence: 100.00
Info
www.imdb.com/name/nm0001122
Name: Jennifer Lawrence
Match Confidence: 67.00
Info
www.imdb.com/name/nm2225369
Name: Wayne Wonder
Match Confidence: 69.00
Info
www.imdb.com/name/nm0938872
Name: Patrik Antonius
Match Confidence: 67.00
Info
Name: Kevin Spacey
Match Confidence: 60.00
Info
www.imdb.com/name/nm0000228
Impressive! imagine how useful of this API on digital marketing, advertising, and media industry. Stay tuned for interesting Machine Learning story.