RestFul API

instargram 사진 포스팅 API (3) rekognition을 이용한 자동 태그 만들기

567Rabbit 2024. 5. 30. 18:07

 

태그를 자동으로 만들어주는 것은 rekognition 포스팅을 참조하기 바란다.

 

https://codebunny99.tistory.com/109

 

AWS S3와 연결하여 AWS Rekognition으로 이미지 인식 태그 API 만들기

https://docs.aws.amazon.com/ko_kr/rekognition/latest/dg/labels-detect-labels-image.html 이미지에서 레이블 감지 - Amazon Rekognition기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경

codebunny99.tistory.com

 

 

 

테이블을 만든다.

 

 

updatedAt은 now() on update now()를 입력하고 apply 해주면 입력된다.

 

 

 

 

 

 

 


app.py 파일에 추가한다.

from resources.posting import PostingListResource

api.add_resource( PostingListResource , '/posting')

 

 

 

 

resources 폴더를 만들고, 그 안에 posting.py 파일을 입력한다.

from datetime import datetime
from flask import request
from flask_jwt_extended import get_jwt_identity, jwt_required
from flask_restful import Resource
from config import Config
from mysql_connection import get_connection
from mysql.connector import Error

import boto3


class PostingListResource(Resource) :
    
    @jwt_required()
    def post(self) :
        
        # 1. 클라이언트로부터 데이터를 받아온다
        
        if 'image' not in request.files :
            return {"result":"fail", "error":"파일을 업로드 하세요."}, 400
        
        if 'content' not in request.form :
            return {"result":"fail", "error":"내용을 작성 하세요."}, 400
        
        file = request.files['image']
        content = request.form['content']
        
        user_id = get_jwt_identity()
        
        # 2. 사진을 S3에 업로드한다
        
        if file is None :
            return {'result':'fail',
                    'error':'파일을 업로드 하세요'}, 400
        
        if 'image' not in file.content_type :
            return {'result':'fail',
                    'error':'이미지 파일만 업로드 가능합니다'}, 400
        
        client = boto3.client('s3', 
                              aws_access_key_id= Config.AWS_ACCESS_KEY_ID, 
                              aws_secret_access_key = Config.AWS_SECRET_ACCESS_KEY)
        
        # 파일 이름을 유니크하게 만들어줘야 한다
        current_time = datetime.now()
        file_name = current_time.isoformat().replace(':','_') + str(user_id) + '.jpg'
        file.filename = file_name
        
        try :
            client.upload_fileobj(file,
                                  Config.AWS_S3_BUCKET,
                                  file.filename,
                                  ExtraArgs = {'ACL':'public-read',
                                               'ContentType':'image/jpeg'})
        except Exception as e:
            return {'result':'fail', 'error':str(e)}, 500
        
        # 3. 업로드한 사진의 URL을 만든다
        image_url = Config.AWS_FILE_URL + file.filename
        
        # 3-2. rekognition을 이용해서, object detection 한다.
        label_list = self.detect_labels(file_name, Config.AWS_S3_BUCKET)
        
        # 3-3 리스트를 하나의 문자열로 만들기
        label_str = ','.join(label_list)
        
        # 3-4 한글로 번역하기
        label_str = self.translate(label_str)
        
        # 3-5 하나의 문자열을 쪼개서 리스트로 다시 바꿔주기
        label_list = label_str.split(', ')
        
        
        # 4. DB에 user_id, image_url, content를 저장한다
        try :
            connection = get_connection()
            query = '''insert into posting
                        (userId, imageUrl, content)
                        values
                        ( %s,%s,%s);'''
            record = (user_id, image_url, content)
            
            cursor = connection.cursor()
            cursor.execute(query, record)
            
            photoId = cursor.lastrowid
            
            for label in label_list :
                
                # tag 테이블에, label이 있는지 확인해서, 있으면 아이디를 가져오고 없으면 인서트한 후에 아이디를 가져온다
                
                query = '''select * 
                            from tag
                            where tag_name = %s;'''
                record = (label, )
                
                cursor = connection.cursor(dictionary=True)
                cursor.execute(query, record)
                
                result_list = cursor.fetchall()
                
                if len(result_list) != 0 :
                    tagId = result_list[0]['id']
                else :
                    query = '''insert into tag
                                (tag_name)
                                values
                                (%s);'''
                    record = (label,)
                    
                    cursor = connection.cursor()
                    cursor.execute(query,record)
                    
                    tagId = cursor.lastrowid
                
                    
                    # 위의 tagId를 postingTag 테이블에 postingId와 함께 넣어준다
                query = '''insert into postingTag
                            (photoId, tagId)
                            values
                            (%s, %s);'''
                record = (photoId, tagId)
                
                cursor = connection.cursor()
                cursor.execute(query,record)
    
            connection.commit()
            
            cursor.close()
            connection.close()
        
        
        except Error as e:
            if cursor is not None:  # null이 아니면
                cursor.close()
            if connection is not None:
                connection.close()
            return {'result': 'fail', 'error': str(e)}, 500  # 500 에러
        
        
        # 5. 클라이언트에 json으로 응답한다  
        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_ID,
                    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
    
    
    def translate(self, text):
        
        translate = boto3.client(service_name='translate', region_name='ap-northeast-2'
                                 ,aws_access_key_id = Config.AWS_TRANSLATE_ACCESS_KEY
                                 ,aws_secret_access_key = Config.AWS_TRANSLATE_SECRET_ACCESS)

        result = translate.translate_text(Text=text, 
                    SourceLanguageCode="en", TargetLanguageCode="ko")
        print('TranslatedText: ' + result.get('TranslatedText'))
        print('SourceLanguageCode: ' + result.get('SourceLanguageCode'))
        print('TargetLanguageCode: ' + result.get('TargetLanguageCode'))
        
        return result.get('TranslatedText')

 

 

 

https://codebunny99.tistory.com/115

 

AWS Translate를 이용해서 영어 태그를 한글로 바꾸기

https://docs.aws.amazon.com/translate/latest/dg/get-started-sdk.html Getting started (SDK) - Amazon TranslateThanks for letting us know this page needs work. We're sorry we let you down. If you've got a moment, please tell us how we can make the documenta

codebunny99.tistory.com

 

번역하기는 위 블로그 포스팅을 참조한다.

 

 

 

 

 

포스트맨의 Headers 부분에, 로그인 한 유저의 accessToken 을 Bearer 뒤에 붙여넣기 하고,

 

 

 

 

 

사진을 넣고 send를 누르면 이처럼 태그가 입력된다.

 

 

 

 

 

MySQL에서 입력하여 실행하면,

select tag_name, userId
from posting p
left join postingTag pt
	on p.id = pt.photoId
left join tag t
	on t.id = pt.tagId
where userId = 2;

 

 

 

태그를 한 내용이 DB에 저장된다.