Subtítulos con Evitación del Personaje (Completa / Aproximada)
0. Dos Objetivos a Distinguir
- "Evitación completa": La intersección de cada rectángulo de texto con la máscara del personaje en cada fotograma es 0. El costo es que el texto solo puede colocarse en los bordes laterales/superior estrechos, y el tamaño de fuente está limitado.
- "Evitación aproximada": Se permite la superposición con los bordes de las alas/fondo, pero la cara y el cuerpo deben estar limpios. Puedes seguir usando estilos de fuente grandes (S4/S6, etc.) y solo verificar los fotogramas de primeros planos.
Por defecto, esta habilidad realiza la evitación completa y proporciona datos verificables; si el usuario pide "explosivo/grande/artístico", probablemente se refiere al segundo modo.
1. Algoritmo Principal (Versión Rápida: Solo Bounding Box)
Ya no es necesario calcular una máscara precisa píxel a píxel, solo necesitamos el bounding box del personaje, que se calcula a 1/4 de resolución, muy rápido:
- Placa de fondo
bg_half.npy(1280×540, ver 2.1/3.1 de subject-color-grade). - Redimensionar cada fotograma a 640×270, restar la placa de fondo:
d = |frame-bg|.max(axis=2), umbral 38 (un umbral bajo incluiría los letreros de LOVE/reflejos). - Dilatar con
MaxFilter(5)→ componente conectado más grande (BFS, rápido en 640×270) → tomar bbox ×4 para restaurar a resolución completa. - Unir los bboxes de cada fotograma por ventana de frase lírica (el personaje se mueve dentro de una frase, usar el rango más amplio de toda la frase), obtener
bounds = (left,right,top,bottom)por frase. - Composición: Colocar las columnas de texto a la izquierda de
left-50/ a la derecha deright+50/ en la parte superior / inferior; el tamaño de fuente se reduce según el ancho disponible. - Verificación fotograma a fotograma: Mapear cada rectángulo de texto de vuelta a 640×270, calcular la intersección con la máscara de cada fotograma, reportar el worst hit; si no es 0, reducir el tamaño de fuente globalmente y volver a verificar hasta que sea 0.
2. Implementación Reutilizable Directamente
字幕\build\avoid_side2.py (recomendado, versión completa: pass1 mide bbox → layout → verify → render → fotogramas clave):
$py='C:\Users\35530\.dsh\dsh-runtimes\dsh-primary-runtime\dependencies\python\python.exe'
& $py '字幕\build\avoid_side2.py'
Procesa fijamente un clip antiguo (0001-4956) de 15.4s; para cambiar de clip/segmento, modifica estas constantes:
SRC/OUT/T0,T1CUES(inicio y fin de cada frase, relativas al segmento)EL(posición de columna L/R, y, fs)LEFT_MARGIN/ lógica de ancho disponible derecho Salida:NEON_avoid_15s.ass+ video renderizado + tabla de fotogramas clave. Versiones antiguas (demostración compuesta):avoid_demo.py,avoid_debug.py,avoid_layout.py(mapa de zona ocupada分析_占位与选位.jpg).
3. Datos de Prueba de Este Proyecto (Video Antiguo 0:51–1:06.4)
- Composición fija inferior: 6/6 frases superponen al personaje, tasa de ocultación del área del personaje 7%–12%.
- Evitación lateral: 0/6 frases superponen al personaje, superposición por frase ≤0.2%; verificación fotograma a fotograma 0 píxeles.
- Columnas laterales disponibles por frase (video antiguo, ancho total 2560): columna izquierda aprox. 0–500px, columna derecha aprox. 2100–2560px, varía por frase, debe calcularse en el momento.
- El personaje en el centro del encuadre, con alas desplegadas ocupa aproximadamente 48%–82% del ancho; en primeros planos/close-ups casi llena el encuadre → en fotogramas de close-up solo se puede colocar el texto en las esquinas superior e inferior.
4. Estrategia de Composición (Atractiva Incluso Sin Tapar)
- Colocar la letra principal en la columna izquierda y las palabras decorativas en la columna derecha, creando una sensación de "canto en dúo izquierda-derecha".
- Colocar frases largas en la parte superior (como
MAKING EVERYBODY GO); en la parte inferior solo texto pequeño/información de ancho fijo. - Cada frase tiene un solo "protagonista visual", el resto de palabras se convierten en texto pequeño, evitando que toda la frase sea grande y no quepa en la columna lateral.
- La estimación del rectángulo de texto debe ser conservadora: ancho ASCII ≈ fs×0.66, CJK ≈ fs×1.06; dejar 10–14px de padding.
5. Lista de Verificación
- ¿El bbox de cada ventana de frase omite las puntas de las alas/la parte superior de la cabeza? (ver
分析_占用区域.jpg) - Worst hit en la verificación fotograma a fotograma = 0 (el script lo imprimirá)
- Revisar 3–4 fotogramas: ¿el texto está pegado al borde/recortado? ¿tapa un dedo o un ala?
- Revisar fotogramas de primeros planos/close-ups por separado
- Si se permite "evitación aproximada", registrar qué fotogramas superponen las alas (aceptable)
6. Problemas Conocidos
- Los letreros de LOL/reflejos de fondo pueden ser detectados erróneamente por la diferencia de fotogramas → el umbral 38 + componente conectado más grande normalmente los elimina; si no, añadir prioridad espacial (personaje en el centro).
- La sombra del personaje puede ser detectada como personaje (bbox más grande) → para la evitación es seguro (evitarás la sombra), pero hará las columnas laterales más estrechas.
- El filtro
MaxFilteren 640×270 equivale aproximadamente a una expansión de 8px en resolución completa; no agregues padding extra durante la verificación. - Si se cambia a un video nuevo o una nueva posición de cámara, todos los bounds deben recalcularse, no se pueden reutilizar los números del video antiguo.