Amazon Web Services 한국 블로그

Amazon Nova Canvas 업데이트: 가상 시착 및 스타일 옵션 정식 출시

새 옷을 사기 전에 내가 입으면 어떻게 보일지 빠르게 시각화할 수 있으면 좋겠다고 생각한 적이 있나요? 아니면 새 가구가 거실에 어울릴지 알고 싶지 않으신가요? 이런 생각을 가능케 하는 Amazon Nova Canvas의 새로운 가상 시착 기능을 오늘 소개하게 되어 매우 기쁩니다. 여기에 더해 텍스트-이미지 기반 스타일 프롬프팅의 스타일 일관성을 개선하기 위해 새로 8가지 스타일 옵션이 추가됩니다. 이러한 기능은 Nova Canvas AI 기반 이미지 생성 기능을 확장하여, 고객 경험을 향상시킬 수 있는 사실적인 제품 시각화와 스타일화된 이미지 생성을 한층 더 쉽게 만듭니다.

이 기능들을 사용하는 방법을 간단히 살펴보겠습니다.

시작하기
먼저, 일반적인 방법을 통해 Nova Canvas 모델에 액세스할 수 있어야 합니다. Amazon Bedrock 콘솔로 이동하여 Model access(모델 액세스)를 선택한 다음 계정의 Amazon Nova Canvas를 활성화하고 워크로드에 적합한 리전을 선택하세요. 이미 액세스 권한이 있고 Nova Canvas를 사용해 왔다면 새 기능이 자동으로 제공되므로 즉시 기능을 사용할 수 있습니다.

가상 시착
첫 번째 흥미로운 새 기능은 가상 시착입니다. 이 기능을 사용하면 업로드한 사진 2장을 합쳐 달라고 Amazon Nova Canvas에 요청하여 사실적인 결과를 얻을 수 있습니다. 옷을 비롯하여 의류, 액세서리, 가구, 기타 제품의 사진도 가능합니다. 예를 들어 사람의 사진을 소스 이미지로 제공하고 의복 사진을 참조 이미지로 제공하면 Amazon Nova Canvas가 이 의복을 입고 있는 같은 사람의 새 이미지를 생성합니다. 한번 해 봅시다!

이미지 2개를 선택하는 것으로 시작합니다. 옷이 바뀐 효과를 잘 볼 수 있는 포즈를 취한 제 사진 1장과 AWS 브랜드 후드티 사진 1장을 골랐습니다.

Matheus와 AWS 브랜드 후드티

참고로 Nova Canvas는 2,048 x 2,048 해상도에 상당하는 최대 410만 픽셀의 이미지까지 허용하므로 필요한 경우 이러한 제약 조건에 맞게 이미지 크기를 조정해야 합니다. 또한 이 문서에 나오는 Python 코드를 실행하려면 Python 3.9 이상과 Python 패키지 boto3 및 Pillow가 설치되어 있어야 합니다.

제 사진에 후드티를 적용하기 위해 Amazon Bedrock Runtime 간접 호출 API를 사용합니다. 이 API의 요청 및 응답 구조에 대한 전체 세부 정보는 Amazon Nova 사용 설명서에서 찾을 수 있습니다. 추론 파라미터 몇 개만 있으면 되는 간단한 코드입니다. “VIRTUAL_TRY_ON”이라는 새로운 taskType을 사용하겠습니다. 그런 다음 virtualTryOnParams 객체를 사용하여 몇 가지 필수 파라미터를 설정하면 소스 이미지와 참조 이미지를 포함하여 원하는 설정을 지정할 수 있습니다. 2개 이미지 모두 Base64 문자열로 변환해야 합니다.

import base64


def load_image_as_base64(image_path): 
   """Helper function for preparing image data."""
   with open(image_path, "rb") as image_file:
      return base64.b64encode(image_file.read()).decode("utf-8")


inference_params = {
   "taskType": "VIRTUAL_TRY_ON",
   "virtualTryOnParams": {
      "sourceImage": load_image_as_base64("person.png"),
      "referenceImage": load_image_as_base64("aws-hoodie.jpg"),
      "maskType": "GARMENT",
      "garmentBasedMask": {"garmentClass": "UPPER_BODY"}
   }
}

Nova Canvas는 마스킹을 사용하여 이미지를 조작합니다. 이는 AI 이미지를 생성할 때 특정 부분이나 영역에 초점을 맞추고 다른 부분이나 영역은 보존할 수 있는 기법으로서, 페인트칠할 때 칠하지 않을 부분을 마스킹 테이프로 보호하는 것과 비슷합니다.

maskType을 올바른 값으로 설정하면 사용 가능한 3가지 마스킹 모드 중에서 선택할 수 있습니다. 여기에서는 “GARMENT”를 사용하고 있는데, 마스킹할 신체 부분을 지정해야 합니다. 저는 “UPPER_BODY”를 사용하고 있지만, “LOWER_BODY”“FULL_BODY” 등 다른 부분도 사용할 수 있고, 특별히 발을 대상으로 지정하고 싶다면 “FOOTWEAR””를 사용하면 됩니다. 전체 옵션 목록은 설명서를 참조하세요.

그런 다음 간접 호출 API를 직접적으로 호출하여 이 추론 인수를 전달하고 생성된 이미지를 디스크에 저장합니다.

# 참고: 위의 inference_params 변수는 아래에서 참조됩니다.

import base64
import io
import json

import boto3
from PIL import Image

# Bedrock 런타임 클라이언트를 생성합니다.
bedrock = boto3.client(service_name="bedrock-runtime", region_name="us-east-1")

# 간접 호출 페이로드를 준비합니다.
body_json = json.dumps(inference_params, indent=2)

# Nova Canvas를 간접적으로 호출합니다.
response = bedrock.invoke_model(
   body=body_json,
   modelId="amazon.nova-canvas-v1:0",
   accept="application/json",
   contentType="application/json"
)

# 응답에서 이미지를 추출합니다.
response_body_json = json.loads(response.get("body").read())
images = response_body_json.get("images", [])

# 오류가 있는지 확인합니다.
if response_body_json.get("error"):
   print(response_body_json.get("error"))

# 각 이미지를 Base64에서 디코딩하고 PNG 파일로 저장합니다.
for index, image_base64 in enumerate(images):
   image_bytes = base64.b64decode(image_base64)
   image_buffer = io.BytesIO(image_bytes)
   image = Image.open(image_buffer)
   image.save(f"image_{index}.png")

매우 흥미로운 결과가 나왔습니다!

AWS 브랜드 후드티를 입은 Matheus

자랑스럽게 AWS 브랜드 후드티를 입고 있는 제 이미지가 간단히 생성됐습니다!

“GARMENT” 마스크 유형 외에 “PROMPT” 마스크나 “IMAGE” 마스크도 사용할 수 있습니다. “PROMPT”를 사용할 때는 소스 이미지와 참조 이미지도 제공하지만, 소스 이미지에서 바꿀 부분을 지정하려면 자연어 프롬프트를 제공해야 합니다. 이는 Nova Canvas에서 “INPAINTING” 태스크 “OUTPAINTING” 태스크가 작동하는 방식과 유사합니다. 자체 이미지 마스크를 사용하려면 “IMAGE” 마스크 유형을 선택하고 마스크로 사용할 흑백 이미지를 제공하세요. 검은색은 소스 이미지에서 바꿀 픽셀을, 흰색은 보존할 픽셀을 나타냅니다.

이 기능은 소매업체에 특히 유용합니다. 소매업체는 이 기능을 사용하여 고객이 구매 전에 제품이 어떻게 보일지 확인하여 더 나은 구매 결정을 내리도록 도울 수 있습니다.

스타일 옵션 사용
저는 애니메이션의 슈퍼히어로가 된 제 모습이 항상 궁금했습니다. 이전에는 Nova Canvas를 사용하여 제 이미지를 조작할 수 있었지만, 제대로 만들려면 저의 뛰어난 프롬프트 엔지니어링 기술에 의존해야 했습니다. 이제 Nova Canvas와 함께 제공되는 사전 훈련된 스타일을 이미지에 적용하면 선택한 예술적 스타일에 맞는 고품질 결과를 얻을 수 있습니다. 3D 애니메이션 가족 영화, 디자인 스케치, 평면 벡터 일러스트레이션, 그래픽 노블, 맥시멀리즘, 미드센추리 레트로, 포토리얼리즘, 소프트 디지털 페인팅 등 8가지 스타일을 사용할 수 있습니다.

추가 파라미터를 Nova Canvas API에 전달하기만 하면 간단하게 스타일을 적용할 수 있습니다. 예제를 살펴보겠습니다.

3D 애니메이션 가족 영화 스타일을 사용하여 AWS 슈퍼히어로 이미지를 생성하고 싶습니다. 이를 위해 taskType“TEXT_IMAGE”로 지정하고 textstyle이라는 2개의 파라미터가 포함된 textToImageParams 객체를 지정합니다. text 파라미터에는 생성하려는 이미지를 설명하는 프롬프트가 포함되어 있습니다. 이 경우에는 “a superhero in a yellow outfit with a big AWS logo and a cape(큰 AWS 로고가 박힌 노란색 의상과 망토를 입은 슈퍼히어로)”입니다. style 파라미터는 미리 정의된 스타일 값 중 하나를 지정합니다. 여기에서는 “3D_ANIMATED_FAMILY_FILM”을 사용하고 있지만, Nova Canvas 사용 설명서에서 전체 목록을 볼 수 있습니다.

inference_params = {
   "taskType": "TEXT_IMAGE",
   "textToImageParams": {
      "text": "a superhero in a yellow outfit with a big AWS logo and a cape.",
      "style": "3D_ANIMATED_FAMILY_FILM",
   },
   "imageGenerationConfig": {
      "width": 1280,
      "height": 720,
      "seed": 321
   }
}

그런 다음 이전 예제에서처럼 간접 호출 API를 직접적으로 호출합니다. (여기에서는 간단히 하기 위해 코드를 생략했습니다.) 결과는 어떨까요? 판단은 여러분의 몫이더라도, 저는 제가 상상했던 대로 3D 애니메이션 가족 영화 스타일에 따라 제가 가장 좋아하는 색상의 옷을 입은 AWS 슈퍼히어로가 구현되어 아주 만족스럽습니다.

정말 멋진 점은 코드와 프롬프트를 똑같이 유지하면서 스타일 속성 값만 변경하여 완전히 다른 스타일의 이미지를 생성할 수 있다는 것입니다. 한번 해 보겠습니다. stylePHOTOREALISM으로 설정합니다.

inference_params = { 
   "taskType": "TEXT_IMAGE", 
   "textToImageParams": { 
      "text": "a superhero in a yellow outfit with a big AWS logo and a cape.",
      "style": "PHOTOREALISM",
   },
   "imageGenerationConfig": {
      "width": 1280,
      "height": 720,
      "seed": 7
   }
}

결과는 인상적입니다! 이전에 생성한 만화와는 아주 다르게 제 설명에 딱 맞는 실사를 방불케 하는 슈퍼히어로입니다. 코드 한 줄만 바꿨는데 말이죠.

알아야 할 사항
가용성 – Amazon Nova Canvas의 가상 시착 및 스타일 옵션은 미국 동부(버지니아 북부), 아시아 태평양(도쿄), 유럽(아일랜드) 리전에서 사용할 수 있습니다. Amazon Nova Canvas의 현재 사용자는 새 모델로 마이그레이션하지 않고도 이 기능을 즉시 사용할 수 있습니다.

요금 – 자세한 요금 정보는 Amazon Bedrock 요금 페이지를 참조하세요.

의상 가상 시착을 미리 보려면 nova.amazon.com에서 사람과 의상의 이미지를 업로드하여 다양한 의류 조합을 시각화할 수 있습니다.

시작할 준비가 되었다면 Nova Canvas 사용 설명서를 확인하거나 AWS Console을 방문하세요.

Matheus Guimaraes | @codingmatheus