Notice
Recent Posts
Recent Comments
Link
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
Archives
Today
Total
관리 메뉴

JustDoEat

AWS comprehend, rembg, openai(달리-3)을 이용한 사진생성 본문

카테고리 없음

AWS comprehend, rembg, openai(달리-3)을 이용한 사진생성

kingmusung 2024. 1. 9. 16:36

전체소스 코드

import boto3
from collections import Counter
from openai import OpenAI
import requests
from PIL import Image
from io import BytesIO
from rembg import remove


# 키워드 추출하는 함수.
def extract_top_keywords(diary_text):
    comprehend_client = boto3.client('comprehend', region_name='ap-northeast-2')
    # boto3이라는 클라이언트를 쓰고 그 위에 comprehend를 올려서 쓴다는 이야기.
    # boto3 위에 comprehend 나 s3를 오려서 씀, region_name= 지역 이름. 한국은 다 서울임 ㅋㅋ
    cleaned_text = preprocess_diary_text(diary_text)
    # 다이러히 텍스트에 있는 공백을 제거 ㅇㅋㅇㅋ
    response = comprehend_client.detect_key_phrases(  # 텍스트에서 키워드를 감지하는 역할을 합니다
        Text=cleaned_text,
        LanguageCode='ko'
    )

    keywords = [phrase['Text'] for phrase in response['KeyPhrases']]
    stopwords = get_korean_stopwords()
    filtered_keywords = [keyword for keyword in keywords if keyword not in stopwords]
    keyword_counts = Counter(filtered_keywords)
    top_keywords = keyword_counts.most_common(2)

    return [keyword[0] for keyword in top_keywords]


def preprocess_diary_text(diary_text):
    cleaned_text = ''.join(char for char in diary_text if char.isalnum() or char.isspace())
    return cleaned_text


def get_korean_stopwords():
    stopwords = [
        "나", "오늘", "우리", "저희", "따라", "의해", "을", "를", "에", "의", "가", "으로", "로", "에게", "뿐이야",
        "여서", "그리고"
    ]
    return stopwords


def generate_sticker_image(keyword):
    client = OpenAI(api_key="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")

    response = client.images.generate(
        model="dall-e-3",
        prompt=f"{keyword} 스티커",
        size="1024x1024",
        quality="standard",
        n=1,  # 한번에 하나씩 밖에 생성못함.
    )

    image_url = response.data[0].url
    return image_url


def remove_background(image_data):  # 이미지
    with Image.open(BytesIO(image_data)) as img:
        # 이미지 크기 조절
        img = img.resize((300, 300))

        new_img = remove(img)

        output_buffer = BytesIO()

        new_img.save(output_buffer, format="PNG")
        output_data = output_buffer.getvalue()

    return output_data

A. extract_top_keywords(최다 사용 코드 추출)

import boto3
from collections import Counter
from openai import OpenAI
import requests
from PIL import Image
from io import BytesIO
from rembg import remove

def extract_top_keywords(diary_text):
comprehend_client = boto3.client('comprehend', region_name='ap-northeast-2')
#boto3위에 컴프리핸드,s3등을 올려서 사용가능, region_name은 지역이름인데, 한국은 다 서울..
cleaned_text = preprocess_diary_text(diary_text) 
#텍스트 공백 지워서 리턴
response = comprehend_client.detect_key_phrases(
Text=cleaned_text,
LanguageCode='ko'
)
#detect_key_phrases안에 텍스트와, 사용 언어 형식 지켜서 입력

 

라이브러리

import boto3:

boto3는 AWS (Amazon Web Services)를 Python에서 사용하기 위한 공식 SDK입니다. 이 모듈을 사용하여 AWS 서비스와 상호작용할 수 있고, boto3 위에 comprehend , s3등을 올려서 사용가능 합니다.

from collections import Counter:

Counter는 Python의 내장 모듈인 collections에서 제공되는 클래스입니다. 이 클래스는 반복 가능한 객체의 요소들의 개수를 세어 딕셔너리로 반환합니다.

from openai import OpenAI:

코드에서는 openai 라이브러리에서 OpenAI 클래스를 가져오고 있습니다. 하지만 일반적으로 OpenAI GPT 모델과 상호작용할 때는 openai 라이브러리를 사용하는 것이 아니라, OpenAI의 GPT 모델 API를 직접 호출하는 방식을 사용합니다.

 

import requests:

requests 모듈은 HTTP 요청을 보내고 응답을 받는 데 사용되는 모듈입니다. 코드에서는  외부 서버에서 이미지를 가져오거나 기타 데이터를 요청하는 데 사용합니다.

 


from PIL import Image:


PIL은 Python Imaging Library의 약자로, 이미지 처리와 관련된 기능을 제공하는 라이브러리입니다. 코드에서는 이미지를 다룰 때 사용될 수 있습니다.

 

 

from io import BytesIO:

io 모듈에서 BytesIO 클래스를 가져와 사용합니다. BytesIO는 바이트 데이터를 파일과 같이 다룰 수 있도록 하는 클래스로, 이미지나 다른 이진 데이터를 다룰 때 유용합니다.


from rembg import remove:

rembg 모듈에서 remove 함수를 가져오고 있습니다. 이 함수는 이미지에서 배경을 제거하는 기능을 제공하는 모듈로, 이미지 처리 및 투명 배경을 생성할 때 사용될 수 있습니다. 글을쓰는 기준에서 3.1 버전 까지만 지원함으로 다운그래이드..

 

keywords = [phrase['Text'] for phrase in response['KeyPhrases']]
#response에서 keyphrases부분을 가지고와서 phrase에 넣고 Text반환
stopwords = get_korean_stopwords() 
#불용어 리턴
filtered_keywords = [keyword for keyword in keywords if keyword not in stopwords]
keyword_counts = Counter(filtered_keywords)
#불용어를 제외한 문장중에서 가장 많이 쓰인 문장을 카운드.
top_keywords = keyword_counts.most_common(2)
#가장 많이 쓰인 문장 2개 까지 추출.
return [keyword[0] for keyword in top_keywords]

 

keywords = [phrase['Text'] for phrase in response['KeyPhrases']]

response=comprehend.client.detect_key_phrase('') 이부분이 실행되고나서 response의 구조는 아래와 같다

 

//detect_key_phrases의 반환구조.

{
    'LanguageCode': 'ko',
    'KeyPhrases': [
        {'Text': '키워드1', 'Score': 0.95},
        {'Text': '키워드2', 'Score': 0.80},
        # ...
    ],
    'ResponseMetadata': {
        # ...
    }
}

keyphrases를 response에 저장하고, keyphrases에 text부분을 phase에 저장함.

keyword_counts = Counter(filtered_keywords)

Counter메서드의 반환 형식은 딕션어리 형식이다.

-> Counter({'사과': 3, '딸기': 2, '바나나': 1})

 


B. generate_sticker_image(빈도수가 높은 단어를 이용하여 스티커 생성)

def generate_sticker_image(keyword):
    client = OpenAI(api_key="인증키")
    #openai 객체 생성,

    response = client.images.generate(
        model="dall-e-3",
        prompt=f"{keyword} 스티커",
        size="1024x1024",
        quality="standard",
        n=1,  
        # 이미지(스티커) 하나만 생성한다는 소리, n을 늘린다고 한번에 많은 양을 처리하는게 아니다.
    )
    #모델은 달리3를 쓴다는 이야기이고, prompt는 스티커 사진을 받으려고 하는거니까 뒤에 "스티커"라고 붙힘

    image_url = response.data[0].url
    #생성된 사진(스티커)들에서 첫번째 사진의 url을 가지고 온다는 말. data[1]은 당연히 두번째 사진이겠지?
    #필요에 따라 로직 수정
    
    return image_url

C. remove_background(뒷배경 삭제, rembg사용)

def remove_background(image_data):  # 이미지
    with Image.open(BytesIO(image_data)) as img:
        img = img.resize((300, 300))
		# 이미지 크기 조절
        new_img = remove(img)
		#배경삭제
        output_buffer = BytesIO()
        #사진을 위에서 바이트io로 읽어 왔듯이 배경이 제거 된 이미지를 저장하기 위한 새로운 바이트io
        new_img.save(output_buffer, format="PNG")
        #배경이 제거 된 이미지를 output_buffer에 png형식으로 저장한다는 소리
        output_data = output_buffer.getvalue()
		#버퍼 데이터를 가지고옴.
    return output_data

with Image.open(BytesIO(image_data)) as img:

->바이트io를 이용해서 사진을 메모리에서 열고 img라는 변수에 할당해줌.

 

with, as 

->with 문은 Python에서 파일이나 리소스를 사용한 후 자동으로 정리(clean-up)하기 위한 구문입니다. with 문을 사용하면 파일이나 리소스를 올바르게 사용한 후 자동으로 닫거나 정리할 수 있습니다. as는 with 문과 함께 사용되어 해당 리소스를 변수에 할당합니다. 이렇게 함으로써 코드 블록 내에서 해당 리소스에 접근할 수 있게 됩니다.

Image.open(image_data)

->Image.open(image_data)를 사용하여 이미지를 열 때, 일반적으로 파일 경로나 파일 객체를 받아들이는 것이 기본 동작입니다. 그러나 image_data가 파일 경로가 아니라 직접적인 이미지 데이터를 포함하는 경우, BytesIO를 사용하여 바이트 스트림으로 변환해주어야 합니다. 만약 BytesIO를 사용하지 않고 Image.open(image_data)를 사용한다면, 이미지 데이터를 직접 파일 경로로 인식하려고 시도할 것입니다. 이 때 이미지 데이터를 파일 경로로 간주하면서 파일을 찾지 못해 에러가 발생할 것입니다.

Image.open(BytesIO(image_data))

->Image.open(BytesIO(image_data))은 PIL(Python Imaging Library)의 Image.open 함수를 사용하여 이미지를 메모리에서 열고, BytesIO(image_data)를 통해 이미지 데이터를 바이트 스트림으로 읽습니다.

 


D. 나머지 코드

def preprocess_diary_text(diary_text):
    cleaned_text = ''.join(char for char in diary_text if char.isalnum() or char.isspace())
    return cleaned_text


def get_korean_stopwords():
    stopwords = [
        "나", "오늘", "우리", "저희", "따라", "의해", "을", "를", "에", "의", "가", "으로", "로", "에게", "뿐이야",
        "여서", "그리고"
    ]
    return stopwords