Je souhaite essayer Rekognition's CompareFaces, mais je ne vois pas d'exemple complet de syntaxe pour l'utilisation de l'API HTTP. En supposant que j'ai deux images, comment j'appellerais cette API de Python pour récupérer un score de similarité?Exemple d'appel de l'API HTTP AWS Rekognition à partir de Python
Répondre
Informations sur le code
Il y a peu de documentation autour de l'utilisation de l'API HTTP pour AWS Rekognition, mais il est assez simple d'utiliser le modèle que la plupart code utilise pour frapper AWS services points de terminaison HTTP.
Informations importantes concernant le code qui suit:
Vous devez avoir installé
requests
. Si vous ne l'avez pas, vous pouvez exécuter ce qui suit dans votre shell (il est recommandé de le faire envirtualenv
).pip install requests
La région
us-east-1
est utilisé. Rekognition est actuellement pris en charge dansus-east-1
,eu-west-1
etus-west-2
afin que vous puissiez modifier le code pour prendre en charge different region endpoints comme vous le souhaitez.Il s'attend à ce que deux fichiers existent sur le disque pour la lecture, appelés
source.jpg
ettarget.jpg
. Comme elle est dans le film le plus récent que j'ai vu, j'utilise des images de Felicity Jones de Star Wars: Rogue One comme ma source et ma cible.Il inclut le code pour le faire signer avec AWS Signature Version 4. Il y a des bibliothèques qui vont faire la génération de signature pour vous, mais je ne voulais pas trop compter sur les bibliothèques tierces afin de montrer un exemple complet. Les informations d'identification AWS que vous utilisez doivent avoir un policy for Rekognition valide.
Il a été écrit pour Python 2.7 (ne devrait pas être terriblement difficile de passer à Python 3).
Le 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'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))
Code de sortie
Si vous obtenez le code en cours d'exécution, il doit quelque chose comme de sortie ceci:
Response code: 200
Response body:
{
"FaceMatches": [],
"SourceImageFace": {
"BoundingBox": {
"Height": 0.9448398351669312,
"Left": 0.12222222238779068,
"Top": -0.017793593928217888,
"Width": 0.5899999737739563
},
"Confidence": 99.99041748046875
}
}
Vraiment, il suffit d'utiliser boto3
La chose la plus simple que vous pouvez faire est d'utiliser boto3
.
Le code serait simplifié à quelque chose comme le suivant, car toute la génération de signature et le travail JSON deviennent inutiles. Assurez-vous d'avoir configuré boto3
avec les informations d'identification dans l'environnement ou via le fichier de configuration, ou insérez vos informations d'identification dans le code. Pour plus d'informations, voir boto3
configuration. Le code pour cela utilise le 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)
L'exemple ci-dessus boto3
devrait afficher ceci:
{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}}
J'essaie 'boto3' car il semble certainement plus simple. L'appel initial ne devrait-il pas être quelque chose comme: 'client = boto3.client ('rekognition', aws_access_key_id = clé, aws_secret_access_key = secret, région_name = région)'? – jensph
Je suis capable d'utiliser la démo Rekognition dans la console AWS, cependant j'obtiens une erreur en utilisant 'boto3':' Une erreur est survenue (AccessDeniedException) lors de l'appel de l'opération CompareFaces: Utilisateur: X n'est pas autorisé à effectuer: rekognition: CompareFaces Peut-être que j'ai besoin de vérifier mes clés, mais je voulais vérifier que le client est correctement configuré. – jensph
@jensph Si vous utilisez boto3, vous pouvez spécifier la clé/secret/jeton/région en demandant un client ou en les spécifiant dans les variables d'environnement. Mes exemples de code supposent ce dernier. Il existe également [d'autres moyens de fournir des informations d'identification] (http://boto3.readthedocs.io/en/latest/guide/configuration.html). En ce qui concerne l'autre problème que vous rencontrez, il semble que votre stratégie IAM n'accorde pas l'accès à l'utilisation des ressources de 'rekognition'. – birryree
Toute raison pour laquelle vous souhaitez utiliser l'API HTTP au lieu de 'boto3'? – birryree