Constrain hi-res phase refine and update beat 14
This commit is contained in:
+1
-1
File diff suppressed because one or more lines are too long
@@ -166,6 +166,11 @@ eine kurze Geste erst korrekt erkannt und anschließend in eine spätere
|
||||
derselben Source-Szene ähnlich gut scoren und die Beat-Dauer abdecken,
|
||||
bevorzugt der Matcher die frühere Phase.
|
||||
|
||||
Der zusätzliche Hi-Res-Phasenrefine bleibt lokal um den bereits validierten
|
||||
Inpoint und übernimmt nur klare Verbesserungen. Er darf keine ganze lange
|
||||
Dialogszene nach ähnlichen Layouts durchsuchen, weil sonst dieselbe Location
|
||||
mit anderer Gestik als falsche Phase gewinnen kann und die Laufzeit explodiert.
|
||||
|
||||
## Multi-Shot-Beats
|
||||
|
||||
Enthält ein Trailerbeat selbst einen harten Umschnitt, werden Kandidaten an
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 21 KiB |
+24
-4
@@ -316,14 +316,31 @@ def _hires_phase_refine(
|
||||
scan_templates = [(off, feat, sp) for off, feat, sp, _ in ref_templates]
|
||||
max_ref_offset = max(off for off, _, _ in scan_templates)
|
||||
|
||||
# Scan the full scene
|
||||
# Scan only a local window around the already validated in-point. A full
|
||||
# scene scan can jump to a different phase of the same shot (same room,
|
||||
# same actor, different gesture) and it is unnecessarily expensive.
|
||||
local_window_s = max(0.8, min(2.0, cfg.cv.deep_scan.content_align_window_seconds * 3.0))
|
||||
scan_start_s = max(scene_start_s, in_point_s - local_window_s)
|
||||
scan_end_s = min(scene_end_s, in_point_s + local_window_s)
|
||||
|
||||
original_scores: list[float] = []
|
||||
with open_video(cfg.paths.source_movie) as cap:
|
||||
for off, ref_feat, ref_spatial in scan_templates:
|
||||
src_frame = grab_frame_at(cap, in_point_s + off)
|
||||
if src_frame is not None:
|
||||
original_scores.append(_hires_phase_score(ref_feat, ref_spatial, src_frame))
|
||||
original_score = -1.0
|
||||
if original_scores:
|
||||
original_score = (sum(original_scores) / len(original_scores)) * 0.7 + min(original_scores) * 0.3
|
||||
|
||||
# Scan the local neighbourhood.
|
||||
best_t = in_point_s
|
||||
best_score = -1.0
|
||||
best_score = original_score
|
||||
scan_step_s = max(1.0 / (cfg.export.edl_frame_rate or 24.0), 0.04)
|
||||
|
||||
with open_video(cfg.paths.source_movie) as cap:
|
||||
t = scene_start_s
|
||||
while t + max_ref_offset <= scene_end_s:
|
||||
t = scan_start_s
|
||||
while t + max_ref_offset <= scan_end_s:
|
||||
scores: list[float] = []
|
||||
all_ok = True
|
||||
for off, ref_feat, ref_spatial in scan_templates:
|
||||
@@ -340,6 +357,9 @@ def _hires_phase_refine(
|
||||
best_t = t
|
||||
t = round(t + scan_step_s, 6)
|
||||
|
||||
if best_score < original_score + 0.025:
|
||||
return in_point_s
|
||||
|
||||
if best_t != in_point_s:
|
||||
logger.info(
|
||||
'Beat %d: hi-res phase refine moved in-point %.3fs -> %.3fs '
|
||||
|
||||
Reference in New Issue
Block a user