2016-12-30 12 views

Odpowiedz

13

Informacja o kodzie

Niewiele jest dokumentacja wokół używając API HTTP dla AWS Rekognition, ale to jest dość prosty w obsłudze model, który najbardziej kod wykorzystuje trafić AWS punktów końcowych HTTP serwisowych.

Ważne informacje o kodzie, który następuje:

  • Musisz mieć requests zainstalowany. Jeśli go nie masz, możesz uruchomić następujące w swojej powłoce (zalecane jest to w virtualenv).

    pip install requests 
    
  • Używany jest region us-east-1. Rekognition jest obecnie obsługiwany w us-east-1, eu-west-1 i us-west-2, dzięki czemu można zmodyfikować kod, aby obsługiwać different region endpoints, jak chcesz.

  • Oczekuje dwóch plików na dysku do odczytu, o nazwie source.jpg i target.jpg.

    W najnowszym filmie, który widziałem, używam zdjęć Felicity Jones z Star Wars: Rogue One jako mojego źródła i celu.

    source.jpg jest: Felicity Jones source image

    target.jpg jest: Felicity Jones target image

  • Zawiera kod do zrobienia podpisanie z AWS Signature Version 4. Istnieją biblioteki, które wykonają dla ciebie generację sygnatur, ale nie chciałem polegać zbytnio na bibliotekach innych firm, aby pokazać pełny przykład.

  • Poświadczenia AWS, których używasz, powinny mieć prawidłowy numer policy for Rekognition.

  • Został napisany dla Pythona 2.7 (nie powinno być strasznie trudno przenieść się do Pythona 3).


Kodeks

#!/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)) 

Kod wyjścia

Jeśli otrzymasz kod działa, powinno wyjściowy coś takiego:

Response code: 200 

Response body: 
{ 

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

Naprawdę, wystarczy użyć boto3

Najprostszą rzeczą, jaką możesz zrobić, to użyć boto3.

Kod zostanie uproszczony do czegoś podobnego, ponieważ tworzenie sygnatur i JSON stają się niepotrzebne.

Upewnij się, że skonfigurowałeś boto3 z poświadczeniami w środowisku lub poprzez plik konfiguracyjny, lub wpisałeś swoje poświadczenia bezpośrednio z kodem. Aby uzyskać więcej informacji, zobacz boto3 configuration.

Kod ten wykorzystuje numer 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) 

Powyższy przykład powinien boto3 wyjście to:

{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}} 
+1

Próbuję "boto3", ponieważ z pewnością wygląda na prostsze. Czy początkowe wywołanie nie powinno wyglądać tak: 'client = boto3.client ('rekognition', aws_access_key_id = klucz, aws_secret_access_key = secret, region_name = region)'? – jensph

+0

Jestem w stanie wykorzystać demo Rekognition w konsoli AWS, jednak pojawia się błąd podczas używania 'boto3':' Wystąpił błąd (AccessDeniedException) podczas wywoływania operacji CompareFaces: Użytkownik: X nie jest uprawniony do wykonywania: rekognition: CompareFaces . "Być może muszę dwukrotnie sprawdzić moje klucze, ale chciałem sprawdzić, czy klient jest poprawnie skonfigurowany. – jensph

+1

@jensph Jeśli używasz boto3, możesz podać klucz/secret/token/region, żądając klienta, lub określając je w zmiennych środowiskowych. Moje przykłady kodu zakładają to drugie. Istnieją również [inne sposoby dostarczania referencji] (http://boto3.readthedocs.io/en/latest/guide/configuration.html). Jeśli chodzi o inny problem, z którym masz do czynienia, brzmi to tak, jakby Twoja zasada IAM nie zapewniała dostępu do zasobów 'rekognition'. – birryree

Powiązane problemy