

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# Amazon RDS および DynamoDB で Amazon Rekognition データを保存する
<a name="storage-tutorial"></a>

Amazon Rekognition の API を使用する場合、API オペレーションは生成されたラベルを一切保存しないことを覚えておくことが重要です。これらのラベルは、それぞれのイメージの識別子と一緒にデータベースに登録することで保存できます。

このチュートリアルでは、ラベルを検出し、検出したラベルをデータベースに保存する方法を説明します。このチュートリアルで開発されたサンプルアプリケーションは、[Amazon S3](https://docs.aws.amazon.com/s3/index.html) バケットからイメージを読み取り、そのイメージに対して [DetectLabels](https://docs.aws.amazon.com/rekognition/latest/APIReference/API_DetectLabels.html) オペレーションを呼び出し、結果のラベルをデータベースに保存します。アプリケーションは、使用したいデータベースタイプに応じて、Amazon RDS データベースインスタンスまたは DynamoDB データベースのいずれかにデータを保存します。

[AWS SDK for Python](https://aws.amazon.com/sdk-for-python/) またはこのチュートリアルを使用することになります。その他の Python チュートリアルについては、 AWS 「Documentation SDK examples [GitHub repo](https://github.com/awsdocs/aws-doc-sdk-examples)」も参照してください。

**Topics**
+ [前提条件](#storage-tutorial-prerequisites)
+ [Amazon S3 バケット内のイメージのラベルを取得する](#storage-tutorial-getting-labels)
+ [Amazon DynamoDB テーブルを作成する](#storage-tutorial-creating-dynamodb)
+ [DynamoDB へのデータのアップロード](#storage-tutorial-uploading-dynamodb)
+ [Amazon RDS で MySQL データベースを作成する](#storage-tutorial-creating-mysql)
+ [Amazon RDS の MySQL テーブルへのデータのアップロード](#storage-tutorial-uploading-mysql)

## 前提条件
<a name="storage-tutorial-prerequisites"></a>

このチュートリアルを開始する前に、Python をインストールし、[Python AWS SDK のセットアップ](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/quickstart.html)に必要な手順を完了する必要があります。これ以外にも、次のことを確認してください:

[AWS アカウントと IAM ロールを作成しました](https://docs.aws.amazon.com/rekognition/latest/dg/setting-up.html)

[Python SDK (Boto3) をインストールしました](https://aws.amazon.com/sdk-for-python/)

[AWS アクセス認証情報を適切に設定する](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html)

[Amazon S3 バケットを作成し、イメージで埋め尽くしました](https://docs.aws.amazon.com/AmazonS3/latest/userguide/create-bucket-overview.html)

RDS を使用してデータを保存する場合、[RDS データベースインスタンスを作成した](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_CreateDBInstance.html)



## Amazon S3 バケット内のイメージのラベルを取得する
<a name="storage-tutorial-getting-labels"></a>

まず、Amazon S3 バケットにあるイメージの名前を受け取り、そのイメージを取得する関数を作成します。このイメージは、正しいイメージが関数内の [DetectLabels](https://docs.aws.amazon.com/rekognition/latest/APIReference/API_DetectLabels.html) の呼び出しに渡されていることを確認するために表示されます。

1. 使用したい Amazon S3 バケットを見つけ、名前を書き込みます。この Amazon S3 バケットを呼び出して、その中のイメージを読み取ります。[DetectLabels](https://docs.aws.amazon.com/rekognition/latest/APIReference/API_DetectLabels.html) オペレーションに渡すイメージがバケットに含まれていることを確認します。

1. Amazon S3 バケットに接続するためのコードを書き込みます。Boto3 を使用して Amazon S3 リソースに接続して、Amazon S3 バケットからイメージを取得できます。Amazon S3 リソースに接続したら、バケットメソッドに Amazon S3 バケット名を指定して、バケットにアクセスできます。Amazon S3 バケットに接続後、Object メソッドでバケットからイメージを取得します。Matplotlib を利用することで、この接続を使用してイメージを可視化することができます。Boto3 は、Rekognition クライアントへの接続にも使用されます。

   以下のコードで、リージョンを region\_name パラメータに指定します。[DetectLabels](https://docs.aws.amazon.com/rekognition/latest/APIReference/API_DetectLabels.html) に Amazon S3 バケット名とイメージ名を渡すと、対応するイメージのラベルが返されます。レスポンスからラベルのみを選択すると、イメージ名とラベルの両方が返されます。

   ```
   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
   ```

1. このコードを get\_images.py というファイルに保存します。

## Amazon DynamoDB テーブルを作成する
<a name="storage-tutorial-creating-dynamodb"></a>

以下のコードでは、boto3 を使って DynamoDB に接続し、DynamoDB `CreateTable` メソッドを使って、Images という名前のテーブルを作成しています。テーブルには、Image というパーティションキーおよび Labels というソートキーで構成されている複合プライマリキーがあります。Image キーにはイメージの名前が含まれ、Labels キーにはそのイメージに割り当てられたラベルが保存されます。

```
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)
```

このコードをエディタに保存し、一度実行すると DynamoDB テーブルが作成されます。

## DynamoDB へのデータのアップロード
<a name="storage-tutorial-uploading-dynamodb"></a>

DynamoDB データベースが作成され、イメージのラベルを取得する関数ができたので、ラベルを DynamoDB に保存することができます。次のコードは、S3 バケット内のすべてのイメージを取得し、それらのラベルを取得し、データを DynamoDB に保存します。

1. DynamoDB にデータをアップロードするためのコードを書く必要があります。`get_image_names` という関数で Amazon S3 バケットに接続し、バケット内のすべてのイメージの名前をリストとして返します。このリストを `read_image_from_S3` 関数に渡すと、作成した `get_images.py` ファイルからインポートされます。

   ```
   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
   ```

1. 先ほど作成した `read_image_from_S3` 関数は、処理中のイメージの名前と、そのイメージに関連するラベルのディクショナリを返します。`find_values` という関数は、レスポンスからラベルのみを取得するために使用されます。イメージの名前とそのラベルを 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
   ```

1. `load_data` という 3 番目の関数で、作成した DynamoDB テーブルにイメージとラベルを実際にロードします。

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

1. ここでは、前回定義した 3 つの関数が呼び出され、オペレーションが実行されます。上記で定義した 3 つの関数を、以下のコードとともに 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_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!")
   ```

[DetectLabels](https://docs.aws.amazon.com/rekognition/latest/APIReference/API_DetectLabels.html) を使用してイメージのラベルを生成し、そのラベルを DynamoDB インスタンスに保存します。このチュートリアルの間に作成したリソースはすべて取り外しておいてください。これにより、使用していないリソースに課金されることを防ぐことができます。

## Amazon RDS で MySQL データベースを作成する
<a name="storage-tutorial-creating-mysql"></a>

先に進む前に、Amazon RDS の [セットアップ手順](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_SettingUp.html) が完了し、Amazon RDS を使用して [MySQL DB インスタンスを作成した](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_GettingStarted.CreatingConnecting.MySQL.html) ことを確認してください。

次のコードは、[PyMySQL](https://pypi.org/project/PyMySQL/) ライブラリと Amazon RDS DB インスタンスを利用しています。イメージの名前とそのイメージに関連するラベルを保持するためのテーブルを作成します。Amazon RDS は、テーブルの作成とテーブルへのデータ挿入のコマンドを受け取ります。Amazon RDS を使用するには、ホスト名、ユーザーネーム、パスワードを使用して Amazon RDS ホストに接続する必要があります。これらの引数を PyMySQL の `connect` 関数に与え、カーソルのインスタンスを作成することで、 Amazon RDS に接続することになります。

1. 次のコードでは、ホストの値を Amazon RDS ホストエンドポイントに置き換え、ユーザーの値を Amazon RDS インスタンスに関連付けられたマスターユーザーネームに置き換えます。また、パスワードをメインユーザーのマスターパスワードに置き換える必要があります。

   ```
   import pymysql
   
   host = "host-endpoint"
   user = "username"
   password = "master-password"
   ```

1. データベースと、イメージとラベルデータを挿入するテーブルを作成します。作成クエリを実行し、コミットすることで行います。次のコードでは、データベースを作成します。このコードは 1 回だけ実行してください。

   ```
   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()
   ```

1. データベースを作成したら、イメージ名とラベルを挿入するテーブルを作成する必要があります。テーブルを作成するには、まず use SQL コマンドとデータベースの名前を `execute` 関数に渡します。接続が完了すると、テーブルを作成するためのクエリが実行されます。次のコードは、データベースに接続し、`image_id` というプライマリキーと、ラベルを保存するテキスト属性の両方を持つテーブルを作成します。先ほど定義したインポートと変数を使用し、このコードを実行してデータベースにテーブルを作成します。

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

## Amazon RDS の MySQL テーブルへのデータのアップロード
<a name="storage-tutorial-uploading-mysql"></a>

 Amazon RDS データベースとデータベースにテーブルを作成した後、イメージのラベルを取得し、それらのラベルを Amazon RDS データベースに保存することができます。

1. Amazon S3 バケットに接続し、バケット内のすべてのイメージの名前を取得します。これらのイメージ名は、先に作成した `read_image_from_s3` 関数に渡され、すべてのイメージのラベルを取得します。次のコードは Amazon S3 バケットに接続し、バケット内のすべてのイメージのリストを返します。

   ```
   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
   ```

1. [DetectLabels](https://docs.aws.amazon.com/rekognition/latest/APIReference/API_DetectLabels.html) API からのリスポンスにはラベル以外のものも含まれているため、ラベルの値のみを抽出する関数を記述するようにしてください。次の関数は、ラベルだけを集めたリストを返します。

   ```
   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
   ```

1. イメージ名とラベルをテーブルに挿入する関数が必要です。次の関数は、挿入クエリを実行し、与えられたイメージ名とラベルのペアを挿入します。

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

1. 最後に、上で定義した関数を実行する必要があります。次のコードでは、バケット内のイメージすべての名前が収集され、[DetectLabels](https://docs.aws.amazon.com/rekognition/latest/APIReference/API_DetectLabels.html) を呼び出す関数に提供されます。その後、ラベルとラベルが適用されるイメージの名前が Amazon RDS データベースにアップロードされます。上記で定義した 3 つの関数を、以下のコードとともに Python ファイルにコピーします。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!")
   ```

DetectLabels を使用してイメージのラベルを生成し、Amazon RDS を使用して MySQL データベースにそのラベルを保存しました。このチュートリアルの間に作成したリソースはすべて取り外しておいてください。これにより、使用していないリソースに課金されることを防ぐことができます。

その他の AWS マルチサービスの例については、 AWS 「Documentation SDK examples [GitHub repository」を参照してください。](https://github.com/awsdocs/aws-doc-sdk-examples)