본문 바로가기
AWS/S3, Rekognition

[api] s3 Storage 이미지 저장, aws rekognition 얼굴 닮은꼴 비교 api

by 코끼리똥11 2024. 6. 21.

순서

s3 버킷 생성

iam 권한 부여

api 생성

 

s3.세팅

Amazon S3(Simple Storage Service)는 Amazon Web Services(AWS)에서 제공하는 객체 스토리지 서비스이다. S3는 웹 규모의 컴퓨팅 용량을 제공하며, 인터넷을 통해 데이터를 저장하고 검색할 수 있는 매우 확장 가능하고 안전한 솔루션이다.

 

S3 버킷 만드는방법

\

 

2.iam 권한

 

\

아래 보이는 권한 추가

엑세스 키를 저장해야함

 

 

 

 

코드

app.py

from flask import request
from flask_restful import Resource
from datetime import datetime
import boto3
from PIL import Image, ImageDraw
from io import BytesIO

from config import Config

class ObjectCompareFaces(Resource):
    def post(self):
        try:
            # Step 1: 파일 검증 및 S3 업로드
            sourceFile = request.files['sourceFile']
            if 'image' not in sourceFile.content_type:
                return {'result': 'fail', 'error': '이미지 파일을 업로드하세요.'}, 400
            
            targetFile = request.files['targetFile']
            if 'image' not in targetFile.content_type:
                return {'result': 'fail', 'error': '이미지 파일을 업로드하세요.'}, 400
            
            sourceFile_name = self.upload_to_s3(sourceFile)
            targetFile_name = self.upload_to_s3(targetFile)
            
            # Step 2: 얼굴 비교
            response = self.compare_faces(sourceFile_name, targetFile_name)
            
            return {"result": "success", "labels": response}
        
        except Exception as e:
            return {'result': 'fail', 'error': str(e)}, 500

    def upload_to_s3(self, file):
        # S3에 파일 업로드하는 메서드
        current_time = datetime.now()
        file_name = current_time.isoformat().replace(':', '_') + '.jpg'
        file.filename = file_name

        client = boto3.client('s3',
                              aws_access_key_id=Config.AWS_ACCESS_KEY,
                              aws_secret_access_key=Config.AWS_SECRET_ACCESS_KEY)

        try:
            client.upload_fileobj(file, Config.S3_BUCKET, file_name, ExtraArgs={'ACL': 'public-read', 'ContentType': 'image/jpeg'})
            return file_name
        except Exception as e:
            raise Exception(f"S3 업로드 실패: {str(e)}")

    def compare_faces(self, source_file_name, target_file_name):
        # 얼굴 비교 메서드
        client = boto3.client('rekognition', region_name='ap-northeast-2',
                              aws_access_key_id=Config.AWS_ACCESS_KEY,
                              aws_secret_access_key=Config.AWS_SECRET_ACCESS_KEY)

        try:
            # Step 1: S3에서 이미지 읽기
            source_image = self.read_image_from_s3(source_file_name)
            target_image = self.read_image_from_s3(target_file_name)

            # Step 2: Rekognition을 이용한 얼굴 비교
            response = client.compare_faces(SimilarityThreshold=10,
                                            SourceImage={'Bytes': source_image},
                                            TargetImage={'Bytes': target_image})

            # Step 3: 일치하는 얼굴 주위에 사각형 그리기
            target_image = Image.open(BytesIO(target_image))
            draw = ImageDraw.Draw(target_image)
            similarity_list = []

            for faceMatch in response['FaceMatches']:
                position = faceMatch['Face']['BoundingBox']
                similarity = str(faceMatch['Similarity'])
                similarity_list.append(similarity)

                imgWidth, imgHeight = target_image.size
                left = imgWidth * position['Left']
                top = imgHeight * position['Top']
                width = imgWidth * position['Width']
                height = imgHeight * position['Height']

                points = [
                    (left, top),
                    (left + width, top),
                    (left + width, top + height),
                    (left, top + height),
                    (left, top)
                ]

                draw.line(points, fill='#ff0000', width=2)
                similarity = round(float(similarity), 3)
                draw.text((left + width + 5, top), f"similarity : {similarity}%", fill='#ff0000')

            # Step 4: 결과 이미지 출력
            target_image.show()
            return similarity_list

        except Exception as e:
            raise Exception(f"얼굴 비교 실패: {str(e)}")

    def read_image_from_s3(self, file_name):
        # S3에서 이미지를 읽어오는 메서드
        client = boto3.client('s3',
                              aws_access_key_id=Config.AWS_ACCESS_KEY,
                              aws_secret_access_key=Config.AWS_SECRET_ACCESS_KEY)

        try:
            response = client.get_object(Bucket=Config.S3_BUCKET, Key=file_name)
            return response['Body'].read()

        except Exception as e:
            raise Exception(f"S3에서 이미지 읽기 실패: {str(e)}")