기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.
Amazon RDS 및 DynamoDB로 Amazon Rekognition 데이터 저장
Amazon Rekognition의 API를 사용할 때는 API 작업에서 생성된 레이블이 저장되지 않는다는 점을 기억해야 합니다. 이러한 레이블을 각 이미지의 식별자와 함께 데이터베이스에 배치하여 저장할 수 있습니다.
이 자습서에서는 레이블을 감지하고 감지된 레이블을 데이터베이스에 저장하는 방법을 보여줍니다. 이 자습서에서 개발한 샘플 애플리케이션은 Amazon S3 버킷에서 이미지를 읽고, 이러한 이미지에 대해 DetectLabels 작업을 직접 호출하고, 결과 레이블을 데이터베이스에 저장합니다. 해당 애플리케이션은 사용하려는 데이터베이스 유형에 따라 Amazon RDS 데이터베이스 인스턴스 또는 DynamoDB 데이터베이스에 데이터를 저장합니다.
이 자습서에서는 AWS SDK for Python
주제
사전 조건
이 자습서를 시작하기 전에 Python을 설치하고 Python AWS SDK를 설정하는
RDS를 사용하여 데이터를 저장하는 경우 RDS 데이터베이스 인스턴스 생성
Amazon S3 버킷에 있는 이미지에 대한 레이블 가져오기
Amazon S3 버킷의 이미지 이름을 가져와서 해당 이미지를 검색하는 함수를 작성하는 것으로 시작하세요. 이 이미지는 함수에 있는 DetectLabels에 대한 직접 호출에 올바른 이미지가 전달되고 있는지 확인하기 위해 표시됩니다.
-
사용하려는 Amazon S3 버킷을 찾아 이름을 적어 둡니다. 이 Amazon S3 버킷을 직접 호출하여 그 안에 있는 이미지를 읽어올 것입니다. DetectLabels 작업에 전달할 이미지가 버킷에 포함되어 있는지 확인하세요.
-
Amazon S3 버킷에 연결하기 위한 코드를 작성합니다. Boto3를 사용하여 Amazon S3 리소스에 연결하고 Amazon S3 버킷에서 이미지를 검색할 수 있습니다. Amazon S3 리소스에 연결되면 Bucket 메서드에 Amazon S3 버킷 이름을 제공하여 버킷에 액세스할 수 있습니다. Amazon S3 버킷에 연결한 후 Object 메서드를 사용하여 버킷에서 이미지를 가져옵니다. Matplotlib를 사용하면 이 연결을 사용하여 이미지가 처리되는 모습을 시각화할 수 있습니다. Boto3는 Rekognition 클라이언트에 연결하는 데에도 사용됩니다.
다음 코드에서 region_name 파라미터에 리전을 입력하세요. Amazon S3 버킷 이름과 이미지 이름을 DetectLabels에 전달하면 해당 이미지의 레이블이 반환됩니다. 응답에서 레이블만 선택하면 이미지 이름과 레이블이 모두 반환됩니다.
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
-
이 코드를 get_images.py 파일에 저장합니다.
Amazon DynamoDB 테이블 생성
다음 코드는 Boto3를 사용하여 DynamoDB에 연결하고 DynamoDB CreateTable
메서드를 사용하여 Images라는 테이블을 생성합니다. 이 테이블은 Image라는 파티션 키와 Labels라는 정렬 키로 구성된 복합 기본 키를 갖습니다. Image 키에는 이미지 이름이 포함되고 Labels 키에는 해당 Image에 할당된 레이블이 저장됩니다.
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로 데이터 업로드
이제 DynamoDB 데이터베이스가 생성되고 이미지의 레이블을 가져오는 함수가 생겼으므로 DynamoDB에 레이블을 저장할 수 있습니다. 다음 코드는 S3 버킷의 모든 이미지를 검색하고 이미지에 대한 레이블을 가져온 다음 DynamoDB에 데이터를 저장합니다.
-
DynamoDB에 데이터를 업로드하기 위한 코드를 작성해야 합니다.
get_image_names
라는 함수는 Amazon S3 버킷에 연결하는 데 사용되며 버킷에 있는 모든 이미지의 이름을 목록으로 반환합니다. 이 목록을 생성한get_images.py
파일에서 가져온read_image_from_S3
함수에 전달합니다.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
-
앞서 만든
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
-
load_data
라는 세 번째 함수를 사용하여 생성한 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!!")
-
여기서 이전에 정의한 세 가지 함수가 직접 호출되고 작업이 수행됩니다. 위에서 정의한 세 가지 함수를 아래 코드와 함께 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를 사용하여 이미지에 대한 레이블을 생성하고 해당 레이블을 DynamoDB 인스턴스에 저장했습니다. 이 자습서를 진행하면서 생성한 리소스를 모두 제거했는지 반드시 확인하세요. 그러면 사용하지 않는 리소스에 대한 비용이 청구되는 것을 방지할 수 있습니다.
Amazon RDS에서 MySQL 데이터베이스 생성
계속 진행하기 전에 Amazon RDS의 설정 절차를 완료하고 Amazon RDS를 사용하여 MySQL DB 인스턴스를 생성했는지 확인하세요.
다음 코드는 PyMySQLconnect
함수에 이러한 인수를 제공하고 커서 인스턴스를 생성하여 Amazon RDS에 연결합니다.
-
다음 코드에서는 호스트의 값을 Amazon RDS 호스트 엔드포인트로 바꾸고, 사용자의 값을 Amazon RDS 인스턴스와 연결된 마스터 사용자 이름으로 바꿉니다. 또한 암호를 기본 사용자의 마스터 암호로 바꿔야 합니다.
import pymysql 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") # run once create_query = "create database rekogDB1" print("Creation successful!") cursor.execute(create_query) cursor.connection.commit()
-
데이터베이스를 만든 후에는 이미지 이름과 레이블을 삽입할 테이블을 만들어야 합니다. 테이블을 생성하려면 먼저 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 테이블에 데이터 업로드
Amazon RDS 데이터베이스를 생성하고 그 안에 테이블을 생성하고 나면 이미지의 레이블을 가져와서 Amazon RDS 데이터베이스에 해당 레이블을 저장할 수 있습니다.
-
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
-
DetectLabels 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
-
테이블에 이미지 이름과 레이블을 삽입하는 함수가 필요합니다. 다음 함수는 삽입 쿼리를 실행하고 주어진 이미지 이름과 레이블 쌍을 삽입합니다.
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!")
-
마지막으로 위에서 정의한 함수를 실행해야 합니다. 다음 코드에서는 버킷에 있는 모든 이미지의 이름을 수집하여 DetectLabels를 직접 호출하는 함수에 제공합니다. 그런 다음 레이블과 해당 레이블이 적용되는 이미지 이름이 Amazon RDS 데이터베이스에 업로드됩니다. 위에서 정의한 세 가지 함수를 아래 코드와 함께 복사하여 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 설명서 SDK 예제 GitHub 리포지토리를 참조하세요.