Armazenamento de dados do Amazon Rekognition com Amazon RDS e DynamoDB - Amazon Rekognition

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

Armazenamento de dados do Amazon Rekognition com Amazon RDS e DynamoDB

Ao usar o Amazon Rekognition APIs, é importante lembrar que as operações da API não salvam nenhum dos rótulos gerados. Você pode salvar esses rótulos colocando-os no banco de dados, junto com identificadores para as respectivas imagens.

Este tutorial demonstra a detecção de rótulos e o salvamento desses rótulos detectados em um banco de dados. O aplicativo de amostra desenvolvido neste tutorial lerá imagens de um bucket do Amazon S3, chamará a DetectLabelsoperação nessas imagens e armazenará os rótulos resultantes em um banco de dados. O aplicativo armazenará dados em uma instância de banco de dados do Amazon RDS ou em um banco de dados do DynamoDB, dependendo do tipo de banco de dados que você gostaria de usar.

Você usará o AWS SDK para Python ou este tutorial. Você também pode ver o GitHub repositório de exemplos do SDK de AWS documentação para ver mais tutoriais em Python.

Pré-requisitos

Antes de começar este tutorial, você precisará instalar o Python e concluir as etapas necessárias para configurar o SDK do Python. AWS Além disso, confira se você:

Criou uma conta na AWS e um perfil do IAM

Instalou o SDK para Python (Boto3)

Configurou corretamente suas credenciais de AWS acesso

O bucket Amazon S3 criado o encheu de imagens

Criou uma instância de banco de dados RDS, se estiver usando o RDS para armazenar dados

Obter rótulos para imagens em um bucket do Amazon S3

Comece escrevendo uma função que pegue o nome de uma imagem em seu bucket do Amazon S3 e recupere essa imagem. Essa imagem será exibida para confirmar que as imagens corretas estão sendo passadas para uma chamada para a DetectLabelsqual também está na função.

  1. Encontre o bucket do Amazon S3 que você gostaria de usar e anote seu nome. Você fará chamadas para esse bucket do Amazon S3 e lerá as imagens dentro dele. Certifique-se de que seu bucket contenha algumas imagens para passar para a DetectLabelsoperação.

  2. Escreva o código para se conectar ao seu bucket Amazon S3. Você pode se conectar ao recurso Amazon S3 com o Boto3 para recuperar uma imagem de um bucket do Amazon S3. Uma vez conectado ao recurso Amazon S3, você pode acessar seu bucket fornecendo ao método Bucket o nome do seu bucket Amazon S3. Depois de se conectar ao bucket do Amazon S3, você recupera imagens do bucket usando o método Object. Ao usar o Matplotlib, você pode usar essa conexão para visualizar suas imagens à medida que elas são processadas. O Boto3 também é usado para se conectar ao cliente Rekognition.

    No código a seguir, forneça sua região ao parâmetro region_name. Você passará o nome do bucket do Amazon S3 e o nome da imagem para DetectLabels, que retornará os rótulos da imagem correspondente. Depois de selecionar apenas os rótulos da resposta, o nome da imagem e os rótulos são retornados.

    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. Salve esse código em um arquivo chamado get_images.py.

Criação de uma tabela do Amazon DynamoDB

O código a seguir usa o Boto3 para se conectar ao DynamoDB e usa o método CreateTable do DynamoDB para criar uma tabela chamada Images. A tabela tem uma chave primária composta que consiste em uma chave de partição chamada Imagem e uma chave de classificação chamada Rótulos. A chave Image contém o nome da imagem, enquanto a tecla Labels armazena os rótulos atribuídos a essa imagem.

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)

Salve esse código em um editor e execute-o uma vez para criar uma tabela do DynamoDB.

Carregar dados para o DynamoDB

Agora que o banco de dados do DynamoDB foi criado e você tem uma função para obter rótulos para imagens, você pode armazená-los no DynamoDB. O código a seguir recupera todas as imagens em um bucket do S3, obtém rótulos para elas e armazena os dados no DynamoDB.

  1. Você precisará escrever o código para fazer o upload dos dados para o DynamoDB. Uma função chamada get_image_names é usada para se conectar ao seu bucket do Amazon S3 e retorna os nomes de todas as imagens no bucket como uma lista. Você passará essa lista para a função read_image_from_S3, que é importada do arquivo get_images.py que você criou.

    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. A função read_image_from_S3 que criamos anteriormente retornará o nome da imagem que está sendo processada e o dicionário de rótulos associados a essa imagem. Uma função chamada find_values é usada para obter apenas os rótulos da resposta. O nome da imagem e seus rótulos estão então prontos para serem enviados para sua tabela do 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. Você usará uma terceira função, chame load_data, para realmente carregar as imagens e os rótulos na tabela do DynamoDB que você criou.

    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. É aqui que as três funções que definimos anteriormente são chamadas e as operações são realizadas. Adicione as três funções definidas acima, junto com o código abaixo, a um arquivo Python. Execute o código.

    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!")

Você acabou de gerar rótulos para suas imagens e armazená-los em uma instância do DynamoDB. DetectLabels Certifique-se de eliminar todos os recursos que você criou ao ler este tutorial. Isso evitará que você seja cobrado por recursos que não está usando.

Criação de um banco de dados MySQL no Amazon RDS

Antes de prosseguir, certifique-se de ter concluído o procedimento de configuração do Amazon RDS e criado uma instância de banco de dados MySQL usando o Amazon RDS.

O código a seguir usa a biblioteca PyMySQL e sua instância de banco de dados Amazon RDS. Ele cria uma tabela para conter os nomes de suas imagens e os rótulos associados a essas imagens. O Amazon RDS recebe comandos para criar tabelas e inserir dados nas tabelas. Para usar o Amazon RDS, você deve se conectar ao host do Amazon RDS usando seu nome de host, nome de usuário e senha. Você se conectará ao Amazon RDS fornecendo esses argumentos à connect função do PyMy SQL e criando uma instância de um cursor.

  1. No código a seguir, substitua o valor do host pelo endpoint do host do Amazon RDS e substitua o valor do usuário pelo nome de usuário principal associado à sua instância do Amazon RDS. Você também precisará substituir a senha pela senha mestra do seu usuário principal.

    import pymysql host = "host-endpoint" user = "username" password = "master-password"
  2. Crie um banco de dados e uma tabela para inserir seus dados de imagem e etiqueta. Faça isso executando e confirmando uma consulta de criação. O código a seguir cria um banco de dados. Execute esse código somente uma vez.

    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. Depois que o banco de dados for criado, você deverá criar uma tabela para inserir os nomes e rótulos das imagens. Para criar uma tabela, primeiro você passará o comando use SQL, junto com o nome do seu banco de dados, para a função execute. Depois que a conexão é feita, uma consulta para criar uma tabela é executada. O código a seguir se conecta ao banco de dados e cria uma tabela com uma chave primária, chamada image_id, e um atributo de texto armazenando os rótulos. Use as importações e variáveis que você definiu anteriormente e execute esse código para criar uma tabela em seu banco de dados.

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

Upload de dados para uma tabela MySQL do Amazon RDS

Depois de criar o banco de dados do Amazon RDS e uma tabela no banco de dados, você pode obter rótulos para suas imagens e armazená-los no banco de dados do Amazon RDS.

  1. Conecte-se ao seu bucket do Amazon S3 e recupere os nomes de todas as imagens no bucket. Esses nomes de imagem serão passados para a função read_image_from_s3 que você criou anteriormente para obter os rótulos de todas as suas imagens. O código a seguir se conecta ao seu bucket do Amazon S3 e retorna uma lista de todas as imagens em seu 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. A resposta da DetectLabelsAPI contém mais do que apenas os rótulos, então escreva uma função para extrair somente os valores dos rótulos. A função a seguir retorna uma lista cheia apenas dos rótulos.

    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. Você precisará de uma função para inserir os nomes e rótulos das imagens em sua tabela. A função a seguir executa uma consulta de inserção e insere qualquer par de nomes e rótulos de imagem.

    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. Finalmente, você deve executar as funções que você definiu acima. No código a seguir, os nomes de todas as imagens em seu bucket são coletados e fornecidos para a função que chama DetectLabels. Depois disso, os rótulos e o nome da imagem à qual eles se aplicam são enviados para seu banco de dados do Amazon RDS. Copie as três funções definidas acima com o código abaixo, em um arquivo Python. Execute o arquivo 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!")

Você usou com sucesso DetectLabels para gerar rótulos para suas imagens e armazenou esses rótulos em um banco de dados MySQL usando o Amazon RDS. Certifique-se de eliminar todos os recursos que você criou ao ler este tutorial. Isso evitará que você seja cobrado por recursos que não está usando.

Para ver mais exemplos AWS de vários serviços, consulte o repositório de exemplos GitHub do SDK de AWS documentação.