forked from awsdocs/aws-doc-sdk-examples
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrekognition_image_detection.py
More file actions
368 lines (317 loc) · 13.7 KB
/
rekognition_image_detection.py
File metadata and controls
368 lines (317 loc) · 13.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
"""
Purpose
Shows how to use the AWS SDK for Python (Boto3) with Amazon Rekognition to
recognize people, objects, and text in images.
The usage demo in this file uses images in the .media folder. If you run this code
without cloning the GitHub repository, you must first download the image files from
https://github.com/awsdocs/aws-doc-sdk-examples/tree/master/python/example_code/rekognition/.media
"""
# snippet-start:[python.example_code.rekognition.image_detection_imports]
import logging
from pprint import pprint
import boto3
from botocore.exceptions import ClientError
import requests
from rekognition_objects import (
RekognitionFace,
RekognitionCelebrity,
RekognitionLabel,
RekognitionModerationLabel,
RekognitionText,
show_bounding_boxes,
show_polygons,
)
logger = logging.getLogger(__name__)
# snippet-end:[python.example_code.rekognition.image_detection_imports]
# snippet-start:[python.example_code.rekognition.RekognitionImage]
class RekognitionImage:
"""
Encapsulates an Amazon Rekognition image. This class is a thin wrapper
around parts of the Boto3 Amazon Rekognition API.
"""
def __init__(self, image, image_name, rekognition_client):
"""
Initializes the image object.
:param image: Data that defines the image, either the image bytes or
an Amazon S3 bucket and object key.
:param image_name: The name of the image.
:param rekognition_client: A Boto3 Rekognition client.
"""
self.image = image
self.image_name = image_name
self.rekognition_client = rekognition_client
# snippet-end:[python.example_code.rekognition.RekognitionImage]
# snippet-start:[python.example_code.rekognition.RekognitionImage.from_file]
@classmethod
def from_file(cls, image_file_name, rekognition_client, image_name=None):
"""
Creates a RekognitionImage object from a local file.
:param image_file_name: The file name of the image. The file is opened and its
bytes are read.
:param rekognition_client: A Boto3 Rekognition client.
:param image_name: The name of the image. If this is not specified, the
file name is used as the image name.
:return: The RekognitionImage object, initialized with image bytes from the
file.
"""
with open(image_file_name, "rb") as img_file:
image = {"Bytes": img_file.read()}
name = image_file_name if image_name is None else image_name
return cls(image, name, rekognition_client)
# snippet-end:[python.example_code.rekognition.RekognitionImage.from_file]
# snippet-start:[python.example_code.rekognition.RekognitionImage.from_bucket]
@classmethod
def from_bucket(cls, s3_object, rekognition_client):
"""
Creates a RekognitionImage object from an Amazon S3 object.
:param s3_object: An Amazon S3 object that identifies the image. The image
is not retrieved until needed for a later call.
:param rekognition_client: A Boto3 Rekognition client.
:return: The RekognitionImage object, initialized with Amazon S3 object data.
"""
image = {"S3Object": {"Bucket": s3_object.bucket_name, "Name": s3_object.key}}
return cls(image, s3_object.key, rekognition_client)
# snippet-end:[python.example_code.rekognition.RekognitionImage.from_bucket]
# snippet-start:[python.example_code.rekognition.DetectFaces]
def detect_faces(self):
"""
Detects faces in the image.
:return: The list of faces found in the image.
"""
try:
response = self.rekognition_client.detect_faces(
Image=self.image, Attributes=["ALL"]
)
faces = [RekognitionFace(face) for face in response["FaceDetails"]]
logger.info("Detected %s faces.", len(faces))
except ClientError:
logger.exception("Couldn't detect faces in %s.", self.image_name)
raise
else:
return faces
# snippet-end:[python.example_code.rekognition.DetectFaces]
# snippet-start:[python.example_code.rekognition.CompareFaces]
def compare_faces(self, target_image, similarity):
"""
Compares faces in the image with the largest face in the target image.
:param target_image: The target image to compare against.
:param similarity: Faces in the image must have a similarity value greater
than this value to be included in the results.
:return: A tuple. The first element is the list of faces that match the
reference image. The second element is the list of faces that have
a similarity value below the specified threshold.
"""
try:
response = self.rekognition_client.compare_faces(
SourceImage=self.image,
TargetImage=target_image.image,
SimilarityThreshold=similarity,
)
matches = [
RekognitionFace(match["Face"]) for match in response["FaceMatches"]
]
unmatches = [RekognitionFace(face) for face in response["UnmatchedFaces"]]
logger.info(
"Found %s matched faces and %s unmatched faces.",
len(matches),
len(unmatches),
)
except ClientError:
logger.exception(
"Couldn't match faces from %s to %s.",
self.image_name,
target_image.image_name,
)
raise
else:
return matches, unmatches
# snippet-end:[python.example_code.rekognition.CompareFaces]
# snippet-start:[python.example_code.rekognition.DetectLabels]
def detect_labels(self, max_labels):
"""
Detects labels in the image. Labels are objects and people.
:param max_labels: The maximum number of labels to return.
:return: The list of labels detected in the image.
"""
try:
response = self.rekognition_client.detect_labels(
Image=self.image, MaxLabels=max_labels
)
labels = [RekognitionLabel(label) for label in response["Labels"]]
logger.info("Found %s labels in %s.", len(labels), self.image_name)
except ClientError:
logger.info("Couldn't detect labels in %s.", self.image_name)
raise
else:
return labels
# snippet-end:[python.example_code.rekognition.DetectLabels]
# snippet-start:[python.example_code.rekognition.DetectModerationLabels]
def detect_moderation_labels(self):
"""
Detects moderation labels in the image. Moderation labels identify content
that may be inappropriate for some audiences.
:return: The list of moderation labels found in the image.
"""
try:
response = self.rekognition_client.detect_moderation_labels(
Image=self.image
)
labels = [
RekognitionModerationLabel(label)
for label in response["ModerationLabels"]
]
logger.info(
"Found %s moderation labels in %s.", len(labels), self.image_name
)
except ClientError:
logger.exception(
"Couldn't detect moderation labels in %s.", self.image_name
)
raise
else:
return labels
# snippet-end:[python.example_code.rekognition.DetectModerationLabels]
# snippet-start:[python.example_code.rekognition.DetectText]
def detect_text(self):
"""
Detects text in the image.
:return The list of text elements found in the image.
"""
try:
response = self.rekognition_client.detect_text(Image=self.image)
texts = [RekognitionText(text) for text in response["TextDetections"]]
logger.info("Found %s texts in %s.", len(texts), self.image_name)
except ClientError:
logger.exception("Couldn't detect text in %s.", self.image_name)
raise
else:
return texts
# snippet-end:[python.example_code.rekognition.DetectText]
# snippet-start:[python.example_code.rekognition.RecognizeCelebrities]
def recognize_celebrities(self):
"""
Detects celebrities in the image.
:return: A tuple. The first element is the list of celebrities found in
the image. The second element is the list of faces that were
detected but did not match any known celebrities.
"""
try:
response = self.rekognition_client.recognize_celebrities(Image=self.image)
celebrities = [
RekognitionCelebrity(celeb) for celeb in response["CelebrityFaces"]
]
other_faces = [
RekognitionFace(face) for face in response["UnrecognizedFaces"]
]
logger.info(
"Found %s celebrities and %s other faces in %s.",
len(celebrities),
len(other_faces),
self.image_name,
)
except ClientError:
logger.exception("Couldn't detect celebrities in %s.", self.image_name)
raise
else:
return celebrities, other_faces
# snippet-end:[python.example_code.rekognition.RecognizeCelebrities]
# snippet-start:[python.example_code.rekognition.Usage_ImageDetection]
def usage_demo():
print("-" * 88)
print("Welcome to the Amazon Rekognition image detection demo!")
print("-" * 88)
logging.basicConfig(level=logging.INFO, format="%(levelname)s: %(message)s")
rekognition_client = boto3.client("rekognition")
street_scene_file_name = ".media/pexels-kaique-rocha-109919.jpg"
celebrity_file_name = ".media/pexels-pixabay-53370.jpg"
one_girl_url = "https://dhei5unw3vrsx.cloudfront.net/images/source3_resized.jpg"
three_girls_url = "https://dhei5unw3vrsx.cloudfront.net/images/target3_resized.jpg"
swimwear_object = boto3.resource("s3").Object(
"console-sample-images-pdx", "yoga_swimwear.jpg"
)
book_file_name = ".media/pexels-christina-morillo-1181671.jpg"
street_scene_image = RekognitionImage.from_file(
street_scene_file_name, rekognition_client
)
print(f"Detecting faces in {street_scene_image.image_name}...")
faces = street_scene_image.detect_faces()
print(f"Found {len(faces)} faces, here are the first three.")
for face in faces[:3]:
pprint(face.to_dict())
show_bounding_boxes(
street_scene_image.image["Bytes"],
[[face.bounding_box for face in faces]],
["aqua"],
)
input("Press Enter to continue.")
print(f"Detecting labels in {street_scene_image.image_name}...")
labels = street_scene_image.detect_labels(100)
print(f"Found {len(labels)} labels.")
for label in labels:
pprint(label.to_dict())
names = []
box_sets = []
colors = ["aqua", "red", "white", "blue", "yellow", "green"]
for label in labels:
if label.instances:
names.append(label.name)
box_sets.append([inst["BoundingBox"] for inst in label.instances])
print(f"Showing bounding boxes for {names} in {colors[:len(names)]}.")
show_bounding_boxes(
street_scene_image.image["Bytes"], box_sets, colors[: len(names)]
)
input("Press Enter to continue.")
celebrity_image = RekognitionImage.from_file(
celebrity_file_name, rekognition_client
)
print(f"Detecting celebrities in {celebrity_image.image_name}...")
celebs, others = celebrity_image.recognize_celebrities()
print(f"Found {len(celebs)} celebrities.")
for celeb in celebs:
pprint(celeb.to_dict())
show_bounding_boxes(
celebrity_image.image["Bytes"],
[[celeb.face.bounding_box for celeb in celebs]],
["aqua"],
)
input("Press Enter to continue.")
girl_image_response = requests.get(one_girl_url)
girl_image = RekognitionImage(
{"Bytes": girl_image_response.content}, "one-girl", rekognition_client
)
group_image_response = requests.get(three_girls_url)
group_image = RekognitionImage(
{"Bytes": group_image_response.content}, "three-girls", rekognition_client
)
print("Comparing reference face to group of faces...")
matches, unmatches = girl_image.compare_faces(group_image, 80)
print(f"Found {len(matches)} face matching the reference face.")
show_bounding_boxes(
group_image.image["Bytes"],
[[match.bounding_box for match in matches]],
["aqua"],
)
input("Press Enter to continue.")
swimwear_image = RekognitionImage.from_bucket(swimwear_object, rekognition_client)
print(f"Detecting suggestive content in {swimwear_object.key}...")
labels = swimwear_image.detect_moderation_labels()
print(f"Found {len(labels)} moderation labels.")
for label in labels:
pprint(label.to_dict())
input("Press Enter to continue.")
book_image = RekognitionImage.from_file(book_file_name, rekognition_client)
print(f"Detecting text in {book_image.image_name}...")
texts = book_image.detect_text()
print(f"Found {len(texts)} text instances. Here are the first seven:")
for text in texts[:7]:
pprint(text.to_dict())
show_polygons(
book_image.image["Bytes"], [text.geometry["Polygon"] for text in texts], "aqua"
)
print("Thanks for watching!")
print("-" * 88)
# snippet-end:[python.example_code.rekognition.Usage_ImageDetection]
if __name__ == "__main__":
usage_demo()