猫の手ツール

Algorithm & UI/UX

イラスト資料を加速させる:21点のランドマークから線画を紡ぐアルゴリズム

複雑な「手の形」を、トレース可能な純粋な骨格情報へ。本ツールではAIが検知した3D座標を、クリエイターが最も扱いやすい2Dワイヤーフレームへと変換・再構成しています。その背後にあるCanvas制御とリアルタイム処理の工夫を紐解きます。

このツールの入力から出力まで

現行コードの確認日:

入力
指が見える手の写真を選び、線色・太さ・関節表示を指定します。
処理
HandLandmarkerの21点と接続を使って手のポーズを線画にします。
出力
透明背景はPNG、それ以外はJPEG品質0.95です。

まず確認する点:手の輪郭の全画素をトレースする処理ではありません。指の重なりや画面外の指で、点がどのように結ばれたかを確認します。

仕上がりの例

手の写真から、指と手のひらの位置を線で表した例です。

加工前・加工後
左は5本の指を開いた手の写真。右は手のポーズを線で描き、透明部分を市松模様で示した画像。

サンプルにはAIで生成した架空の人物画像を使用しています。市松模様は透明部分を示す表示用の背景です。ツールで保存する透過PNGには含まれません。

加工前・加工後

左は5本の指を開いた手の写真。右は手のポーズを線で描き、透明部分を市松模様で示した画像。

掲載画像はサイトにある既存の公開作例です。保存済みの資料ではAIで作成した架空の人物・手の画像を使用しています。今回の確認日が、この作例を実行した日を表すわけではありません。

保存済み検証記録の条件を見る

資料の種類は「ツールの出力画像を保存した記録」です。公開作例と保存済み記録で素材や色などが異なる場合があるため、下の数値は保存済み検証記録の条件として読んでください。

記録の入力画像
1254×1254px (JPEG)
記録の出力画像
1254×1254px (PNG)
保存済み記録の主な操作・出力条件
画面の項目記録の値現行コードの初期値・範囲
線の色#a855f7初期値 #a855f7
線の太さ3初期値 3 / 範囲 1〜15
関節点0初期値 0 / 範囲 0〜15
元の写真を表示(透かし)0初期値 0 / 範囲 0〜100

記録では「この線画で保存へ進む」から完成表示へ進んでいます。初期値と記録値を比べてから、効果を1項目ずつ変えると作用を確認しやすくなります。

資料ファイルの作成日は実行日として扱っていません。個別端末の処理速度や、ほかの写真に対する検出・加工の精度を測定した資料でもありません。

実装の確認箇所:src/pages/ai/hand/pose-sketch/index.astro。以下のコード抜粋と出力条件は、この本番実装に基づいて説明します。

仕組みを読み進めるときは、MediaPipeの手ランドマーク(手の21点と接続の読み方)、Canvas APIと画像処理(画像寸法、drawImage、画素と透明度の扱い)が参考になります。

1. 接続マトリックスによるワイヤーフレームの再構築

AI(MediaPipe Hand Landmarker)が返すデータは、手の各関節にあたる21個の「点」の集合です。これだけではイラストの資料としては不十分なため、本ツールでは手首から指先までの「骨格の流れ」を定義した独自の接続リスト(HAND_CONNECTIONS)を用いて、Canvas上に一気に線を引いています。

この実装により、単なる点の羅列を「構造体」として可視化することが可能になります。また、描画時には lineCap="round" と lineJoin="round" を指定することで、デジタル特有の硬さを抑えた、ペン入れしやすい滑らかな線画を実現しています。

21点を接続リストに沿って描く例です。connectionsは手首と各指の関節を結ぶインデックスの組、pointsはMediaPipeの推定結果です。

function drawHandLines(ctx, points, connections, w, h) {
  ctx.beginPath();
  for (const [start, end] of connections) {
    ctx.moveTo(points[start].x * w, points[start].y * h);
    ctx.lineTo(points[end].x * w, points[end].y * h);
  }
  ctx.stroke();
}

2. requestAnimationFrame による低遅延なプレビュー同期

スライダーで線の太さや透過度を連続して変更すると、描画要求も続けて発生します。本ツールでは、値を変更するたびに即時描画を行うのではなく、requestAnimationFrame を介した描画リクエスト方式を採用しています。

これにより、ブラウザの更新タイミングに合わせて描画が最適化され、未実行の描画予約をまとめて、最新の設定で描画します。処理そのものはメインスレッドで行うため、推論や描画が長ければ操作が待たされることはあります。

3. WASMによる完全ローカル処理とプライバシー設計

自撮りした「自分の手」という非常にプライベートな情報を守るため、AIエンジン(Hand Landmarker)はWebAssembly(WASM)技術を用いてユーザーのブラウザ上で直接動作します。

選んだ写真の推論と描画はブラウザ内で行い、画像を処理サーバーへアップロードする実装はありません。ただし、ページやAIモデルの読込には通信と待ち時間が必要です。

出力の仕様と確認する点

線の太さは1〜15、関節点の大きさは0〜15で調整し、0では関節点を描きません。線の色・背景色と元写真の表示量も変えられます。

AI設定は最大4本の手で、入力は長辺1500px以下へ縮小します。描くのはx・y座標を結ぶ2Dの線で、手の輪郭の自動トレースや3Dモデルの書き出しではありません。隠れた指の形を正しく復元する保証もありません。

透明背景はPNG、それ以外はJPEG品質0.95です。元写真の表示量を上げると写真も出力へ含まれます。イラストのレイヤーへ重ねる用途では、透明背景と元写真表示0の組合せを確認してください。

制作時に確かめたこと