Remoção de logo/legendas de vídeo (video-watermark-remover)
Use o ProPainter para reparar logotipos, selos de canto e legendas (impressas na tela) que estão em posição fixa em vídeos. Apenas recorta a ROI ao redor do elemento para reparar, depois suaviza e cola de volta no vídeo original, sem alterar pixels fora da ROI.
⚠ A licença do ProPainter é S-Lab License 1.0: apenas uso não comercial é permitido. Para uso comercial, entre em contato com os autores. Use apenas em materiais que você tem o direito de processar.
0. Ambiente (primeiro uso)
Os scripts estão em scripts/, e o diretório de trabalho deve ser o diretório desta skill (ou seja, onde SKILL.md está).
python scripts/setup_env.py # Verifica ffmpeg / PyTorch (CUDA), clona a versão fixa do ProPainter, gera config.json
python scripts/selftest.py # Cria vídeo de teste, executa o fluxo completo, compara com o ground truth e retorna PASS/FAIL
- Se
config.jsonnão existir,setup_env.pyindicará o que está faltando e como instalar. O PyTorch precisa ser instalado pelo usuário de acordo com sua placa de vídeo (versão CUDA). - Não prossiga se o autoteste falhar; resolva o ambiente primeiro.
- Daqui em diante,
pythonse refere ao interpretador escrito no config pelosetup_env.py(ou seja, o ambiente usado ao executar setup).
O que o usuário deve fornecer
| Item | Obrigatório | Descrição |
|---|---|---|
| Arquivo de vídeo | ✅ | Um ou mais |
| O que remover | ✅ | Linguagem natural: "logotipo no canto superior esquerdo", "logotipo grande no meio", "legenda no rodapé" |
| Dica de posição | Opcional | Necessário apenas se houver mais de um elemento do mesmo tipo |
| Intervalo de tempo | Opcional | Padrão: detecção automática. Necessário apenas se quiser preservar uma parte |
| Próximos passos | Sugerido perguntar | Se vai sobrepor novo logo, re-legendar, se a nova legenda tem fundo. Se tiver fundo, apenas desfoque, sem necessidade de reparo |
Questione apenas itens obrigatórios; não pergunte opcionais.
Limites de capacidade (verifique antes de começar, avise o usuário se exceder)
- ✅ Logotipos fixos, selos de canto, marcas de transmissão, incluindo semitransparentes, com fade in/out, que são esticados ou desfocados em transições de abertura/fechamento.
- ✅ Legendas fixas, centralizadas horizontalmente, de linha única (impressas na tela), brancas ou escuras, com ou sem sombra.
- ⚠️ Logotipos que se movem ou escalam, legendas rolantes, legendas de múltiplas linhas, legendas não centralizadas: o script não pode rastrear automaticamente; o usuário precisará indicar o intervalo de tempo, e usar
--block,--grow-frommanualmente, com qualidade reduzida. - ⚠️ Texto existente na cena (placas, textos na tela) que se sobrepõe ao elemento a ser removido será desfocado junto. Alerte o usuário na lista de identificação.
- Requer GPU NVIDIA, de preferência com pelo menos 4 GB de VRAM livre. Funciona apenas com CPU, mas é muito lento.
Fluxo (8 etapas, em ordem)
Arquivos intermediários ficam no diretório de trabalho temporário $W. O vídeo final é salvo ao lado do original, as imagens de controle de qualidade ficam em <diretório do vídeo>/qc/.
1. Detecção
python scripts/probe.py IN1.mp4 [IN2.mp4] --out-dir $W
Analisa os quadros amostrados e determina:
- Onde está o elemento;
- Se é um selo de canto ou um logotipo grande centralizado;
- Se há fade in (anote o intervalo de quadros onde o logotipo está estável), fade para preto, zoom ou transições com desfoque;
- Se há legendas.
2. Localização (logotipo estático)
python scripts/locate_static.py --video IN1.mp4@quadro_início:quadro_fim [--video IN2.mp4@a:b] --out-dir $W
- Evite quadros de fade in, fade para preto e transições.
- Quando o mesmo logotipo aparece em vários arquivos, passe todos juntos. O script considera apenas pixels que estão estáticos em todos os vídeos, excluindo blocos que acidentalmente estão parados no fundo.
- Veja
static_rel.png(quanto mais preto, mais estático). Use isso para definir o--box(caixa) e o limiar: logotipos sólidos use 0.3–0.5, logotipos semitransparentes use 0.6–0.75.
3. Criação da máscara, e obrigatório que o usuário confirme
Logotipo estático:
python scripts/mask_logo.py --rel $W/static_rel.npy --box x0,y0,x1,y1 --thresh 0.5 \
[--block retângulo] [--clear região --block região] --preview IN1.mp4@quadro [--preview IN2.mp4@quadro] --out-dir $W
- Elementos finos (texto, raios, linhas) devem ser recortados traço a traço, deixando o fundo real entre eles como referência para o modelo.
- Use
--blockretângulo apenas em dois casos: blocos sólidos grandes OU texto muito pequeno que não pode ser recortado completamente, como uma linha de texto pequeno em inglês. - ❌ Nunca cubra completamente um elemento fino. Quando a câmera se aproxima lentamente, a área coberta perde quase todo o fundo real, e o modelo gera conteúdo do zero, resultando em textura de "escamas".
- Verifique na imagem de pré-visualização se bordas e pontas do elemento estão faltando. Se faltarem, serão arrastadas para dentro durante o reparo, deixando uma linha colorida.
Legendas:
python scripts/mask_subtitle.py IN.mp4 --out-dir $W [--rows y0,y1] [--dark] [--shadow 0,0]
- Sem
--rows, o script procurará automaticamente linhas de legenda nos 40% inferiores da tela; se encontrar errado, especifique manualmente. - Preste atenção aos avisos de "próximo à borda da tela" na saída.
Confirmação do usuário: Mostre mask_preview.png ou subtitle_mask_preview.png ao usuário, junto com uma lista de identificação. Use as coordenadas impressas por mask_logo.py, por exemplo:
① Logotipo no canto superior esquerdo: caixa de reparo (21,15)–(124,50), aparece durante todo o vídeo ② Legenda no rodapé: y485–524, total de 47 sentenças ③ Em 1:34, uma placa na cena cai dentro da área de reparo e será desfocada junto
O usuário deve confirmar antes de prosseguir para a etapa 5.
4. Segmentação
python scripts/shots.py IN.mp4 --out $W/bounds.json [--extra 178]
Cortes abruptos e transições com fade in/out são segmentados. Se não segmentar, em cenas estáticas aparecerão "blocos de cor em formato de pílula" originados de cores de cenas vizinhas.
5+6. Inpaint + Composição
Vídeos longos devem ser executados em segundo plano, verificando logs periodicamente e reportando progresso ativamente.
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: padrão 2; para logotipos semitransparentes com brilho, use 4.--grow-from quadro:pixels: a partir de um certo quadro, expande a máscara em alguns pixels para cobrir logotipos que se espalham em transições de zoom ou desfoque.- Para remover logo e legenda no mesmo vídeo, execute duas vezes separadamente: o
--videoda segunda execução usa a saída da primeira, não combine as duas ROIs em uma caixa grande. - Se interromper, basta re-executar o comando original; as etapas já concluídas serão ignoradas.
- O arquivo de saída é nomeado como
original-nologo.mp4ouoriginal-nologo-nosub.mp4. O script se recusa a sobrescrever o original. - Referência de tempo (RTX 3060, 2 workers paralelos): vídeo 960×540 de 126 segundos: logotipo no canto ~17 min, legenda ~21 min; logotipo grande centralizado de 5 segundos ~1 min.
7. Controle de qualidade
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 <diretório do vídeo>/qc/xxx
Métricas numéricas:
- Resíduo: A variância do vídeo final deve ser aproximadamente igual à variância da área externa.
- Cintilação: A mediana da razão deve estar em torno de 1 ou menor, com poucos quadros de salto.
- Costura: Razão próxima de 1.
- Erro fora da área: menor que 2.
- Cor residual: reduzida para próximo de zero.
- Quadros totalmente pretos: 0 quadros.
⚠ Mesmo se todas as métricas estiverem boas, podem existir problemas locais. É obrigatório abrir cada sheet_XX.png e inspecionar visualmente (blocos de cor, textura de escamas, caracteres residuais, linhas coloridas). Se encontrar problemas, volte à etapa correspondente e corrija:
- Bloco de cor: use
shots.py --extrapara adicionar pontos de corte. - Textura de escamas: mude para recorte traço a traço.
- Linha residual: adicione
--block.
Após corrigir, execute novamente apenas as partes afetadas e refaça o controle de qualidade.
8. Entrega
- Forneça o caminho absoluto do vídeo final e da imagem de comparação, e mostre
before_after.pngao usuário. - Se precisar concatenar vários vídeos, use
python scripts/concat.py A.mp4 B.mp4 C.mp4 --out FULL.mp4. O script verificará se o total de quadros é igual à soma das partes. - Escreva um documento de coordenadas, modelo em
references/positions-template.md. Para cada elemento, escreva três níveis de caixa: área do elemento original, área de reparo real, e a borda mais externa com feathering (ou seja, a área recomendada para sobrepor um novo logotipo). Para legendas, useunion_boxdesubtitle_info.json. - Liste os defeitos conhecidos com timestamps claramente; não esconda.
Regras rígidas (todas descobertas empiricamente)
- Largura e altura da ROI devem ser ≥ 160. Com altura 96, o ProPainter gera preto total na área da máscara, mesmo com fp32.
inpaint.pyjá garante isso ao selecionar automaticamente a ROI. - Transições devem ser segmentadas. Segmentar apenas por cortes abruptos perde fades in/out; o ProPainter pegará pixels emprestados de cenas vizinhas, gerando blocos de cor. Aumentar a máscara ou usar fp32 não resolve.
- Elementos finos: recorte traço a traço, não cubra completamente.
- Legendas: corte centralizado simétrico, use a mesma máscara para a mesma sentença. Sem corte simétrico, faixas claras do fundo serão puxadas para dentro; máscaras diferentes para a mesma sentença causam cintilação e falhas no fade in.
- Métricas numéricas perdem problemas; é obrigatório inspecionar visualmente as folhas de contato.
- Antes de iniciar o reparo, o usuário deve confirmar a máscara. Não sobrescreva o original, não delete arquivos do usuário.
- Subprocessos em segundo plano não abrem janelas (já implementado nos scripts). Tarefas longas devem rodar em segundo plano, com relatório ativo de progresso.