Personenausweichende Untertitel (vollständig/weitestgehend nicht überlappend)
0. Zwei Ziele klar unterscheiden
- „Vollständig nicht überlappend“: Die Schnittmenge jedes Buchstabenrahmens mit der Maske der Figur in jedem Frame = 0. Der Preis: Der Text kann nur in schmalen seitlichen/oberen Spalten platziert werden, die Schriftgröße ist begrenzt.
- „Weitestgehend nicht überlappend“: Erlaubt Überlappungen mit Flügelrändern/Hintergrund, aber Gesicht und Körper müssen frei bleiben. Große Schriftstile (S4/S6 usw.) können weiterhin verwendet werden, es werden nur Nahaufnahmen-Frames geprüft.
Dieses Skill verwendet standardmäßig den Modus „vollständig nicht überlappend“ und liefert überprüfbare Daten. Wenn der Benutzer „übertrieben/große Schrift/künstlerischer Text“ sagt, handelt es sich wahrscheinlich um Letzteres.
1. Kernalgorithmus (schnelle Version: nur Bounding Box)
Nicht mehr pixelgenaue Matten, nur die Bounding Box der Figur, berechnet in 1/4 Auflösung, sehr schnell:
- Hintergrundplatte
bg_half.npy(1280×540, siehe 2.1/3.1 von subject-color-grade). - Jeden Frame auf 640×270 verkleinern, Differenz zur Hintergrundplatte bilden:
d = |frame-bg|.max(axis=2), Schwellwert 38 (niedrigerer Schwellwert würde LOVE-Lampenschilder/Lichtflecken einbeziehen). MaxFilter(5)aufblähen → größte zusammenhängende Region (BFS, auf 640×270 sehr schnell) → Bounding Box ×4 zurück auf Vollauflösung.- Pro Liedtext-Fenster die Bounding Boxes aller Frames vereinigen (die Figur bewegt sich innerhalb eines Satzes, also breitester Bereich des gesamten Satzes), ergibt pro Satz
bounds = (left,right,top,bottom). - Layout: Textspalten links von
left-50/ rechts vonright+50/ oben / unten platzieren; Schriftgröße nach verfügbarer Breite anpassen. - Frame-für-Frame-Überprüfung: Jeden Buchstabenrahmen zurück auf 640×270 abbilden, mit der Maske jedes Frames schneiden, den schlimmsten Treffer melden; ist dieser nicht 0, wird die gesamte Schriftgröße reduziert und erneut geprüft, bis 0 erreicht ist.
2. Direkt wiederverwendbare Implementierung
Untertitel\build\avoid_side2.py (empfohlen, vollständige Version: Pass1 misst BBox → Layout → Verify → Rendern → Keyframes):
$py='C:\Users\35530\.dsh\dsh-runtimes\dsh-primary-runtime\dependencies\python\python.exe'
& $py 'Untertitel\build\avoid_side2.py'
Es verarbeitet standardmäßig eine alte Szene (0001-4956) von 15,4 s Länge; zum Wechseln von Szene/Segment diese Konstanten ändern:
SRC/OUT/T0,T1CUES(Start/Ende jedes Satzes, relativ zum Segment)- Schriftgröße/Positionskandidaten in
EL(L/RSpalte, y, fs) LEFT_MARGIN/ Logik der verfügbaren Breite rechts Ergebnisse:NEON_avoid_15s.ass+ gerendertes Video + Keyframe-Tabelle. Alte Versionen (Synthese-Demo):avoid_demo.py,avoid_debug.py,avoid_layout.py(Belegungs-HitzekarteAnalyse_Belegung_und_Positionswahl.jpg).
3. Gemessene Daten dieses Projekts (alte Szene 0:51–1:06.4)
- Festes unteres Layout: 6/6 Sätze überlappen die Figur, Überdeckungsrate des Figurenbereichs 7%–12%.
- Seiten-Spalt-Ausweichung: 0/6 Sätze überlappen die Figur, Überdeckung pro Satz ≤0,2%; Frame-für-Frame-Überprüfung 0 Pixel.
- Verfügbare Seiten-Spalte pro Satz (alte Szene, volle 2560 breit): linke Spalte ca. 0–500px, rechte Spalte ca. 2100–2560px, je Satz unterschiedlich, muss aktuell berechnet werden.
- Die Figur in der Bildmitte, mit ausgebreiteten Flügeln, nimmt ca. 48%–82% der Breite ein; bei Nahaufnahmen fast vollständig → Nahaufnahme-Frames zwingen den Text in die oberen/unteren Ecken.
4. Layout-Strategie (auch ohne Überlappung ansprechend)
- Haupttext in die linke Spalte, ergänzende Wörter in die rechte Spalte, erzeugt einen „Wechselgesang“-Eindruck;
- Lange Sätze oben platzieren (wie
MAKING EVERYBODY GO), unten nur kleine Schrift/Gleichbreit-Info; - Pro Satz nur ein „visueller Hauptdarsteller“, die restlichen Wörter klein, damit der gesamte Satz nicht zu groß für die Seiten-Spalte wird;
- Buchstabenrahmen konservativ schätzen: ASCII-Breite ≈ fs×0,66, CJK ≈ fs×1,06; 10–14px Padding lassen.
5. Checkliste zur Verifikation
- Wurden Flügelspitzen/Kopf in der Bounding Box des Satzfensters übersehen? (siehe
Analyse_Belegungsbereich.jpg) - Frame-für-Frame-Überprüfung: schlechtester Treffer = 0 (Skript druckt dies aus)
- 3–4 Frames stichprobenartig ansehen: Ist der Text randständig/beschnitten? Überlappt er Finger/Flügel?
- Nahaufnahme-/Portrait-Frames separat stichprobenartig prüfen
- Falls „weitestgehend nicht überlappend“ erlaubt ist, notieren, welche Frames Flügel überlappen (akzeptabel)
6. Bekannte Fallstricke
- Hintergrund-LOL-Lampenschilder/Lichtflecken werden durch Frame-Differenz fälschlich erkannt → Schwellwert 38 + größte zusammenhängende Region entfernt es meist; falls nicht, räumliches Vorwissen hinzufügen (Figur in der Mitte).
- Der Schatten der Figur könnte als Figur erkannt werden (BBox wird größer) → für die Ausweichung sicher (der Schatten wird gemieden), aber die Seiten-Spalte wird schmaler.
- Der Filter
MaxFilterauf 640×270 entspricht ≈ 8px Aufweitung in Vollauflösung; bei der Überprüfung kein zusätzliches Padding mehr hinzufügen. - Bei einem neuen Video/neuer Kameraposition: alle Bounds müssen neu berechnet werden, Zahlen aus alten Szenen sind nicht wiederverwendbar.