バーチャル試着、FASHN AI + nano banana pro が最強説
はじめに
どうも!
株式会社エクスプラザのhyodoです!
弊社アドベントカレンダー22日目の投稿となります!
AIバーチャル試着、どれも微妙じゃないです?
ECサイトで見つけた服、「自分が着たらどんな感じだろう」と思って、AIを利用して着せ替えを試したことがある人は多いと思います。
例えば、下記のように試着させようとして、画像生成AIに実行させると、、、
だいたいこうなります。
- 切り貼りしたみたいに合成感が出る
- 対象以外の服が着せられてる
- 顔が別人
- 服の質感が元画像と違う
などなど…
これを、FASHN AIとnano banana proを組み合わせる方法で解消できたので、紹介させていただければと思います。
ざっくり手順をお伝えすると、
Step 1: FASHN AI → シームレスに服を着せる
Step 2: Gemini → 元の服の質感を転写する
です。
この手順で先ほどの人物と服を合成させると、
このように自然に試着したようになります。
1つのAIだけだと難しい
一般的な画像生成AI
人物画像と服の画像を渡して「この人にこの服を着せて」と指示すると、全然違う人が全然違う服を着ている画像が出てきます。顔が変わる、体型が変わる、服のデザインが勝手にアレンジされる。といった事象が発生します。
Virtual Try-On専用のAI
FASHN AIのようなVirtual Try-On専用AIは、合成感がなくて自然に仕上がります。顔も体型もちゃんと保持されます。
ただ、元の服の「生地感」が少し失われます。光沢やシワの細かさが物足りません。写真としては綺麗ですが、元の服を見比べると「なんか違う」という感じがします。
2段階アプローチ
そこで考えたのが2段階アプローチです。
- まずFASHNで合成感のない着せ替えをする
- その結果に対して、Geminiで元の服の質感を転写する
これで自然な合成とリアルな質感の両方が手に入ります。
実装
必要なもの
- FASHN AI APIキー(fashn.aiで取得)
- Gemini APIキー(Google AI Studioで取得、無料枠あり)
- Python 3.9以上
pip install pillow requests google-generativeai
Step 1: FASHN AIで着せ替え
import base64
import time
from io import BytesIO
from PIL import Image
import requests
class FashnTryOn:
def __init__(self, api_key: str):
self.api_key = api_key
self.base_url = "https://api.fashn.ai/v1"
def try_on(self, person_image: Image.Image, garment_image: Image.Image) -> Image.Image:
person_b64 = self._to_base64(person_image)
garment_b64 = self._to_base64(garment_image)
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {self.api_key}",
}
payload = {
"model_name": "tryon-v1.6",
"inputs": {
"model_image": person_b64,
"garment_image": garment_b64,
"category": "auto",
"mode": "quality",
"segmentation_free": True,
"num_samples": 1,
"output_format": "png",
},
}
resp = requests.post(f"{self.base_url}/run", json=payload, headers=headers)
job_id = resp.json()["id"]
while True:
status = requests.get(
f"{self.base_url}/status/{job_id}",
headers={"Authorization": f"Bearer {self.api_key}"}
).json()
if status["status"] == "completed":
img_url = status["output"][0]
img_data = requests.get(img_url).content
return Image.open(BytesIO(img_data))
if status["status"] == "failed":
raise Exception("FASHN処理失敗")
time.sleep(3)
def _to_base64(self, image: Image.Image) -> str:
if image.mode == 'RGBA':
bg = Image.new('RGB', image.size, (255, 255, 255))
bg.paste(image, mask=image.split()[3])
image = bg
buffer = BytesIO()
image.save(buffer, format='PNG')
b64 = base64.b64encode(buffer.getvalue()).decode()
return f"data:image/png;base64,{b64}"
FASHNのポイントはmode: "quality"です。これで最高品質のモードになります(処理時間は約19秒)。顔と体型が完全に保持されて、合成感もほとんどありません。
Step 2: Geminiで質感強化
FASHNの結果に対して、元の服の質感を転写します。
import google.generativeai as genai
from io import BytesIO
from PIL import Image
class TextureEnhancer:
def __init__(self, api_key: str):
genai.configure(api_key=api_key)
def enhance(self, tryon_result: Image.Image, original_garment: Image.Image) -> Image.Image:
model = genai.GenerativeModel("gemini-3-pro-image-preview")
tryon_result = self._resize(tryon_result, 1024)
original_garment = self._resize(original_garment, 1024)
prompt = """
IMAGE 1: 試着済みの画像(人物が服を着ている状態)
IMAGE 2: 元の服の画像
IMAGE 1の服の質感を、IMAGE 2に合わせて強化してください。
変えてはいけないもの:
- 人物の顔、体型、ポーズ
- 背景
- 服のシルエット
強化するもの:
- 生地のテクスチャ(織り目、糸の質感)
- 光沢感またはマット感
- シワや陰影のリアルさ
"""
response = model.generate_content([
tryon_result.convert('RGB'),
original_garment.convert('RGB'),
prompt
])
for candidate in response.candidates:
for part in candidate.content.parts:
if hasattr(part, 'inline_data') and part.inline_data:
return Image.open(BytesIO(part.inline_data.data))
return tryon_result
def _resize(self, image: Image.Image, max_size: int) -> Image.Image:
if max(image.size) > max_size:
ratio = max_size / max(image.size)
new_size = tuple(int(d * ratio) for d in image.size)
return image.resize(new_size, Image.Resampling.LANCZOS)
return image
ここで大事なのは、元の服の画像を「参照」として一緒に渡すことです。Geminiはマルチモーダルなので、2つの画像を見比べて質感を転写してくれます。
プロンプトで「変えてはいけないもの」を明示しておくと、人物や背景を変えずに質感だけを強化してくれます。
2つを組み合わせる
def perfect_tryon(person_path: str, garment_path: str) -> Image.Image:
person = Image.open(person_path)
garment = Image.open(garment_path)
print("Step 1: FASHN AI で着せ替え中...")
fashn = FashnTryOn(api_key="YOUR_FASHN_API_KEY")
tryon_result = fashn.try_on(person, garment)
print("Step 2: Gemini で質感強化中...")
enhancer = TextureEnhancer(api_key="YOUR_GEMINI_API_KEY")
final_result = enhancer.enhance(tryon_result, garment)
return final_result
result = perfect_tryon("person.jpg", "shirt.png")
result.save("result.png")
なぜこの組み合わせがうまくいくのか
FASHNは合成の自然さに特化しています。服を人物に「溶け込ませる」技術が優れていて、切り貼り感が出ません。ただし、その過程で元の服の細かいテクスチャが少し失われます。
一方、Geminiは画像理解と画像生成の両方ができます。2つの画像を渡して「こっちの質感をこっちに適用して」と指示すれば、それをやってくれます。ただし、Gemini単体で着せ替えをさせると合成感が出たり、人物が変わったりします。
つまり、それぞれ得意分野が違います。
- FASHN:合成の自然さ、ID保持
- Gemini:質感の再現、細部の強化
2つを組み合わせることで、弱点を補い合えます。
入力画像のコツ
人物画像は全身が写っていて、正面向きのものが良いです。腕を広げすぎていたり、複雑なポーズだと精度が落ちます。
服の画像は平置き(テーブルに置いた状態)がベストです。白背景でシワがない状態だと認識精度が上がります。モデルが着用している写真でも動きますが、平置きの方が安定します。
処理時間とコスト
処理時間はFASHNのqualityモードで約20秒、Geminiの質感強化で約5〜10秒です。合計で約30秒弱かかります。
FASHNは従量課金、Geminiは無料枠があります。個人で試す分にはGeminiの無料枠で十分足ります。
まとめ
- FASHNで合成感のない着せ替えをする
- Geminiで元の服の質感を転写する
- 2段階でやることで、自然さと質感の両方を実現できる
「AIっぽい」着せ替え結果に不満があった方は、ぜひこの方法を試してみてください。
参考リンク
「プロダクトの力で、豊かな暮らしをつくる」をミッションに、法人向けに生成AIのPoC、コンサルティング〜開発を支援する事業を展開しております。 エンジニア募集しています。カジュアル面談応募はこちらから: herp.careers/careers/companies/explaza
Discussion