猫の手ツール

Algorithm & UI/UX

服のシワを殺さない「輝度保存」ブレンドの極意

単なる「色の塗りつぶし」では、服の質感は失われてしまいます。本ツールでは、AIによる高精度な領域抽出と、ピクセル単位の輝度演算を組み合わせることで、実写のような自然なカラーチェンジを実現しました。

1. テクスチャを維持する「輝度抽出(Luminance)ブレンド」

服の色を変更する際、最も大きな課題は「影やシワをいかに残すか」です。単純に特定の色を重ねる(Overlay)だけでは、立体感が消えてベタ塗りのような不自然な仕上がりになります。

このツールでは、まず元の画像の各ピクセルから輝度(Luminance)を計算します。輝度とは、その点の「明るさの度合い」です。この値を抽出した上で、新しく指定されたカラーと乗算合成を行うことで、元の服が持っていた光の当たり具合をそのまま新しい色に投影しています。

// ピクセルごとの輝度計算とブレンド処理の核心
function applyColorEffect(pixelData, maskValue, targetColor, intensity) {
    // 独自のチューニング値を用いた輝度算出
    const luminance = (pixelData.r * 0.299) + (pixelData.g * 0.587) + (pixelData.b * 0.114);

    // ここにターゲット色との乗算とブレンドの計算処理が入ります
    // 1. 輝度に基づいて新しい色を生成
    // 2. スライダーの強度(intensity)に合わせて元画像と線形補間
    const finalR = // 計算されたR値
    const finalG = // 計算されたG値
    const finalB = // 計算されたB値

    return { r: finalR, g: finalG, b: finalB };
}

2. MediaPipe Wasmによるマルチクラス・セグメンテーション

「服だけ」を自動で選ぶためには、画像の中から衣服の領域を特定するAI(セグメンテーション)が必要です。本ツールでは、MediaPipeのSelfie Multiclassモデルを採用しています。

この実装のポイントは、サーバーを介さないブラウザ完結型であることです。WebAssembly(Wasm)を活用することで、1枚の画像をピクセル単位で解析し、「背景」「肌」「髪」「衣類」といったカテゴリに分類したマスク配列を高速に生成します。このマスク情報をCanvasのImageData操作に直接結びつけることで、低遅延なプレビューを可能にしています。

// AIエンジンの初期化とマスク取得(抽象化)
async function runSegmentation(imageSource) {
    const segmenter = await ImageSegmenter.createFromOptions(vision, {
        baseOptions: { 
            modelAssetPath: "internal_assets/ai_model.tflite",
            delegate: "GPU" 
        },
        runningMode: "IMAGE"
    });

    const results = segmenter.segment(imageSource);
    // カテゴリID「4(衣類)」に該当するピクセルのみを抽出
    return results.categoryMask.getAsUint8Array();
}

3. requestAnimationFrameによるレンダリングの最適化

カラーピッカーやスライダーを動かした際、Canvasの全ピクセル(数百万個)をループ処理して再描画すると、ブラウザのメインスレッドを占有し、UIがカクつく原因になります。

これを防ぐため、本ツールでは requestAnimationFrame を用いた間引き描画(Throttling)を実装しています。変更イベントが連続して発生しても、ブラウザの描画更新タイミング(通常60fps)に合わせて1回だけ描画処理を実行することで、スムーズな操作感と計算資源の節約を両立させています。

Developer's Note

最も苦労したのは、黒い服や白い服への対応です。黒い服はもともとの輝度が低いため、単に色を乗算するだけでは真っ黒なままになり、逆に白い服は色が飛びすぎてしまいます。

そのため、内部的には「カラーブレンドの強度」を調整する独自の係数を導入し、ユーザーが直感的に「染まり具合」をコントロールできるようにしました。また、プライバシーを最優先に考え、すべてのライブラリ(MediaPipe等)を自社サーバーのディレクトリ内に配置し、外部のCDNやAPIへ一切リクエストを送らない設計にこだわっています。