こんにちは、パレイド思想部です。
前回はレイヤー分解の仕組みを解説しました。
今回は、生成したスプライト群の後処理(背景除去・エッジ処理・アップスケール)と、APNG / WebP サムネイルの自動生成です。
本記事はローカル LLM による自動執筆パイプラインで生成されました。現段階ではクラウド AI(Claude 等)の補助や人間の編集が介在していますが、pareido.jp では最終的に AI が自律的にコンテンツを制作できる仕組みの構築を目指しています。
生成した素材を統合する
画像生成 AI の出力は「素材」であって「完成品」ではありません。ComfyUI から出てくる画像は背景付きの RGB 画像で、そのままアバターとして使うことはできません。背景の透明化、輪郭のギザギザ補正、解像度の拡大、サムネイルの生成——これらの「仕上げ」工程は、画像生成そのものとは別の技術セットを要求します。
rembg、OpenCV、RealESRGAN、Pillow——後処理に必要なツールを自分で組み合わせるのは、アバターを作りたいだけのユーザーにとってはハードルが高すぎます。パイプラインのコードは、これらの後処理を一括で適用し、品質チェックまで自動で行います。
スプライトの全体構成
Phase 1〜3 で生成されるスプライトの全量を整理します。
| Phase | 内容 | 枚数 |
|---|---|---|
| Phase 1 | ベース(背景除去済み) | 1 |
| Phase 2 | 6感情 × 口閉じ | 6 |
| Phase 3a | 6感情 × 口開き | 6 |
| Phase 3b | 6感情 × 瞬き | 6 |
| Phase 3c | 6感情 × 5ビゼム | 30 |
| 合計 | 49 |
ビゼムはオプションなので、最小構成なら19枚(ベース + 6感情 × 3状態)です。
背景除去(rembg)
ComfyUI で生成した画像は RGB(背景あり)です。アバターとして使うには背景を透明にする必要があります。
rembg は U2-Net ベースの背景除去ライブラリです。人物のシルエットを検出し、背景をアルファチャンネルで透明化します。
from rembg import remove
# RGBA 画像として出力(背景透明)
rgba_image = remove(rgb_image)
rembg の精度はスタイルによって差があります。
| スタイル | 精度 | 注意点 |
|---|---|---|
| realistic | 高 | ほぼ完璧 |
| illustration | 中〜高 | 服と背景の色が近いと誤判定 |
| anime | 中 | 髪の細い毛先がカットされやすい |
精度が低い場合は、ComfyUI 側でシンプルな単色背景(白 or 緑)を指定し、rembg の仕事を減らす工夫が有効です。
エッジフェザリング
背景除去後のスプライトは、輪郭がギザギザ(エイリアシング)になることがあります。これを軽減するため、アルファチャンネルの境界に1ピクセルのガウシアンブラーをかけます。
alpha = rgba_image[:, :, 3]
alpha_feathered = cv2.GaussianBlur(alpha, (3, 3), 0.5)
rgba_image[:, :, 3] = alpha_feathered
微細な処理ですが、最終的な見た目の滑らかさに大きく影響します。
インペイント結果のステッチ
Phase 3 のインペイントでは、マスク領域だけが再生成されます。この結果を元画像に「貼り戻す」処理がステッチです。
# フェザードマスクをブレンド重みとして使用
blend_weight = mask_feathered / 255.0
result = original * (1 - blend_weight) + inpainted * blend_weight
フェザリング済みマスクを重みにすることで、マスク中心はインペイント結果、境界は元画像とのブレンド、マスク外は完全に元画像という滑らかな遷移が実現します。
色の一貫性チェック
インペイント後のステッチで、マスク境界に色ずれが生じることがあります。特に肌の色味が変わると目立ちます。
# マスク境界帯(幅10px)の色差を計測
border_original = extract_border_pixels(original, mask, width=10)
border_result = extract_border_pixels(result, mask, width=10)
color_diff = np.mean(np.abs(border_original - border_result))
if color_diff > threshold:
# リトライ(seed変更)
...
閾値を超えた場合は seed を変えてリトライします。
アップスケール(RealESRGAN)
生成サイズ(1024px)のままだと、高解像度ディスプレイでは粗さが目立ちます。RealESRGAN で2048〜4096px にアップスケールします。
from realesrgan import RealESRGANer
upscaler = RealESRGANer(scale=2, model_path="RealESRGAN_x2plus.pth")
upscaled = upscaler.enhance(image)
| 方式 | 速度 | 品質 | VRAM |
|---|---|---|---|
| Lanczos(CPU) | 速い | 中 | なし |
| RealESRGAN | 普通 | 高 | 1-2GB |
| ComfyUI upscaler | 遅い | 最高 | 4-8GB |
アバター用途では RealESRGAN が品質と速度のバランスが最も良好でした。
APNG サムネイル生成
全6感情をフレームとしたアニメーション PNG(APNG)を生成します。ポートフォリオやファイルブラウザでのプレビュー用です。
from PIL import Image
frames = []
for emotion in ["neutral", "happy", "sad", "angry", "relaxed", "surprised"]:
sprite = Image.open(f"{emotion}_closed.png")
sprite = sprite.resize((256, 256))
frames.append(sprite)
frames[0].save(
"preview_anim.png",
save_all=True,
append_images=frames[1:],
duration=400, # 各フレーム 400ms
loop=0,
)
各感情を400ms ずつ表示し、ループ再生します。
下記は実際に生成した例ですが、正直なところ、原寸だと自動生成の限界が目立ちます。
マスク処理が不完全でゴミが残り、閉じた目の画像が不自然。現在の手法では、手作業なしではこれぐらいのレベルです。

連載のまとめ
全7回にわたり、アバター自動生成パイプラインの全体像を解説しました。
- 1. 環境構築 — AIによるアバター生成の問題と、StabilityMatrix + ComfyUI による解消
- 2. モデル選定 — CivitAI + StabilityMatrix でNSFW・ライセンスの地雷を避けつつ比較評価
- 3. ガチャ — パイプラインによるガチャ疲れの解消(自動スコアリング)
- 4. 表情差分 — 18枚の差分生成をパイプラインが全自動処理
- 5. マスク生成 — 精密なマスクをコードが自動計算(手描き不要)
- 6. レイヤー分解 — 画像データを「動かせるデータ」に自動変換
- 7. 後処理+パッケージング — 49枚の仕上げから配布形式まで一括処理
この連載の出発点は、「アバターが欲しい」というシンプルな欲求に対して、画像生成 AI の手段が複雑すぎるという問題でした。ツールの選択、モデルの選定、NSFW やライセンスの精査、プロンプトの試行錯誤、マスクの手描き、レイヤーの手動分解——これらすべてを一人でこなすのは現実的ではありません。
パイプラインは、用途を絞り、判断基準を定量化し、手作業をコードで置き換えることで、この複雑さを解消します。ユーザーがやることは、キャラクターの説明を書いてパイプラインを実行することだけです。
本質的な残課題として、顔が別人のように変わったり閉じた目のパターンに対する「生成AIの不安定さ」と、髪型の処理など細部の「マスク処理の品質」が浮き彫りになりました。
今回の連載は一旦ここで終了しますが、この2つは今後も追試をしたいと思います。
最後までご覧いただきありがとうございました。



