影片去 Logo / 去字幕(video-watermark-remover)
用 ProPainter 修補影片中位置固定的 Logo、角標和字幕(壓在畫面上的)。只裁出元素周圍的 ROI 去修補,再羽化貼回原片,ROI 以外的像素不動。
⚠ ProPainter 的授權條款是 S-Lab License 1.0:僅允許非商業用途,商業使用需聯絡原作者取得授權。 僅用於你擁有處理權限的素材。
0. 環境(首次使用)
腳本都在 scripts/ 下,工作目錄必須設為本 skill 目錄(即 SKILL.md 所在目錄)。
python scripts/setup_env.py # 檢查 ffmpeg / PyTorch(CUDA),clone 固定版本的 ProPainter,產生 config.json
python scripts/selftest.py # 合成測試影片跑完整流程,與真值比對,輸出 PASS/FAIL
config.json不存在時,setup_env.py會提示缺少什麼、如何安裝。PyTorch 需要使用者依照自己的顯示卡安裝 CUDA 版本。- 自檢未通過請勿繼續,先依照提示修正環境。
- 下文的
python指的是setup_env.py寫入 config 的那個直譯器(也就是執行 setup 時使用的環境)。
使用者需要提供什麼
| 項目 | 必須 | 說明 |
|---|---|---|
| 影片檔案 | ✅ | 一段或多段 |
| 要去除什麼 | ✅ | 口語描述即可:「左上角台標」「中間大 logo」「底部字幕」 |
| 位置提示 | 可選 | 同類元素不只一個時才需要 |
| 時間段 | 可選 | 預設自動偵測,只有要保留一部分時才需要 |
| 後續規劃 | 建議詢問 | 是否疊加新 Logo、重配字幕、新字幕是否有底條。有底條時直接打模糊即可,不必修補 |
缺少必須項就詢問使用者;可選項不要追問。
能力邊界(開工前對照,超出範圍需先告知使用者)
- ✅ 固定位置的 Logo、角標、台標,包含半透明、淡入淡出、在片頭片尾轉場中被拉模糊的。
- ✅ 固定位置、水平居中、單行的字幕(壓在畫面上的),白字或深色字,帶不帶陰影都行。
- ⚠️ 會移動或縮放的 Logo、滾動字幕、多行字幕、不居中的字幕:腳本無法自動追蹤,需要使用者指出時間段,再用
--block、--grow-from手動處理,效果會打折扣。 - ⚠️ 畫面裡本來就有的文字(標牌、螢幕上的字),和要去除的元素重疊時會被一起抹糊。需在識別清單中提醒使用者。
- 需要 NVIDIA GPU,VRAM 最好空閒 4GB 以上。僅用 CPU 也能跑,但非常慢。
流程(8 步驟,按順序走)
中間檔案放在暫存工作目錄 $W。成品放在原影片旁邊,品質檢查圖放在 <影片目錄>/qc/。
1. 探測
python scripts/probe.py IN1.mp4 [IN2.mp4] --out-dir $W
查看抽幀拼圖,判斷以下事項:
- 元素在哪;
- 是角標還是居中的大 Logo;
- 是否有淡入(記下 Logo 穩定顯示的幀區間)、黑場、縮放或模糊轉場;
- 是否有字幕。
2. 定位(靜態 Logo)
python scripts/locate_static.py --video IN1.mp4@穩定起始幀:結束幀 [--video IN2.mp4@a:b] --out-dir $W
- 起止幀要避開淡入、黑場和轉場。
- 多段素材裡有同一個 Logo 時,一起傳入。 腳本只取「每段都靜止」的像素,這樣可以排除背景裡碰巧靜止的區塊。
- 查看
static_rel.png(越黑越靜止),據此決定 Logo 的大框--box和閾值:實心 Logo 用 0.3–0.5,半透明 Logo 用 0.6–0.75。
3. 製作遮罩,並且必須讓使用者確認
靜態 Logo:
python scripts/mask_logo.py --rel $W/static_rel.npy --box x0,y0,x1,y1 --thresh 0.5 \
[--block 矩形] [--clear 區域 --block 區域] --preview IN1.mp4@幀 [--preview IN2.mp4@幀] --out-dir $W
- 細的元素(文字、射線、線條)依照筆畫摳,筆畫之間的真正背景留給模型做參考。
- 只有兩種情況用
--block矩形:一是實心大塊;二是細到摳不全的小字,例如一行很小的英文。 - ❌ 不要把細元素整塊蓋住。 鏡頭慢慢推進時,被蓋住的那塊幾乎沒有真正背景露出來,模型只能憑空生成,會補出「鱗片紋理」。
- 檢查預覽圖上元素的邊緣和尾巴有沒有漏。漏掉的部分會被修補時往裡帶,留下一截彩線。
字幕:
python scripts/mask_subtitle.py IN.mp4 --out-dir $W [--rows y0,y1] [--dark] [--shadow 0,0]
- 不給
--rows時,會在畫面下 40% 的範圍裡自動找字幕行;找錯了就手動指定。 - 留意輸出中「貼近畫面邊緣」的警告。
給使用者確認:把 mask_preview.png 或 subtitle_mask_preview.png 展示給使用者,再附一份識別清單。座標用 mask_logo.py 列印出來的值,例如:
① 左上角台標:修補框 (21,15)–(124,50),全程出現 ② 底部字幕:y485–524,共 47 句 ③ 1:34 處畫面裡的一塊牌子落在修補區內,會被一起抹糊
使用者確認後才進入第 5 步。
4. 分段
python scripts/shots.py IN.mp4 --out $W/bounds.json [--extra 178]
硬切和淡入淡出轉場都會被切開。不分段就跑,靜止鏡頭裡會冒出鄰近鏡頭顏色的「藥丸狀色塊」。
5+6. 修補 + 合成
長影片要放背景執行,定時查看日誌並主動回報進度。
python scripts/inpaint.py --video IN.mp4 (--mask $W/mask.npy | --masks $W/masks.npz) --bounds $W/bounds.json \
--workdir $W/run --out OUT.mp4 [--mask-dilation 2] [--grow-from 178:14] [--workers 2]
--mask-dilation:預設 2;半透明、帶光暈的 Logo 用 4。--grow-from 幀:像素:從某一幀起把遮罩再外擴若干像素,用來蓋住縮放、模糊轉場裡被拉散的 Logo。- 同一個影片既要去除 Logo 又要去除字幕,分兩次跑:第二次的
--video用第一次的輸出,不要把兩個 ROI 合併成一個大框。 - 中斷後用原命令重跑即可,已經完成的段落會跳過。
- 輸出檔案命名為
原名-nologo.mp4或原名-nologo-nosub.mp4。腳本拒絕覆蓋原片。 - 耗時參考(RTX 3060,2 路並行):960×540 的 126 秒影片,左上角標約 17 分鐘,字幕帶約 21 分鐘;5 秒的居中大 Logo 約 1 分鐘。
7. 品質檢查
python scripts/qc.py --orig IN.mp4 --out OUT.mp4 (--mask .. | --masks ..) --bounds $W/bounds.json --workdir $W/run \
[--residue blue] [--times 3,12,20] --out-dir <影片目錄>/qc/xxx
數值指標:
- 殘影:成品變異數應約等於外圈變異數。
- 閃爍:比值中位數在 1 左右或更小,突跳幀很少。
- 接縫:比值約 1。
- 區外誤差:小於 2。
- 殘留色:降到接近 0。
- 全黑幀:0 幀。
⚠ 數值全部達標也可能有局部問題,必須逐頁打開 sheet_XX.png 用肉眼看(色塊、鱗片紋理、殘字、彩線)。發現問題,回到對應步驟修正:
- 色塊:用
shots.py --extra補充切點。 - 鱗片紋理:改成依照筆畫摳。
- 殘線:補
--block。
修正後只重跑受影響的部分,再品質檢查一遍。
8. 交付
- 給出成品和對比圖的絕對路徑,並把
before_after.png展示給使用者。 - 多段需要拼接時用
python scripts/concat.py A.mp4 B.mp4 C.mp4 --out FULL.mp4,腳本會校驗總幀數等於各段之和。 - 撰寫座標文件,模板見
references/positions-template.md。每個元素寫三層框:原元素範圍、實際修補範圍、含羽化的最外圈(即建議新 Logo 覆蓋的範圍)。字幕用subtitle_info.json裡的union_box。 - 已知瑕疵按時間點列清楚,不要隱藏。
硬規則(皆為實測踩出來的教訓)
- ROI 的寬和高都必須 ≥160。 高 96 時,ProPainter 在遮罩區輸出全黑,換 fp32 也一樣。
inpaint.py自動選 ROI 時已保證這一點。 - 轉場必須切開。 只按硬切分段會漏掉淡入淡出,ProPainter 會跨鏡頭借用像素,出現色塊。擴大遮罩或改用 fp32 都解決不了。
- 細元素依照筆畫摳,不要整塊蓋。
- 字幕要做居中對稱裁切,同一句字幕用同一個遮罩。 不做對稱裁切會把背景亮條摳進來;同一句換不同遮罩會閃爍,淡入時也會漏摳。
- 數值指標會漏掉問題,必須逐頁用肉眼看聯繫圖。
- 動手修補前必須讓使用者確認遮罩。 不覆蓋原片,不刪除使用者的檔案。
- 背景子程序不彈視窗(腳本已內建)。長任務放背景執行,並主動回報進度。