🔥알림🔥
① 테디노트 유튜브 - 구경하러 가기!
② LangChain 한국어 튜토리얼 바로가기 👀
③ 랭체인 노트 무료 전자책(wikidocs) 바로가기 🙌

4 분 소요

이번 튜토리얼은 OpenAI 의 DALL·E 의 Python API 사용법을 다룹니다. 이번 튜토리얼을 통하여 이미지 생성, 수정, 다양화 하는 방법에 대해 알아보겠습니다.

튜토리얼 진행시 참고사항

🌱 DALL·E 에 대해

2023년 9월, OpenAI는 달리3(DALL·E 3)를 출시했습니다. 이 AI는 기존 인공지능 모델들과 비교할 때 프롬프트를 이해하는 능력이 월등히 뛰어나며, 텍스트를 바탕으로 이미지를 창조하는 기능을 가진 세계적으로 몇 안 되는 모델 중 하나입니다.

2023년 10월, 달리3는 챗GPT Plus(유료 버전)에 통합되어 챗GPT 대화창을 통해 사용할 수 있으며, Microsoft Copilot 및 Bing Image Creator(무료)에서도 이용 가능합니다. 이러한 플랫폼들은 사용자가 제공하는 텍스트 프롬프트를 기반으로 상세하고 독창적인 이미지를 생성할 수 있는 능력을 제공합니다.

특히 주목할 점은 달리3가 영어뿐만 아니라 여러 다른 언어를 이해 할 수 있다는 것입니다. 한국어로 작성된 프롬프트(명령어) 또한 높은 수준으로 잘 이해하며 처리합니다. 이는 영어에 부담을 느껴 AI 그림에 관심은 있지만 실제로 이미지를 생성해보지 못했던 잠재적 사용자들에게 AI 그림 생성 분야로의 접근 장벽을 크게 낮춰주는 요소로 작용할 것입니다

  • 웹사이트: DALL·E

  • 웹사이트에서 이미지를 업로드 하거나, 이미지를 생성하는 기능 구현이 잘 되어 있습니다.

  • in-painting, out-painting 도구도 함께 제공합니다.

이번 튜토리얼에는 OpenAI 의 Python API 를 활용하여 DALL·E 로 이미지를 생성, 수정, 다양화 하는 방법에 대해 알아보겠습니다.

# 토큰 정보로드를 위한 라이브러리
# 설치: pip install python-dotenv
from dotenv import load_dotenv

# 토큰 정보로드
load_dotenv()
True

📍 Client 생성

  • client 는 OpenAI 모듈로 생성된 인스턴스 입니다.

[주의] 아래의 코드에서 오류가 난다면 API 키의 오류일 가능성이 높습니다.

from openai import OpenAI

client = OpenAI()

① 이미지 생성

  • Reference: https://platform.openai.com/docs/guides/images/introduction?context=node

  • model

    • 생성: 사용 가능한 모델은 dall-e-3dall-e-2

    • 편집(edit): dall-e-2

    • 기준 이미지에 대한 다양화(variation): dall-e-2

이미지 크기

  • dall-e-2

    • 256x256, 512x512, 1024x1024
  • dall-e-3
  • 1024x1024, 1792x1024, 1024x1792

기본적으로 이미지는 표준 화질로 생성되지만, DALL·E 3을 사용할 때는 화질을 설정할 수 있습니다. “HD”로 설정하면 디테일이 향상됩니다. 정사각형의 표준 화질 이미지가 가장 빠르게 생성됩니다.


사진요청 개수

DALL·E 3을 사용하면 한 번에 1개의 이미지를 요청 할 수 있고(병렬 요청을 통해 더 많은 이미지를 요청할 수 있음), DALL·E 2를 사용하면 n 매개변수와 함께 한 번에 최대 10개의 이미지를 요청 할 수 있습니다.

  • 참고: https://dallery.gallery/the-dalle-2-prompt-book/
# DALL-E 3 모델을 사용하여 이미지를 생성합니다.
response = client.images.generate(
    model="dall-e-3",
    prompt="A detailed neoclassicism painting depicting the frustration of being put on hold during a phone call(iphone)",
    size="1024x1024",
    quality="standard",
    n=1,
)

# 생성된 이미지의 URL을 저장합니다.
image_url = response.data[0].url

다운로드 받을 수 있는 이미지의 URL을 출력합니다.

# 생성된 이미지의 URL을 출력합니다.
print(image_url)
https://oaidalleapiprodscus.blob.core.windows.net/private/org-EUkMGHsCeNpJHqLp8Qiam46y/user-0HsEDRozYOsvSpNlFt0PVWxB/img-HtAg3dMsr1vk41gU89QEVyv3.png?st=2024-01-08T07%3A13%3A34Z&se=2024-01-08T09%3A13%3A34Z&sp=r&sv=2021-08-06&sr=b&rscd=inline&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2024-01-08T04%3A06%3A11Z&ske=2024-01-09T04%3A06%3A11Z&sks=b&skv=2021-08-06&sig=g%2By4keAm32S8GWrbrUwL4Wx3t/ZKmxsreX0k30tnmoQ%3D

Jupyter Notebook 에서 출력하기 위하여 Image 를 사용합니다.

from IPython.display import Image

# 생성된 이미지를 출력합니다.
Image(url=image_url)

generated_image


urllib 라이브러리를 사용하여 이미지를 다운로드합니다.

import urllib

# 생성된 이미지를 URL로부터 다운로드하여 저장합니다.
urllib.request.urlretrieve(image_url, "generated_image.jpg")
('generated_image.jpg', <http.client.HTTPMessage at 0x12870fcd0>)

✔️ DALL·E 프롬프트 예시

  • ① 예시 프롬프트:

    • a closeup of a female face with headphones in retro colors, synthwave style, 2d digital vector art
  • ② 예시 프롬프트:

    • A detailed neoclassicism painting depicting the frustration of being put on hold during a phone call(iphone)
  • 더 많은 예시는 다음의 링크를 참고해 보세요.

response = client.images.generate(
    model="dall-e-3",
    prompt="A sunlit indoor lounge area with a pool with clear water"
    "and another pool with translucent pastel pink water, next"
    " to a big window, digital art",
    size="1024x1024",
    quality="standard",
    n=1,
)

image_url = response.data[0].url

생성된 이미지를 출력합니다.

print(image_url)
https://oaidalleapiprodscus.blob.core.windows.net/private/org-EUkMGHsCeNpJHqLp8Qiam46y/user-0HsEDRozYOsvSpNlFt0PVWxB/img-zGk344f20iVT4RYOhK8gk95u.png?st=2024-01-08T07%3A25%3A32Z&se=2024-01-08T09%3A25%3A32Z&sp=r&sv=2021-08-06&sr=b&rscd=inline&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2024-01-07T15%3A41%3A00Z&ske=2024-01-08T15%3A41%3A00Z&sks=b&skv=2021-08-06&sig=2%2BHEFg2y2qUhcwptQ6q6I6ayPydAszFGS5Oza/w7CD0%3D
# 생성된 이미지를 출력합니다.
Image(url=image_url)

generated_image2

# 생성된 이미지를 URL로부터 다운로드하여 저장합니다.
urllib.request.urlretrieve(image_url, "generated_image2.jpg")
('generated_image2.jpg', <http.client.HTTPMessage at 0x128919b70>)

② 이미지 수정(Image Edit)

  • 도큐먼트: https://platform.openai.com/docs/api-reference/images/createEdit

주요 파라미터

  • mask:

    • 마스킹 영역은 완전히 투명한 영역(예: 알파가 0인 곳)이 이미지를 편집할 위치를 나타내는 추가 이미지입니다.

    • 4MB 미만의 유효한 PNG 파일이어야 하며 이미지와 크기가 같아야 합니다.

    • 마스킹한 영역에 대하여 다양한 버전의 이미지를 생성합니다.

  • model: 이미지 생성에 사용할 모델입니다. 현재 dall-e-2 만 지원됩니다.

  • n: 생성할 이미지의 개수입니다.

  • size: 256x256, 512x512, or 1024x1024. 기본값은 1024x1024 입니다.

from openai import OpenAI

client = OpenAI()

response = client.images.edit(
    model="dall-e-2",
    image=open("data/sample.png", "rb"),
    mask=open("data/sample-mask.png", "rb"),
    prompt="add a Christmas tree, Sigma 24mm f/8",
    n=1,
    size="1024x1024",
)

image_url = response.data[0].url

이전의 코드에서 작성한 프롬프트는 마치 사진과 같은 Photorealistic 이미지를 생성하기 위하여 카메라 렌즈 정보를 추가해 주었습니다. 이렇게 카메라 렌즈, 화각, 조리개 값등을 넣어 마치 사진으로 촬영한 듯한 이미지를 생성할 수 있습니다.


원본 이미지는 다음과 같습니다.

# 원본 이미지를 출력합니다.
Image(url="data/sample.png")

sample


다음은 마스킹한 이미지입니다. 마스킹은 photopea 에서 쉽게 진행할 수 있습니다.

# 마스킹된 이미지를 출력합니다.
Image(url="data/sample-mask.png")

sample-mask


마지막으로 마스킹된 영역을 크리스마스 트리로 채운 결과 이미지 입니다.

# 생성된 이미지를 URL로부터 다운로드하여 저장합니다.
urllib.request.urlretrieve(image_url, "edited_output.png")

# 생성된 이미지를 출력합니다.
Image(url="edited_output.png")

edited_output

③ 다양한 버전의 이미지 생성(Image Variation)

주어진 이미지의 변형을 생성합니다.

  • 도큐먼트: https://platform.openai.com/docs/api-reference/images/createVariation

주요 파라미터

  • image: 변형의 기준으로 사용할 이미지입니다. 4MB 미만의 유효한 PNG 파일이어야 하며 정사각형 이어야 합니다.

  • model: 이미지 생성에 사용할 모델입니다. 현재 dall-e-2 만 지원됩니다.

  • n: 생성할 이미지의 개수입니다.

  • size: 256x256, 512x512, or 1024x1024. 기본값은 1024x1024 입니다.

number_of_variations = 2
image_size = "512x512"

response = client.images.create_variation(
    image=open("data/generated_image_porche.png", "rb"),  # 기준 이미지
    n=number_of_variations,  # 생성할 이미지의 개수
    size=image_size,  # 생성할 이미지의 크기
)

image_url = response.data[0].url

생성된 이미지를 출력합니다.

import matplotlib.pyplot as plt
from matplotlib.image import imread


fig, ax = plt.subplots(1, number_of_variations,
                       figsize=(8, 8 * number_of_variations))

for i in range(1, number_of_variations + 1):
    filename = f"variated_image_{i}.jpg"
    i -= 1
    urllib.request.urlretrieve(response.data[i].url, filename)
    img = imread(filename)
    ax[i].imshow(img)
    ax[i].axis("off")
    ax[i].set_title(f"Variation {i+1}")

plt.tight_layout()
plt.show()

댓글남기기