Communitygithub.com

muyunxue/dance-mmd-subtitle-kit

MMD ダンス動画向けの被写体制御カラーグレーディング——舞者を強調(背景を暗く/冷たく/彩度低下、被写体を明るく/暖かく/シャープ/輝かせる)ために、ソフトなステージライト楕円またはハードなキャラクターマットを使用。ffmpeg レシピ、測定済みパラメータセット、既知の失敗モード(キャストシャドウマット汚染、バンディング、ソース切断)も含む。調色/人物強調/背景圧縮/トーン統一が必要な場合、またはグレーディング後のクリップがダンサーの周りに変な明るい塊を表示する場合にロードします。

dance-mmd-subtitle-kit とは?

このスキルは、MMD(MikuMikuDance)ダンス動画において、被写体(ダンサー)を視覚的に際立たせるためのカラーグレーディング技術を提供します。主に2つのアプローチをサポートします。1つ目は「ライトゾーンシェーピング」で、ダンサーを中心としたソフトな楕円形の明るい領域を生成し、内部(被写体)を明るく/暖かく/彩度高く/微かに輝かせ、外部(背景)を暗く/冷たく/彩度低く/微かにぼかすことで自然な分離を実現します。これが推奨される方法で、ffmpeg フィルターグラフを使って効率的に処理できます。2つ目は「ハードキーイング」(硬いマット分離)で、フレーム差から人物のマスクを抽出し、被写体と背景を別々にグレーディングして合成します。理論的には品質が高いですが、キャストシャドウ(人物の影)がマスクに混入しやすく、ダンサーの周りに不自然な明るいブロブが発生するなど、実用的な課題があります。このスキルでは、Python スクリプト(PIL/numpy ベース)、ffmpeg フィルター、そして測定済みのパラメータセットを提供し、紫基調のステージなど様々なシーンに適用可能です。また、既知の失敗モード(キャストシャドウマット汚染、背景板の人物汚染、8bit 色帯等)とその対策についても文書化されています。

対応~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/muyunxue/dance-mmd-subtitle-kit/tree/HEAD/skills/subject-color-grade

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

MMD 主体認識カラーグレーディング(人物強調)

0. 結論

  • MMD ステージ動画で「人物を強調」するには、2つの方法:
    1. ライトゾーンシェーピング(推奨、クリーン):人物を中心としたソフトな楕円/放射状グラデーション——楕円内の人物を明るく/暖かく/シャープ/輝かせ、楕円外の背景を暗く/冷たく/彩度低下/微かにぼかす;エッジのトランジションは非常に広く、ほとんど円が見えない。
    2. ハードキーイング分離(上限は高いが汚れやすい):フレーム差背景板から人物マスクを取得し、人物/背景を別々にグレーディングして合成。難点は人物の影(キャストシャドウ)が人物と一緒に動き、繋がってしまうこと → マスクに大きな影が含まれる → 明るい斑点が発生;強引に縮小すると羽や翼などが削られる。
  • 最終成果物の場合は1を選択;Blender/MMD からアルファ付きのキャラクターレイヤーを再レンダリングできる場合は2を選択(最高品質)。

1. 素材とツール

アイテムパス
ソース動画D:\mmd.mp4\0002-4956.mkv(フル 165.166s)/ 字幕\0001-4956 - コピー.mkv(約137sにカット)
グレーディングスクリプト字幕\build\grade_ffmpeg.py(ライトゾーン/ソフトライト)、grade_final5s.py(5s 最終パラメータ)、color_grade.py(旧版フレーム差キーイング)、gothic_art.py(静的フレームゴシック調色)
検証スクリプトavoid_layout.py(占有率分析)、avoid_side2.py(占有率+bbox)
ffmpegC:\Users\35530\AppData\Local\Microsoft\WinGet\Packages\Gyan.FFmpeg_Microsoft.Winget.Source_8wekyb3d8bbwe\ffmpeg-9.0-full_build\bin\ffmpeg.exe
PythonC:\Users\35530\.dsh\dsh-runtimes\dsh-primary-runtime\dependencies\python\python.exe(PIL/numpy、cv2/深層学習なし)

2. ルート A:ライトゾーンシェーピング(本プロジェクトのデフォルト)

2.1 ソフトマスクの生成(1回限りの PNG)

import numpy as np
from PIL import Image
W,H = 2560,1080
yy,xx = np.mgrid[0:H,0:W].astype(np.float32)
cx,cy = 0.515,0.565          # 人物中心(2560x1080 縦構図はおおよそこの位置;別の動画の場合はフレームを確認して調整)
rx,ry = 0.245,0.47           # 半幅/半高(比率);小さすぎると円が見え、大きすぎると分離効果が弱まる
q = ((xx-W*cx)/(W*rx))**2 + ((yy-H*cy)/(H*ry))**2
mask = np.clip(1.0-q,0,1)**0.55          # 0.5–0.7 がソフトめ
Image.fromarray((mask*255).astype(np.uint8)).save("_mask_final.png")

参考成品:字幕\出力\調色テスト\_mask_final.png、字幕\出力\字幕サンプル\_mask_final.png。

2.2 ffmpeg 合成(人物浮き上がらせ + 背景暗く)

考え方:人物用グレーディング版 + 背景用グレーディング版、マスクでアルファ合成:

[0:v]split=2[sv][bv];
[sv]eq=brightness=0.050:contrast=1.06:saturation=1.15,
    colorbalance=rs=0.02:bs=-0.02:rm=0.05:bm=-0.06:rh=0.02:bh=-0.02,
    split=2[sm][sh];[sh]gblur=sigma=14[blur];
    [sm][blur]blend=all_mode=screen:all_opacity=0.34[sub];
    [sub]format=yuva420p[suba];
[1:v]format=gray[gm];[suba][gm]alphamerge[subj];
[bv]eq=brightness=-0.045:contrast=1.07:saturation=0.87,
    colorbalance=rm=-0.03:bm=0.05,gblur=sigma=0.6[bg];
[bg][subj]overlay=0:0,format=yuv420p[v]

コマンド:

& $ff -v error -y -ss 36.5 -t 30 -i src.mkv -loop 1 -i _mask_final.png `
  -filter_complex "<上記 graph>" -map "[v]" -t 30 `
  -c:v libx264 -preset medium -crf 16 -pix_fmt yuv420p OUT.mp4

注意:-loop 1 -i mask.png の場合マスクは静止ストリーム;overlay 終了後は -t で長さを制限すること。 パラメータの意味:bg brightness 負=暗くする、saturation<1=彩度低下、bm>0=背景を青み(寒色)に、gblur=微かにぼかし;subj 側では brightness/彩度/暖色/blend screen で輝きを追加。

2.3 実測パラメータセット(2560×1080、紫ステージ MMD)

設定bg brightnessbg satsubj gainsubj satbloomvignette効果
A 自然−0.0350.82+0.0301.080.200.30軽く人物を引き立て、雰囲気はほとんど変えず
B 強化−0.0750.70+0.0551.160.340.42明確な分離、ライトゾーンのエッジがわずかに見える
最終方向−0.0850.68+0.0501.150.300.38ソフトライトが非常に広く、全編のベースとして推奨

5s でパラメータを試し、満足したらそのまま 30s/全編に適用(ffmpeg で一括処理の方がフレームごとの Python より速い)。

3. ルート B:ハードキーイング(よりクリーンなマスクが必要な場合)

3.1 背景板

  • 全編から 1/2s ごとにフレームをサンプリング、1280×540 に縮小、ピクセルごとに中央値 = 背景板 bg_half.npy。
  • コマンド/レビュー:字幕\build\color_grade.py の build_background()。
  • 既知の問題:人物が中央に長時間立っている場合、中央値が人物に「汚染」される(人物の一部のピクセルが頻繁に出現する) → フレーム差が胴体部分で小さくなる → マスクに穴。fill_holes または bbox で対策。

3.2 フレーム差マスク(1/4 解像度が最速)

m = |frame_q - bg_q|.max(axis=2) > 38
m = MaxFilter(5)(外側に拡大)→ largest connected component → 必要に応じて穴埋め/ブラー
  • 占有率分析/回避(avoid-subtitles 参照)に使用;グレーディングに使用する場合は「人物類似度」制約を追加しないと、影/光斑が混入する。

3.3 既知の失敗パターン(本プロジェクトで実測)

  • 影の汚染:人物の影が動きに合わせて移動し、マスクが繋がる → グレーディング後に人物周辺に明るい斑点/色ブロックが出現。解決策:フレーム差を正確なマットとして使用しない;影ごと明るくする(不自然)か、ライトゾーンシェーピングに戻る。
  • 中央値背景の汚染:人物が立ち止まっている部分でマスクに穴 → 胴体がグレーディングされず、斑模様になる。解決策:穴埋め/bbox の使用。
  • 8bit 色帯:大幅な色調整後、空やグラデーションに色帯が発生 → 1–3 の粒状ノイズ追加(ffmpeg noise=alls=6:allf=t+u)または 10bit/HEVC 出力。
  • 字幕のコントラスト:ベースを暗くすると白文字がより明確になる;暗くしすぎると人物も暗くなるため、人物をさらに明るくするか bloom を追加する必要がある。

4. ゴシック/ネオン等のスタイライズドグレーディング(静的フレーム用)

  • ゴシック赤黒(ユーザーに却下済み、アーカイブのみ):字幕\build\gothic_art.py の gothic_grade():明るさ 0.42–0.52 に暗く、彩度 0.30–0.42 に低下、中間調を紫/赤に、強めのビネット、霞。
  • テーマカラーバージョン(ユーザーが最終的に希望したもの):白/骨白を基調 + ラベンダー紫/マゼンタピンクの輝き、背景を濃い紫黒に;gothic_art.py 内の調色定数(BLOOD/LAV/PINK/VIOLET)参照。
  • ネオンバージョン:neon_wide.py(ASS で直接ネオン描画、グレーディング不要)。
  • クイックカラー適用:eq + colorbalance + vignette の3点セットで紫ステージを任意の色調に変更可能:
    • 冷たい青:colorbalance=bs=0.10:bm=0.12:bm...(青にシフト)、彩度低下;
    • 暖かく燃えるような:colorbalance=rs=0.10:rm=0.08、eq=saturation=1.1。

5. 検証チェックリスト

  • 3–5 フレーム抽出:人物の明るさと背景の分離が自然か、ライトゾーンのエッジに明らかな円がないか
  • 近接/クローズアップ:顔が露出オーバーになっていないか、肌の色が偏っていないか
  • 暗部が死滅/色帯(8bit)になっていないか
  • 字幕と一緒に確認:白文字が十分に明確か
  • 出力 ffprobe の長さ/フレームレートが正しい;10bit 出力は -pix_fmt yuv420p10le -c:v libx265 を使用

6. リソース

  • 5s 最終パラメータと比較:字幕\出力\調色テスト\(A自然/B強化/最終方向 + 比較動画)
  • 30s ベース:字幕\出力\S4S6_30s\_base_30s.mp4(軽く暗くしたのみ、フルグレーディングなし)
  • 以前試したが却下された方向:ゴシック(字幕\出力\字幕設計\G1…G3)、FLARE 演出、ネオン(字幕\出力\字幕サンプル)——パラメータ参照用にアーカイブ。

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

muyunxue/dance-mmd-subtitle-kit

Hard rules, templates, ffmpeg commands and failure diagnosis for authoring ASS/SSA subtitles and burning them with libass on this machine. Load this before writing any ASS file, when a burn "succeeds" but no text appears, when text is misplaced/too big, when \p1 drawings are offset, or when you need the transparent-overlay export recipe. Contains the exact pitfalls hit in this project (timestamp format, style colour trailing ampersand, fontsdir, drawing anchor, chained \t, Permanent Marker sizing).

muyunxue/dance-mmd-subtitle-kit

Character-avoiding subtitle layout for the MMD dance videos — measure the dancer's per-frame bounding box, compute a per-cue union, place text in safe side/top columns, and verify zero overlap on every frame. Load this when asked 字幕不要挡住人物/完全不挡/避让, or when text overlaps wings/body and you need a verified-free layout with measured overlap counts.

muyunxue/dance-mmd-subtitle-kit

End-to-end recipe for making subtitles for the MMD dance videos in this workspace (字幕/ project) — probe the source, pick a segment, map LRC cues, choose a style, build ASS, burn, verify, and deliver. Load this when starting or resuming any subtitle task (静态稿/5s小样/30s小样/全片/透明叠加层), when a render "succeeded" but the video has no text, or when you need this project's paths, font list, cue sheet and acceptance criteria.

muyunxue/dance-mmd-subtitle-kit

Design and deliver subtitle style mockups and animated comparison samples for the MMD/K-pop dance videos — S1–S6 style catalogue (Y2K chrome, minimal kinetic, glitch, mix&match editorial, graphic emphasis, hand-marker), PIL/numpy effect recipes, font list, contact-sheet/comparison video conventions, and the parallel-subagent workflow used for S4 vs S6. Load this when asked 出几个静态帧方案/参考女团PV字幕/做个小样/对比几个风格, or when choosing a visual direction before building a full-length subtitle track.

関連スキル