从 Python 调用 AWS Rekognition HTTP API 的示例
An example of calling AWS Rekognition HTTP API from Python
我想尝试 Rekognition's CompareFaces,但我没有看到使用 HTTP API 的语法的完整示例。假设我有两张图片,我如何从 Python 中调用此 API 来检索相似度分数?
关于代码的信息
几乎没有关于将 HTTP API 用于 AWS Rekognition 的文档,但使用大多数代码用于命中 AWS 服务 HTTP 端点的模型非常简单。
有关以下代码的重要信息:
您必须安装 requests
。如果没有,您可以 运行 在 shell 中执行以下操作(建议在 virtualenv
中执行)。
pip install requests
使用了us-east-1
区域。 us-east-1
、eu-west-1
和 us-west-2
目前支持 Rekognition,因此您可以根据需要修改代码以支持 different region endpoints。
它希望磁盘上存在两个文件供读取,名为 source.jpg
和 target.jpg
。
因为她出现在我最近看的电影中,所以我使用 星球大战:侠盗一号 中 Felicity Jones 的图像作为我的来源和目标。
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))
代码输出
如果你得到代码 运行ning,它应该输出如下内容:
Response code: 200
Response body:
{
"FaceMatches": [],
"SourceImageFace": {
"BoundingBox": {
"Height": 0.9448398351669312,
"Left": 0.12222222238779068,
"Top": -0.017793593928217888,
"Width": 0.5899999737739563
},
"Confidence": 99.99041748046875
}
}
真的,就用boto3
最简单的方法就是使用 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}}
我想尝试 Rekognition's CompareFaces,但我没有看到使用 HTTP API 的语法的完整示例。假设我有两张图片,我如何从 Python 中调用此 API 来检索相似度分数?
关于代码的信息
几乎没有关于将 HTTP API 用于 AWS Rekognition 的文档,但使用大多数代码用于命中 AWS 服务 HTTP 端点的模型非常简单。
有关以下代码的重要信息:
您必须安装
requests
。如果没有,您可以 运行 在 shell 中执行以下操作(建议在virtualenv
中执行)。pip install requests
使用了
us-east-1
区域。us-east-1
、eu-west-1
和us-west-2
目前支持 Rekognition,因此您可以根据需要修改代码以支持 different region endpoints。它希望磁盘上存在两个文件供读取,名为
source.jpg
和target.jpg
。因为她出现在我最近看的电影中,所以我使用 星球大战:侠盗一号 中 Felicity Jones 的图像作为我的来源和目标。
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))
代码输出
如果你得到代码 运行ning,它应该输出如下内容:
Response code: 200
Response body:
{
"FaceMatches": [],
"SourceImageFace": {
"BoundingBox": {
"Height": 0.9448398351669312,
"Left": 0.12222222238779068,
"Top": -0.017793593928217888,
"Width": 0.5899999737739563
},
"Confidence": 99.99041748046875
}
}
真的,就用boto3
最简单的方法就是使用 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}}