JustDoEat
AWS comprehend, rembg, openai(달리-3)을 이용한 사진생성 본문
전체소스 코드
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