Archiviazione dei dati di Amazon Rekognition con Amazon RDS e DynamoDB - Amazon Rekognition

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Archiviazione dei dati di Amazon Rekognition con Amazon RDS e DynamoDB

Quando si utilizza Amazon Rekognition APIs, è importante ricordare che le operazioni API non salvano nessuna delle etichette generate. Puoi salvare queste etichette inserendole nel database, insieme agli identificatori per le rispettive immagini.

Questo tutorial dimostra il rilevamento delle etichette e il salvataggio di quelle etichette rilevate in un database. L'applicazione di esempio sviluppata in questo tutorial leggerà le immagini da un bucket Amazon S3, richiamerà l'DetectLabelsoperazione su queste immagini e memorizzerà le etichette risultanti in un database. L'applicazione memorizzerà i dati in un'istanza di database Amazon RDS o in un database DynamoDB, a seconda del tipo di database che desideri utilizzare.

Utilizzerai l'AWS SDK per Python per questo tutorial. Puoi anche vedere il GitHub repository degli esempi di AWS Documentation SDK per altri tutorial su Python.

Prerequisiti

Prima di iniziare questo tutorial, devi installare Python e completare i passaggi necessari per configurare Python SDK. AWS Oltre a ciò, assicurati di:

Aver creato un account AWS e un ruolo IAM

Aver installato l'SDK Python (Boto3)

Hai configurato correttamente le tue credenziali di accesso AWS

Aver creato il bucket Amazon S3 e riempito di immagini

Aver creato un'istanza di database RDS, se si utilizza RDS per archiviare dati

Ottenere etichette per immagini in un bucket Amazon S3

Inizia scrivendo una funzione che assuma il nome di un'immagine nel tuo bucket Amazon S3 e recupera quell'immagine. Questa immagine verrà visualizzata per confermare che le immagini corrette vengano passate a una chiamata a DetectLabelscui è presente anche la funzione.

  1. Trova il bucket Amazon S3 che desideri utilizzare e scrivine il nome. Effettuerai chiamate a questo bucket Amazon S3 e leggerai le immagini al suo interno. Assicurati che il bucket contenga alcune immagini da passare all'DetectLabelsoperazione.

  2. Scrivi il codice per effettuare la connessione al bucket Amazon S3. Puoi connetterti alla risorsa Amazon S3 con Boto3 per recuperare un'immagine da un bucket Amazon S3. Una volta connesso alla risorsa Amazon S3, puoi accedere al bucket fornendo al metodo Bucket il nome del bucket Amazon S3. Dopo la connessione al bucket Amazon S3, recuperi le immagini dal bucket utilizzando il metodo Object. Utilizzando Matplotlib, puoi utilizzare questa connessione per visualizzare le tue immagini mentre vengono elaborate. Boto3 viene utilizzato anche per connettersi al client Rekognition.

    Nel codice seguente, fornisci la tua regione al parametro region_name. Passerai il nome del bucket Amazon S3 e il nome dell'immagine a DetectLabels, che restituirà le etichette per l'immagine corrispondente. Dopo aver selezionato solo le etichette dalla risposta, vengono restituiti sia il nome dell'immagine che le etichette.

    import boto3 from io import BytesIO from matplotlib import pyplot as plt from matplotlib import image as mp_img boto3 = boto3.Session() def read_image_from_s3(bucket_name, image_name): # Connect to the S3 resource with Boto 3 # get bucket and find object matching image name s3 = boto3.resource('s3') bucket = s3.Bucket(name=bucket_name) Object = bucket.Object(image_name) # Downloading the image for display purposes, not necessary for detection of labels # You can comment this code out if you don't want to visualize the images file_name = Object.key file_stream = BytesIO() Object.download_fileobj(file_stream) img = mp_img.imread(file_stream, format="jpeg") plt.imshow(img) plt.show() # get the labels for the image by calling DetectLabels from Rekognition client = boto3.client('rekognition', region_name="region-name") response = client.detect_labels(Image={'S3Object': {'Bucket': bucket_name, 'Name': image_name}}, MaxLabels=10) print('Detected labels for ' + image_name) full_labels = response['Labels'] return file_name, full_labels
  3. Salva questo codice in un file chiamato get_images.py.

Creazione di una tabella Amazon DynamoDB

Il codice seguente utilizza Boto3 per connettersi a DynamoDB e utilizza il metodo DynamoDB CreateTable per creare una tabella denominata Images. La tabella ha una chiave primaria composita costituita da una chiave di partizione chiamata Image e da una chiave di ordinamento chiamata Labels. La chiave Image contiene il nome dell'immagine, mentre la chiave Labels memorizza le etichette assegnate a quell'immagine.

import boto3 def create_new_table(dynamodb=None): dynamodb = boto3.resource( 'dynamodb',) # Table defination table = dynamodb.create_table( TableName='Images', KeySchema=[ { 'AttributeName': 'Image', 'KeyType': 'HASH' # Partition key }, { 'AttributeName': 'Labels', 'KeyType': 'RANGE' # Sort key } ], AttributeDefinitions=[ { 'AttributeName': 'Image', 'AttributeType': 'S' }, { 'AttributeName': 'Labels', 'AttributeType': 'S' }, ], ProvisionedThroughput={ 'ReadCapacityUnits': 10, 'WriteCapacityUnits': 10 } ) return table if __name__ == '__main__': device_table = create_new_table() print("Status:", device_table.table_status)

Salva questo codice in un editor ed eseguilo una volta per creare una tabella DynamoDB.

Importazione di dati in DynamoDB

Ora che il database DynamoDB è stato creato e hai una funzione per ottenere le etichette per le immagini, puoi memorizzare le etichette in DynamoDB. Il codice seguente recupera tutte le immagini in un bucket S3, recupera le etichette per esse e archivia i dati in DynamoDB.

  1. Dovrai scrivere il codice per caricare i dati su DynamoDB. Una funzione chiamata get_image_names viene utilizzata per connettersi al bucket Amazon S3 e restituisce i nomi di tutte le immagini nel bucket sotto forma di elenco. Passerai questo elenco alla funzione read_image_from_S3, che viene importata dal file get_images.py che hai creato.

    import boto3 import json from get_images import read_image_from_s3 boto3 = boto3.Session() def get_image_names(name_of_bucket): s3_resource = boto3.resource('s3') my_bucket = s3_resource.Bucket(name_of_bucket) file_list = [] for file in my_bucket.objects.all(): file_list.append(file.key) return file_list
  2. La funzione read_image_from_S3 che abbiamo creato in precedenza restituirà il nome dell'immagine in fase di elaborazione e il dizionario delle etichette associate a quell'immagine. Una funzione chiamata find_values viene utilizzata per ottenere solo le etichette dalla risposta. Il nome dell'immagine e le relative etichette sono quindi pronti per essere caricati nella tabella DynamoDB.

    def find_values(id, json_repr): results = [] def _decode_dict(a_dict): try: results.append(a_dict[id]) except KeyError: pass return a_dict json.loads(json_repr, object_hook=_decode_dict) # Return value ignored. return results
  3. Utilizzerai una terza funzione, chiamata load_data, per caricare effettivamente le immagini e le etichette nella tabella DynamoDB che hai creato.

    def load_data(image_labels, dynamodb=None): if not dynamodb: dynamodb = boto3.resource('dynamodb') table = dynamodb.Table('Images') print("Adding image details:", image_labels) table.put_item(Item=image_labels) print("Success!!")
  4. Qui vengono chiamate le tre funzioni che abbiamo definito in precedenza e dove vengono eseguite le operazioni. Aggiungi le tre funzioni sopra definite, insieme al codice seguente, a un file Python. Eseguire il codice.

    bucket = "bucket_name" file_list = get_image_names(bucket) for file in file_list: file_name = file print("Getting labels for " + file_name) image_name, image_labels = read_image_from_s3(bucket, file_name) image_json_string = json.dumps(image_labels, indent=4) labels=set(find_values("Name", image_json_string)) print("Labels found: " + str(labels)) labels_dict = {} print("Saving label data to database") labels_dict["Image"] = str(image_name) labels_dict["Labels"] = str(labels) print(labels_dict) load_data(labels_dict) print("Success!")

Hai appena generato etichette per le tue immagini e le hai archiviate in un'istanza di DynamoDB. DetectLabels Assicurati di eliminare tutte le risorse che hai creato durante questo tutorial. In questo modo eviterai che ti vengano addebitate risorse che non utilizzi.

Creazione di un database MySQL in Amazon RDS

Prima di andare oltre, assicurati di aver completato la procedura di configurazione per Amazon RDS e di aver creato un'istanza DB MySQL utilizzando Amazon RDS.

Il codice seguente utilizza la libreria PyMySQL e l'istanza database Amazon RDS. Crea una tabella per contenere i nomi delle immagini e le etichette associate a tali immagini. Amazon RDS riceve comandi per creare tabelle e inserire dati nelle tabelle. Per utilizzare Amazon RDS, devi connetterti all'host Amazon RDS utilizzando il nome host, il nome utente e la password. Potrai connetterti ad Amazon RDS fornendo questi argomenti alla connect funzione di PyMy SQL e creando un'istanza di cursore.

  1. Nel codice seguente, sostituisci il valore di host con il tuo endpoint host Amazon RDS e sostituisci il valore di user con il nome utente principale associato all'istanza Amazon RDS. Dovrai inoltre sostituire la password con la password principale dell'utente principale.

    import pymysql host = "host-endpoint" user = "username" password = "master-password"
  2. Crea un database e una tabella in cui inserire i dati dell'immagine e dell'etichetta. Fatelo eseguendo e commettendo una query di creazione. Usa il seguente codice per creare un database. Esegui questo codice solo una volta.

    conn = pymysql.connect(host=host, user=user, passwd=password) print(conn) cursor = conn.cursor() print("Connection successful") # run once create_query = "create database rekogDB1" print("Creation successful!") cursor.execute(create_query) cursor.connection.commit()
  3. Una volta creato il database, è necessario creare una tabella in cui inserire i nomi e le etichette delle immagini. Per creare una tabella, devi prima passare il comando use SQL, insieme al nome del tuo database, alla execute funzione. Dopo aver effettuato la connessione, viene eseguita una query per creare una tabella. Il codice seguente si connette al database e quindi crea una tabella con una chiave primaria, chiamataimage_id, e un attributo di testo che memorizza le etichette. Usa le importazioni e le variabili che hai definito in precedenza ed esegui questo codice per creare una tabella nel tuo database.

    # connect to existing DB cursor.execute("use rekogDB1") cursor.execute("CREATE TABLE IF NOT EXISTS test_table(image_id VARCHAR (255) PRIMARY KEY, image_labels TEXT)") conn.commit() print("Table creation - Successful creation!")

Caricamento di dati su una tabella Amazon RDS MySQL

Dopo aver creato il database Amazon RDS e una tabella nel database, puoi ottenere etichette per le tue immagini e memorizzarle nel database Amazon RDS.

  1. Connettiti al tuo bucket Amazon S3 e recupera i nomi di tutte le immagini nel bucket. Questi nomi di immagini verranno passati alla read_image_from_s3 funzione creata in precedenza per ottenere le etichette per tutte le immagini. Il codice seguente si collega al tuo bucket Amazon S3 e restituisce un elenco di tutte le immagini nel bucket.

    import pymysql from get_images import read_image_from_s3 import json import boto3 host = "host-endpoint" user = "username" password = "master-password" conn = pymysql.connect(host=host, user=user, passwd=password) print(conn) cursor = conn.cursor() print("Connection successful") def get_image_names(name_of_bucket): s3_resource = boto3.resource('s3') my_bucket = s3_resource.Bucket(name_of_bucket) file_list = [] for file in my_bucket.objects.all(): file_list.append(file.key) return file_list
  2. La risposta dell'DetectLabelsAPI non contiene solo le etichette, quindi scrivi una funzione per estrarre solo i valori delle etichette. La seguente funzione restituisce un elenco completo delle sole etichette.

    def find_values(id, json_repr): results = [] def _decode_dict(a_dict): try: results.append(a_dict[id]) except KeyError: pass return a_dict json.loads(json_repr, object_hook=_decode_dict) # Return value ignored. return results
  3. Avrai bisogno di una funzione per inserire i nomi e le etichette delle immagini nella tua tabella. La seguente funzione esegue una query di inserimento e inserisce una determinata coppia di nomi ed etichette di immagini.

    def upload_data(image_id, image_labels): # insert into db cursor.execute("use rekogDB1") query = "INSERT IGNORE INTO test_table(image_id, image_labels) VALUES (%s, %s)" values = (image_id, image_labels) cursor.execute(query, values) conn.commit() print("Insert successful!")
  4. Infine, è necessario eseguire le funzioni definite in precedenza. Nel codice seguente, i nomi di tutte le immagini nel bucket vengono raccolti e forniti alla funzione che chiama DetectLabels. Successivamente, le etichette e il nome dell'immagine a cui si riferiscono vengono caricate nel tuo database Amazon RDS. Copia le tre funzioni sopra definite, insieme al codice seguente, in un file Python. Esegui il file Python.

    bucket = "bucket-name" file_list = get_image_names(bucket) for file in file_list: file_name = file print("Getting labels for " + file_name) image_name, image_labels = read_image_from_s3(bucket, file_name) image_json = json.dumps(image_labels, indent=4) labels=set(find_values("Name", image_json)) print("Labels found: " + str(labels)) unique_labels=set(find_values("Name", image_json)) print(unique_labels) image_name_string = str(image_name) labels_string = str(unique_labels) upload_data(image_name_string, labels_string) print("Success!")

Hai generato con successo etichette per le tue immagini e le hai archiviate in un database MySQL utilizzando Amazon RDS. DetectLabels Assicurati di eliminare tutte le risorse che hai creato durante questo tutorial. Questo eviterà che ti vengano addebitate risorse che non utilizzi.

Per altri esempi AWS multiservizio, consulta l'archivio degli esempi di Documentation SDK. AWS GitHub