Python AWS Rekognition HTTP API Call Example

I would like to try Rekognition CompareFaces , but I don't see a complete syntax example for using the HTTP API. Assuming I have two images, how can I call this API from Python to get a similarity score?

+6
source share
1 answer

Code Information

There is little documentation on using the HTTP API for Rexognition AWS, but it's pretty simple to use the model that most code uses to use AWS HTTP endpoints.

Important information about the following code:

  • You must have installed requests . If you do not have it, you can run the following in your shell (it is recommended to do this in virtualenv ).

     pip install requests 
  • The us-east-1 . Rekognition is currently supported in us-east-1 , eu-west-1 and us-west-2 , so you can change the code to support different endpoints in the region as you wish.

  • He expects two files to exist on the read disk, called source.jpg and target.jpg .

    Like her in the last movie I saw, I use images of Felicity Jones from Star Wars: The Rogue One as my source and target.

    source.jpg : Original Image Felicity Jones

    target.jpg : Target Image Felicity Jones

  • It includes code for signing with AWS Signature Version 4 . There are libraries that will generate signatures for you, but I did not want to rely too much on third-party libraries to demonstrate a complete example.

  • The AWS credentials you use must have a valid policy for Rekognition .

  • This was written for Python 2.7 (it shouldn't be terribly difficult to upgrade to Python 3).


The code

 #!/usr/bin/env python # -*- coding: utf-8 -*- import os import base64 import datetime import hashlib import hmac import json import requests # Key derivation functions # http://docs.aws.amazon.com/general/latest/gr/signature-v4-examples.html#signature-v4-examples-python def sign(key, msg): return hmac.new(key, msg.encode('utf-8'), hashlib.sha256).digest() def getSignatureKey(key, date_stamp, regionName, serviceName): kDate = sign(('AWS4' + key).encode('utf-8'), date_stamp) kRegion = sign(kDate, regionName) kService = sign(kRegion, serviceName) kSigning = sign(kService, 'aws4_request') return kSigning if __name__ == '__main__': # Read credentials from the environment access_key = os.environ.get('AWS_ACCESS_KEY_ID') secret_key = os.environ.get('AWS_SECRET_ACCESS_KEY') # Uncomment this line if you use temporary credentials via STS or similar #token = os.environ.get('AWS_SESSION_TOKEN') if access_key is None or secret_key is None: print('No access key is available.') sys.exit() # This code shows the v4 request signing process as shown in # http://docs.aws.amazon.com/general/latest/gr/sigv4-signed-request-examples.html host = 'rekognition.us-east-1.amazonaws.com' endpoint = 'https://rekognition.us-east-1.amazonaws.com' service = 'rekognition' # Currently, all Rekognition actions require POST requests method = 'POST' region = 'us-east-1' # This defines the service target and sub-service you want to hit # In this case you want to use 'CompareFaces' amz_target = 'RekognitionService.CompareFaces' # Amazon content type - Rekognition expects 1.1 x-amz-json content_type = 'application/x-amz-json-1.1' # Create a date for headers and the credential string now = datetime.datetime.utcnow() amz_date = now.strftime('%Y%m%dT%H%M%SZ') date_stamp = now.strftime('%Y%m%d') # Date w/o time, used in credential scope # Canonical request information canonical_uri = '/' canonical_querystring = '' canonical_headers = 'content-type:' + content_type + '\n' + 'host:' + host + '\n' + 'x-amz-date:' + amz_date + '\n' + 'x-amz-target:' + amz_target + '\n' # list of signed headers signed_headers = 'content-type;host;x-amz-date;x-amz-target' # Our source image: http://i.imgur.com/OK8aDRq.jpg with open('source.jpg', 'rb') as source_image: source_bytes = base64.b64encode(source_image.read()) # Our target image: http://i.imgur.com/Xchqm1r.jpg with open('target.jpg', 'rb') as target_image: target_bytes = base64.b64encode(target_image.read()) # here we build the dictionary for our request data # that we will convert to JSON request_dict = { 'SimilarityThreshold': 75.0, 'SourceImage': { 'Bytes': source_bytes }, 'TargetImage': { 'Bytes': target_bytes } } # Convert our dict to a JSON string as it will be used as our payload request_parameters = json.dumps(request_dict) # Generate a hash of our payload for verification by Rekognition payload_hash = hashlib.sha256(request_parameters).hexdigest() # All of this is canonical_request = method + '\n' + canonical_uri + '\n' + canonical_querystring + '\n' + canonical_headers + '\n' + signed_headers + '\n' + payload_hash algorithm = 'AWS4-HMAC-SHA256' credential_scope = date_stamp + '/' + region + '/' + service + '/' + 'aws4_request' string_to_sign = algorithm + '\n' + amz_date + '\n' + credential_scope + '\n' + hashlib.sha256(canonical_request).hexdigest() signing_key = getSignatureKey(secret_key, date_stamp, region, service) signature = hmac.new(signing_key, (string_to_sign).encode('utf-8'), hashlib.sha256).hexdigest() authorization_header = algorithm + ' ' + 'Credential=' + access_key + '/' + credential_scope + ', ' + 'SignedHeaders=' + signed_headers + ', ' + 'Signature=' + signature headers = { 'Content-Type': content_type, 'X-Amz-Date': amz_date, 'X-Amz-Target': amz_target, # uncomment this if you uncommented the 'token' line earlier #'X-Amz-Security-Token': token, 'Authorization': authorization_header} r = requests.post(endpoint, data=request_parameters, headers=headers) # Let format the JSON string returned from the API for better output formatted_text = json.dumps(json.loads(r.text), indent=4, sort_keys=True) print('Response code: {}\n'.format(r.status_code)) print('Response body:\n{}'.format(formatted_text)) 

Code output

If you run the code, it should output something like this:

 Response code: 200 Response body: { "FaceMatches": [], "SourceImageFace": { "BoundingBox": { "Height": 0.9448398351669312, "Left": 0.12222222238779068, "Top": -0.017793593928217888, "Width": 0.5899999737739563 }, "Confidence": 99.99041748046875 } } 

Really, just use boto3

The simplest thing you can do is use boto3 .

The code will be simplified to something like the following, since all signature generation and JSON operation become unnecessary.

Make sure you configure boto3 with credentials in the environment or through the configuration file, or put your credentials in a line with the code. See boto3 configuration for more information.

This code uses the boto3 Rekognition API .

 import pprint import boto3 # Set this to whatever percentage of 'similarity' # you'd want SIMILARITY_THRESHOLD = 75.0 if __name__ == '__main__': client = boto3.client('rekognition') # Our source image: http://i.imgur.com/OK8aDRq.jpg with open('source.jpg', 'rb') as source_image: source_bytes = source_image.read() # Our target image: http://i.imgur.com/Xchqm1r.jpg with open('target.jpg', 'rb') as target_image: target_bytes = target_image.read() response = client.compare_faces( SourceImage={ 'Bytes': source_bytes }, TargetImage={ 'Bytes': target_bytes }, SimilarityThreshold=SIMILARITY_THRESHOLD ) pprint.pprint(response) 

The above boto3 example should output this:

 {u'FaceMatches': [], 'ResponseMetadata': {'HTTPHeaders': {'connection': 'keep-alive', 'content-length': '195', 'content-type': 'application/x-amz-json-1.1', 'date': 'Sat, 31 Dec 2016 23:15:56 GMT', 'x-amzn-requestid': '13edda2d-cfaf-11e6-9999-d3abf4c2feb3'}, 'HTTPStatusCode': 200, 'RequestId': '13edda2d-cfaf-11e6-9999-d3abf4c2feb3', 'RetryAttempts': 0}, u'SourceImageFace': {u'BoundingBox': {u'Height': 0.9448398351669312, u'Left': 0.12222222238779068, u'Top': -0.017793593928217888, u'Width': 0.5899999737739563}, u'Confidence': 99.99041748046875}} 
+13
source

Source: https://habr.com/ru/post/1013621/


All Articles