Eliminar logotipo / subtítulos de video (video-watermark-remover)
Usa ProPainter para reparar elementos fijos en videos: logotipos, marcas de esquina y subtítulos quemados (superpuestos en el cuadro). Solo recorta la región de interés (ROI) alrededor del elemento para reparar, luego la fusiona con bordes suaves de vuelta al video original; los píxeles fuera del ROI no se modifican.
⚠ La licencia de ProPainter es S-Lab License 1.0: solo permite uso no comercial. Para uso comercial, contacta al autor original. Úsalo solo con material que tengas derecho a procesar.
0. Entorno (primer uso)
Los scripts están en scripts/. El directorio de trabajo debe ser el directorio de esta skill (donde se encuentra SKILL.md).
python scripts/setup_env.py # Verifica ffmpeg / PyTorch (CUDA), clona una versión fija de ProPainter, genera config.json
python scripts/selftest.py # Crea un video de prueba sintético, ejecuta el flujo completo, compara con la verdad y muestra PASS/FAIL
- Si
config.jsonno existe,setup_env.pyindicará qué falta y cómo instalarlo. PyTorch requiere que el usuario instale la versión CUDA según su tarjeta gráfica. - No continúes si la autocomprobación falla; primero corrige el entorno según las indicaciones.
- En adelante,
pythonse refiere al intérprete configurado enconfig.json(el mismo entorno usado al ejecutarsetup).
Qué debe proporcionar el usuario
| Elemento | Obligatorio | Descripción |
|---|---|---|
| Archivo de video | ✅ | Uno o varios |
| Qué eliminar | ✅ | En lenguaje natural: "marca de esquina superior izquierda", "logotipo grande en el centro", "subtítulo inferior" |
| Indicación de posición | Opcional | Solo necesario si hay múltiples elementos similares |
| Intervalo de tiempo | Opcional | Por defecto se detecta automáticamente; solo se necesita si se desea conservar una parte |
| Plan posterior | Recomendado preguntar | Si se va a superponer un nuevo logotipo, resubtitular o si el nuevo subtítulo tiene fondo. Si tiene fondo, basta con aplicar un desenfoque, no es necesario reparar. |
Si falta algún campo obligatorio, pregunta al usuario; no preguntes por los opcionales.
Límites de capacidad (verificar antes de comenzar; si se superan, informar al usuario)
- ✅ Logotipos fijos, marcas de esquina, incluyendo semitransparentes, fundidos, o que aparecen deformados en transiciones de apertura/cierre.
- ✅ Subtítulos fijos, centrados horizontalmente, de una línea (superpuestos en el cuadro), blancos u oscuros, con o sin sombra.
- ⚠️ Logotipos que se mueven o escalan, subtítulos en desplazamiento (scrolling), subtítulos de múltiples líneas o no centrados: los scripts no pueden rastrearlos automáticamente; el usuario debe indicar el intervalo y usar
--blocko--grow-frommanualmente, con resultados reducidos. - ⚠️ Texto que ya está en la escena (carteles, texto en pantalla) que se superponga con el elemento a eliminar será borrado junto con él. Adviértelo en la lista de identificación.
- Se requiere GPU NVIDIA, preferiblemente con más de 4 GB de VRAM libre. También puede ejecutarse solo con CPU, pero será muy lento.
Flujo (8 pasos, en orden)
Los archivos intermedios se guardan en un directorio de trabajo temporal $W. El video final se coloca junto al original, y las imágenes de control de calidad en <directorio del video>/qc/.
1. Detección
python scripts/probe.py IN1.mp4 [IN2.mp4] --out-dir $W
Examina los mosaicos de fotogramas extraídos para determinar:
- Dónde está el elemento;
- Si es una marca de esquina o un logotipo grande centrado;
- Si hay fundido de entrada (registra el intervalo de fotogramas donde el logotipo es estable), campos negros, transiciones de zoom o desenfoque;
- Si hay subtítulos.
2. Localización (logotipo estático)
python scripts/locate_static.py --video IN1.mp4@fotograma_inicio:fotograma_fin [--video IN2.mp4@a:b] --out-dir $W
- Los fotogramas de inicio y fin deben evitar fundidos, campos negros y transiciones.
- Si el mismo logotipo aparece en múltiples fragmentos, pásalos juntos. El script solo toma los píxeles que permanecen estáticos en todos los fragmentos, eliminando así áreas que por casualidad son estáticas en el fondo.
- Revisa
static_rel.png(cuanto más negro, más estático). Con base en esto, define el cuadro delimitador--boxy el umbral: logotipos sólidos usan 0.3–0.5, logotipos semitransparentes usan 0.6–0.75.
3. Crear máscara y obtener confirmación del usuario
Logotipo estático:
python scripts/mask_logo.py --rel $W/static_rel.npy --box x0,y0,x1,y1 --thresh 0.5 \
[--block rectángulo] [--clear área --block área] --preview IN1.mp4@fotograma [--preview IN2.mp4@fotograma] --out-dir $W
- Los elementos finos (texto, líneas, trazos) se recortan por trazo, dejando el fondo real visible entre los trazos como referencia para el modelo.
- Solo se usa
--block(rectángulo) en dos casos: para elementos sólidos grandes, o para texto pequeño que no se puede recortar completamente por trazo, como una línea pequeña de texto en inglés. - ❌ No cubras completamente los elementos finos con un rectángulo. Cuando la cámara se acerca lentamente, el área cubierta casi no tendrá fondo real visible, y el modelo tendrá que generarlo de la nada, produciendo una textura de "escamas".
- Revisa en la imagen de vista previa si los bordes y las colas del elemento quedan descubiertos. Las partes descubiertas se arrastrarán durante la reparación, dejando líneas de color.
Subtítulos:
python scripts/mask_subtitle.py IN.mp4 --out-dir $W [--rows y0,y1] [--dark] [--shadow 0,0]
- Si no se proporciona
--rows, busca automáticamente las líneas de subtítulos en el 40% inferior del cuadro; si se equivoca, especifícalo manualmente. - Presta atención a las advertencias de "cerca del borde del cuadro" en la salida.
Confirmación del usuario: Muestra mask_preview.png o subtitle_mask_preview.png al usuario, junto con una lista de identificación. Las coordenadas se toman de los valores impresos por mask_logo.py, por ejemplo:
① Marca de esquina superior izquierda: cuadro de reparación (21,15)–(124,50), presente durante todo el video ② Subtítulo inferior: y485–524, total 47 líneas ③ En 1:34, hay un cartel en la escena que cae dentro del área de reparación y se borrará junto con el resto
Solo después de la confirmación del usuario se pasa al paso 5.
4. Segmentación
python scripts/shots.py IN.mp4 --out $W/bounds.json [--extra 178]
Se dividen los cortes duros y las transiciones de fundido. Si no se segmenta, en tomas estáticas aparecerán "manchas de color tipo píldora" provenientes de los colores de tomas vecinas.
5+6. Reparación + Composición
Para videos largos, ejecuta en segundo plano, revisa el registro periódicamente e informa el progreso activamente.
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: predeterminado 2; para logotipos semitransparentes o con halo, usa 4.--grow-from fotograma:píxeles: desde un fotograma específico, expande la máscara varios píxeles más, para cubrir logotipos que se dispersan durante transiciones de zoom o desenfoque.- Si el mismo video necesita eliminar tanto logotipo como subtítulos, hazlo en dos ejecuciones separadas: en la segunda,
--videoapunta a la salida de la primera; no combines las dos ROI en un solo cuadro grande. - Si se interrumpe, solo vuelve a ejecutar el mismo comando; las partes ya completadas se omitirán.
- El archivo de salida se nombra
original-nologo.mp4ooriginal-nologo-nosub.mp4. El script rechaza sobrescribir el original. - Tiempo de referencia (RTX 3060, 2 hilos paralelos): video de 960×540 y 126 segundos, marca de esquina superior izquierda ≈ 17 minutos, subtítulos ≈ 21 minutos; logotipo grande centrado de 5 segundos ≈ 1 minuto.
7. Control de calidad (QC)
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 <directorio del video>/qc/xxx
Métricas:
- Residuo: la varianza del video final debe ser aproximadamente igual a la varianza del área exterior.
- Parpadeo: la mediana de la relación debe estar alrededor de 1 o menos, con pocos fotogramas de salto.
- Costuras: la relación debe ser aproximadamente 1.
- Error fuera del área: menor que 2.
- Color residual: debe reducirse a casi 0.
- Fotogramas completamente negros: 0 fotogramas.
⚠ Incluso si todas las métricas son correctas, puede haber problemas locales; debes revisar cada página de sheet_XX.png visualmente (manchas de color, textura de escamas, restos de texto, líneas de color). Si encuentras problemas, vuelve al paso correspondiente para corregirlos:
- Manchas de color: usa
shots.py --extrapara agregar puntos de corte adicionales. - Textura de escamas: cambia a recorte por trazo.
- Líneas restantes: agrega
--block.
Después de corregir, solo vuelve a ejecutar las partes afectadas y repite el QC.
8. Entrega
- Proporciona las rutas absolutas del video final y las imágenes de comparación, y muestra
before_after.pngal usuario. - Si hay múltiples fragmentos que unir, usa
python scripts/concat.py A.mp4 B.mp4 C.mp4 --out FULL.mp4; el script verificará que el número total de fotogramas sea igual a la suma de los fragmentos. - Escribe un documento de coordenadas, plantilla en
references/positions-template.md. Para cada elemento, escribe tres niveles de cuadro: el rango original del elemento, el rango real de reparación y el borde exterior con fusión suave (es decir, el área recomendada para superponer el nuevo logotipo). Para subtítulos, usaunion_boxdesubtitle_info.json. - Enumera los defectos conocidos por marca de tiempo, sin ocultarlos.
Reglas estrictas (basadas en pruebas reales)
- El ancho y alto de la ROI deben ser ≥ 160. Si la altura es 96, ProPainter genera negro completo en el área de la máscara, incluso con fp32.
inpaint.pyya garantiza esto al seleccionar automáticamente la ROI. - Las transiciones deben dividirse. Si solo se segmentan cortes duros, se omitirán los fundidos; ProPainter tomará píxeles de tomas vecinas, causando manchas de color. Ni expandir la máscara ni usar fp32 soluciona esto.
- Los elementos finos se recortan por trazo, no se cubren completamente con un rectángulo.
- Los subtítulos deben recortarse con simetría central; una misma línea de subtítulo debe usar la misma máscara. Si no se hace el recorte simétrico, se pueden incluir barras brillantes del fondo; si se usan máscaras diferentes para la misma línea, aparecerá parpadeo, y durante los fundidos también se filtrarán partes.
- Las métricas pueden pasar por alto problemas; debes revisar visualmente cada página de la hoja de contacto.
- Antes de reparar, debes obtener confirmación del usuario sobre la máscara. No sobrescribas el video original ni elimines archivos del usuario.
- Los procesos en segundo plano no deben abrir ventanas emergentes (el script ya lo tiene incorporado). Las tareas largas se ejecutan en segundo plano con informe activo de progreso.