Mask timecode in phase refine and guard cutter scene starts
This commit is contained in:
+1
-1
File diff suppressed because one or more lines are too long
+4
-3
@@ -170,9 +170,10 @@ 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.
|
||||
Report-Clips werden zusätzlich an den bekannten Source-Szenenstart geklemmt,
|
||||
damit ein knapp vor der Schnittkante liegender Inpoint nicht mit Frames der
|
||||
vorherigen Einstellung beginnt.
|
||||
Report-Clips werden zusätzlich an den bekannten Source-Szenenstart plus eine
|
||||
kurze Guard-Zone geklemmt, damit ein knapp vor oder direkt auf der Schnittkante
|
||||
liegender Inpoint nicht mit Frames der vorherigen Einstellung oder einer zu
|
||||
frühen Übergangsphase beginnt.
|
||||
|
||||
## Multi-Shot-Beats
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
@@ -120,6 +120,7 @@ STILL_WIDTH = 480
|
||||
STILL_QUALITY = 4
|
||||
CLIP_WIDTH = 480
|
||||
CLIP_MAX_DURATION_S = 30.0
|
||||
SCENE_START_GUARD_S = 0.32
|
||||
# Each half of the side-by-side compare strip
|
||||
COMPARE_HALF_W = 480
|
||||
COMPARE_H = 270 # 16:9
|
||||
@@ -423,18 +424,26 @@ def collect_rows(
|
||||
num_segs = len(segs)
|
||||
if scenes_by_id:
|
||||
rec_scene = scenes_by_id.get(int(rec.get("scene_id", -1)))
|
||||
if rec_scene and float(rec["in_point_s"]) < float(rec_scene["start_s"]):
|
||||
shift = float(rec_scene["start_s"]) - float(rec["in_point_s"])
|
||||
if rec_scene and float(rec["in_point_s"]) < float(rec_scene["start_s"]) + SCENE_START_GUARD_S:
|
||||
guarded_start = min(
|
||||
float(rec_scene["end_s"]) - 0.04,
|
||||
float(rec_scene["start_s"]) + SCENE_START_GUARD_S,
|
||||
)
|
||||
shift = guarded_start - float(rec["in_point_s"])
|
||||
rec = dict(rec)
|
||||
rec["in_point_s"] = float(rec_scene["start_s"])
|
||||
rec["in_point_s"] = guarded_start
|
||||
rec["out_point_s"] = max(float(rec["in_point_s"]) + 0.04, float(rec["out_point_s"]) + shift)
|
||||
fixed_segs = []
|
||||
for seg in segs:
|
||||
fixed = dict(seg)
|
||||
seg_scene = scenes_by_id.get(int(fixed.get("scene_id", -1)))
|
||||
if seg_scene and float(fixed["in_point_s"]) < float(seg_scene["start_s"]):
|
||||
shift = float(seg_scene["start_s"]) - float(fixed["in_point_s"])
|
||||
fixed["in_point_s"] = float(seg_scene["start_s"])
|
||||
if seg_scene and float(fixed["in_point_s"]) < float(seg_scene["start_s"]) + SCENE_START_GUARD_S:
|
||||
guarded_start = min(
|
||||
float(seg_scene["end_s"]) - 0.04,
|
||||
float(seg_scene["start_s"]) + SCENE_START_GUARD_S,
|
||||
)
|
||||
shift = guarded_start - float(fixed["in_point_s"])
|
||||
fixed["in_point_s"] = guarded_start
|
||||
fixed["out_point_s"] = max(float(fixed["in_point_s"]) + 0.04, float(fixed["out_point_s"]) + shift)
|
||||
fixed_segs.append(fixed)
|
||||
segs = fixed_segs
|
||||
|
||||
@@ -206,7 +206,12 @@ def _hires_phase_feature(frame: np.ndarray) -> np.ndarray:
|
||||
with an 8×8 spatial histogram grid provides enough spatial resolution to
|
||||
discriminate facial expression phases within a single continuous scene.
|
||||
"""
|
||||
trimmed = _trim_dark_borders(frame)
|
||||
trimmed = _trim_dark_borders(frame).copy()
|
||||
h0, w0 = trimmed.shape[:2]
|
||||
# Source and trailer masters often contain burned-in timecode in the
|
||||
# upper-left corner. It changes every frame and can dominate fine phase
|
||||
# matching, so neutralise that area before extracting hi-res features.
|
||||
trimmed[: int(h0 * 0.16), : int(w0 * 0.28)] = 0
|
||||
h, w = trimmed.shape[:2]
|
||||
cropped = trimmed[int(h * 0.05):int(h * 0.95), :]
|
||||
gray = cv2.cvtColor(cropped, cv2.COLOR_BGR2GRAY)
|
||||
|
||||
Reference in New Issue
Block a user