我想尝试Rekognition's CompareFaces,但我没有看到使用HTTP API语法的完整示例。假设我有两个图像,我如何从Python调用此API来检索相似性得分?
答案 0 :(得分:19)
关于使用HTTP API进行AWS Rekognition的文档很少,但使用大多数代码用于命中AWS服务HTTP端点的模型非常简单。
有关以下代码的重要信息:
您必须安装requests
。如果您没有,可以在shell中运行以下内容(建议在virtualenv
中执行此操作)。
pip install requests
使用us-east-1
区域。 us-east-1
,eu-west-1
和us-west-2
目前支持重新认知,因此您可以根据需要修改代码以支持different region endpoints。
它希望磁盘上存在两个文件供读取,称为source.jpg
和target.jpg
。
在我看过的最新电影中,我使用了来自星球大战:盗贼一号的费利西蒂·琼斯的照片作为我的来源和目标。
它包含与AWS Signature Version 4签名的代码。有些库会为你做签名生成,但我并不想过多地依赖第三方库来展示完整的例子。
您使用的AWS凭据应具有有效的policy for Rekognition。
它是为Python 2.7编写的(不应该非常难以转移到Python 3)。
#!/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's 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))
如果你运行代码,它应该输出如下内容:
Response code: 200
Response body:
{
"FaceMatches": [],
"SourceImageFace": {
"BoundingBox": {
"Height": 0.9448398351669312,
"Left": 0.12222222238779068,
"Top": -0.017793593928217888,
"Width": 0.5899999737739563
},
"Confidence": 99.99041748046875
}
}
您可以做的最简单的事情是使用boto3
。
代码将简化为以下内容,因为所有签名生成和JSON工作都变得不必要。
确保您已在环境中或通过配置文件配置了boto3
凭据,或者将您的凭据与代码内联。有关详细信息,请参阅boto3
configuration。
此代码使用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)
以上boto3
示例应输出:
{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}}