DevOps/AWS

AWS S3์™€ ์—ฐ๊ฒฐํ•˜์—ฌ AWS Rekognition์œผ๋กœ ์ด๋ฏธ์ง€ ์ธ์‹ ํƒœ๊ทธ API ๋งŒ๋“ค๊ธฐ

567Rabbit 2024. 5. 28. 15:10

https://docs.aws.amazon.com/ko_kr/rekognition/latest/dg/labels-detect-labels-image.html

 

์ด๋ฏธ์ง€์—์„œ ๋ ˆ์ด๋ธ” ๊ฐ์ง€ - Amazon Rekognition

๊ธฐ๊ณ„ ๋ฒˆ์—ญ์œผ๋กœ ์ œ๊ณต๋˜๋Š” ๋ฒˆ์—ญ์ž…๋‹ˆ๋‹ค. ์ œ๊ณต๋œ ๋ฒˆ์—ญ๊ณผ ์›๋ณธ ์˜์–ด์˜ ๋‚ด์šฉ์ด ์ƒ์ถฉํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” ์˜์–ด ๋ฒ„์ „์ด ์šฐ์„ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฏธ์ง€์—์„œ ๋ ˆ์ด๋ธ” ๊ฐ์ง€ ์ด DetectLabels์ž‘์—…์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฏธ์ง€์—์„œ ๋ ˆ์ด๋ธ” (

docs.aws.amazon.com

- ๋ฉ”๋‰ด์–ผ์„ ์ฐธ๊ณ ํ•œ๋‹ค.

 

 

 

 

์•„๋ž˜๋ฅผ ์ฐธ๊ณ ํ•˜์—ฌ ๋ฒ„ํ‚ท์„ ๋งŒ๋“ ๋‹ค.

 

https://msdev-st.tistory.com/155

 

[AWS] S3 ๋ฒ„ํ‚ท ๋งŒ๋“ค๊ธฐ _ ์Šคํ† ๋ฆฌ์ง€ ๋งŒ๋“ค์–ด์„œ ์‚ฌ์šฉํ•˜๊ธฐ

S3 ๋ฒ„ํ‚ท ๋งŒ๋“ค๊ธฐ _ ์Šคํ† ๋ฆฌ์ง€ ๋งŒ๋“ค์–ด์„œ ์‚ฌ์šฉํ•˜๊ธฐAWS์˜ S3๋ž€? Simple Storage Service์˜ ์•ฝ์ž๋กœ ํŒŒ์ผ ์„œ๋ฒ„์˜ ์—ญํ• ์„ ํ•˜๋Š” ์„œ๋น„์Šค๋‹ค. ์ผ๋ฐ˜์ ์ธ ํŒŒ์ผ์„œ๋ฒ„๋Š” ํŠธ๋ž˜ํ”ฝ์ด ์ฆ๊ฐ€ํ•จ์— ๋”ฐ๋ผ์„œ ์žฅ๋น„๋ฅผ ์ฆ์„คํ•˜๋Š” ์ž‘

msdev-st.tistory.com

 

 

 

 

 

aws์˜ IAM์—์„œ,  AmazonRekognitionFullAcess ๊ถŒํ•œ์ถ”๊ฐ€ํ•˜๊ธฐ

 

 

 

 

 

 

 

serverless๋กœ ๋งŒ๋“  ํด๋”๋ฅผ vscode๋กœ ์—ฐ๋‹ค.

 

 

 

 

 

๋ฒ„ํ‚ท ๋งŒ๋“ค ๋•Œ ์‚ฌ์šฉํ•œ ์ด๋ฆ„์„ ๋„ฃ์œผ๋ฉด ๋œ๋‹ค.

 

 

 

 

 

app.py ์ž‘์„ฑ

from flask import Flask
from flask_restful import Api

from resources.image import FileUploadResource

app = Flask(__name__)

api = Api(app)

# ๊ฒฝ๋กœ์™€ ๋ฆฌ์†Œ์Šค๋ฅผ ์—ฐ๊ฒฐํ•œ๋‹ค.
api.add_resource( FileUploadResource , '/upload' )

if __name__ == '__main__' :
    app.run()

 

 

 

 

 

resources ํด๋” ์•ˆ์— image.py ์ž‘์„ฑ

from flask_restful import Resource
from flask import request

from datetime import datetime

import boto3

from config import Config


class FileUploadResource(Resource) :

    def post(self):
        # 1. ํด๋ผ์ด์–ธํŠธ๋กœ๋ถ€ํ„ฐ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์˜จ๋‹ค.
        #    ํŒŒ์ผ์€ request.files ์•ˆ์— ์žˆ๊ณ ,
        #    ํ…์ŠคํŠธ๋Š” request.form ์•ˆ์— ์žˆ๋‹ค.

        if 'photo' not in request.files :
            return {"result":"fail", "error":"ํŒŒ์ผ์„ ์—…๋กœ๋“œ ํ•˜์„ธ์š”."}, 400
        
        if 'content' not in request.form :
            return {"result":"fail", "error":"๋‚ด์šฉ์„ ์ž‘์„ฑ ํ•˜์„ธ์š”."}, 400
        
        file = request.files.get('photo')
        
        if 'image' not in file.content_type :
            return {'result':'fail',
                    'error':'์ด๋ฏธ์ง€ ํŒŒ์ผ๋งŒ ์—…๋กœ๋“œ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค'}, 400
        
        print(file)

        content = request.form['content']
        print(content)

        # ํŒŒ์ผ์„ s3์— ์—…๋กœ๋“œ ํ•ด์•ผ ํ•˜๋Š”๋ฐ,
        # ๋จผ์ €, ํŒŒ์ผ๋ช…์€ ์œ ๋‹ˆํฌ ํ•ด์•ผ ํ•œ๋‹ค.
        # ๋”ฐ๋ผ์„œ, ์œ ๋‹ˆํฌํ•œ ํŒŒ์ผ๋ช…์œผ๋กœ ๋ฐ”๊ฟ”์„œ ์—…๋กœ๋“œ ํ•œ๋‹ค.

        # ํ˜„์žฌ์‹œ๊ฐ„๊ณผ ์œ ์ €์•„์ด๋”” ๋“ฑ์„ ์กฐํ•ฉํ•ด์„œ ๋งŒ๋“ ๋‹ค.
        current_time = datetime.now()
        file_name = current_time.isoformat().replace(':','_') + '.' + file.content_type.split('/')[-1]
        print(file_name)

        # ์œ ์ €๊ฐ€ ์—…๋กœ๋“œํ•œ ํŒŒ์ผ๋ช…์„, ๋‚ด๊ฐ€ ๋งŒ๋“  ํŒŒ์ผ๋ช…์œผ๋กœ ๋ฐ”๊พผ๋‹ค.
        file.filename = file_name

        # s3์— ํŒŒ์ผ์„ ์—…๋กœ๋“œํ•œ๋‹ค.
        # aws์˜ ์„œ๋น„์Šค๋“ค์„ ํŒŒ์ด์ฌ์ฝ”๋“œ๋กœ ์ž‘์„ฑ ํ•  ์ˆ˜ ์žˆ๋Š” 
        # boto3 ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ด์šฉํ•ด์„œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•œ๋‹ค.
        # ( ์„ค์น˜๋Š”, $ pip install boto3 )

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

        # ExtraArgs = {'ACL':'public-read','ContentType':'image/jpg'} ์ค‘์š”๋ถ€๋ถ„

        try :
            client.upload_fileobj(file,
                                  Config.S3_BUCKET,
                                  file_name,
                                  ExtraArgs = {'ACL':'public-read',
                                               'ContentType':file.content_type})
        except Exception as e:
            return {"result":"fail", "error":str(e)}, 500


        return {"result":"success", "url":Config.S3_URL + file_name}

 

 

 

vscode cmd์—์„œ ์„ค์น˜ํ•œ๋‹ค.

pip install boto3

 

 

 

rekognition.py ์ž‘์„ฑ

from flask import request
from flask_restful import Resource
from datetime import datetime
import boto3

from config import Config


class ObjectDetectionResource(Resource):
    def post(self):

        if 'photo' not in request.files :
            return {"result":"fail", "error":"์‚ฌ์ง„์€ ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค."}, 400
        
        file = request.files['photo']

        if 'image' not in file.content_type :
            return {"result":"fail", "error":"์ด๋ฏธ์ง€ํŒŒ์ผ์„ ์—…๋กœ๋“œ ํ•˜์„ธ์š”."}, 400
        
        current_time = datetime.now()
        file_name = current_time.isoformat().replace(':','_') + '.jpg'

        file.filename = file_name

        # s3์— ์—…๋กœ๋“œ
        # rekognition ์„œ๋น„์Šค๋ฅผ ์ด์šฉํ•˜๋ ค๋ฉด,
        # ๋จผ์ € s3์— ์ด๋ฏธ์ง€ ํŒŒ์ผ์„ ์—…๋กœ๋“œ ํ•ด๋†”์•ผ ํ•œ๋‹ค

        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'})
        except Exception as e:
            return {"result":"fail", "error":str(e)}, 500


        # ๋ฆฌ์ฝ”๊ทธ๋‹ˆ์…˜์„ ์ด์šฉ
        label_list = self.detect_labels(file_name, Config.S3_BUCKET)
        

        return {"result":"success", "lable": label_list}
    
    def detect_labels(self, photo, bucket):

        client = boto3.client('rekognition',
                     'ap-northeast-2',
                     aws_access_key_id = Config.AWS_ACCESS_KEY,
                     aws_secret_access_key = Config.AWS_SECRET_ACCESS_KEY)

        response = client.detect_labels(Image={'S3Object':{'Bucket':bucket,'Name':photo}},
        MaxLabels=10,
        # Uncomment to use image properties and filtration settings
        #Features=["GENERAL_LABELS", "IMAGE_PROPERTIES"],
        #Settings={"GeneralLabels": {"LabelInclusionFilters":["Cat"]},
        # "ImageProperties": {"MaxDominantColors":10}}
        )

        print('Detected labels for ' + photo)
        print()
        print(response['Labels'])

        label_list = []

        for label in response['Labels']:
            print("Label: " + label['Name'])
            label_list.append(label['Name'])



        return label_list

 

 

 

 

 

 

์‚ฌ์ง„ ์—…๋กœ๋“œ API ํฌ์ŠคํŠธ๋งจ ์ž‘์„ฑ

 

 

 

 

 

sendํ•˜๊ณ , s3 ๋ฒ„ํ‚ท์— ๋“ค์–ด๊ฐ€๋ณด๋ฉด ์•„๋ž˜์ฒ˜๋Ÿผ ์‚ฌ์ง„์„ sendํ•œ ๋ชฉ๋ก๋“ค์ด ๋œฌ๋‹ค.

 

 

 

 

 

 

object detection API ํฌ์ŠคํŠธ๋งจ ์ž‘์„ฑํ•˜๊ณ  sendํ•˜๋ฉด

 

 

 

 

 

vscode์—์„œ๋Š” ์ด๋ ‡๊ฒŒ ๋œฌ๋‹ค.

 

 

 

 

 

 

 

.jpeg, .jpg ๋“ฑ์˜ ํƒ€์ž… ์„ค๋ช… ํ™ˆํŽ˜์ด์ง€ ๋งํฌ์ด๋‹ค.

 

https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types

 

Common MIME types - HTTP | MDN

This topic lists the most common MIME types with corresponding document types, ordered by their common extensions.

developer.mozilla.org