Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6b5b27477a |
+39
-2
@@ -119,6 +119,22 @@ def parse_arguments():
|
|||||||
"edges. 0 (default) allows cropped faces; set >0 to reject "
|
"edges. 0 (default) allows cropped faces; set >0 to reject "
|
||||||
"faces touching the crop lines.",
|
"faces touching the crop lines.",
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--probe-stride",
|
||||||
|
type=int,
|
||||||
|
default=1,
|
||||||
|
help="Within a scene still needing a face, run detection every Nth "
|
||||||
|
"frame instead of every frame (1 = original behavior, free on "
|
||||||
|
"CUDA). For slow devices (iGPU ~5s/img) use e.g. 25: decode "
|
||||||
|
"stays frame-perfect, only the expensive inference is thinned.",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--probe-max-per-scene",
|
||||||
|
type=int,
|
||||||
|
default=4,
|
||||||
|
help="With --probe-stride>1, probes before giving up on a scene and "
|
||||||
|
"waiting for the next scene start (default 4).",
|
||||||
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--scene-threshold",
|
"--scene-threshold",
|
||||||
type=float,
|
type=float,
|
||||||
@@ -272,6 +288,17 @@ def process_video(video_path, output_dir, args, model, device, draw,
|
|||||||
face_in_scene = False
|
face_in_scene = False
|
||||||
frame_idx = 0
|
frame_idx = 0
|
||||||
|
|
||||||
|
# Probe schedule. probe_stride=1 reproduces the original every-frame
|
||||||
|
# loop (right on CUDA, where predict costs ~0.2 s). On slow devices
|
||||||
|
# (iGPU ~5 s/img) predicting every frame is hopeless: decode is ~300 fps,
|
||||||
|
# inference 0.2/s. With stride>1 we decode through frames for free and
|
||||||
|
# predict only at scene starts, retrying every stride frames up to
|
||||||
|
# probe_max attempts per scene, then waiting for the next scene start.
|
||||||
|
probe_stride = getattr(args, "probe_stride", 1)
|
||||||
|
probe_max = getattr(args, "probe_max_per_scene", 4)
|
||||||
|
next_probe = 0
|
||||||
|
probes_used = 0
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
ret, frame = cap.read()
|
ret, frame = cap.read()
|
||||||
if not ret:
|
if not ret:
|
||||||
@@ -279,10 +306,20 @@ def process_video(video_path, output_dir, args, model, device, draw,
|
|||||||
|
|
||||||
if frame_idx in scene_starts:
|
if frame_idx in scene_starts:
|
||||||
face_in_scene = False
|
face_in_scene = False
|
||||||
# membership test on a set; pop matched starts to keep it cheap
|
next_probe = frame_idx
|
||||||
# (scenes strictly increase, so set stays small either way)
|
probes_used = 0
|
||||||
|
|
||||||
|
if face_in_scene:
|
||||||
|
frame_idx += 1
|
||||||
|
continue
|
||||||
|
if probe_stride > 1 and (frame_idx < next_probe
|
||||||
|
or probes_used >= probe_max):
|
||||||
|
frame_idx += 1
|
||||||
|
continue
|
||||||
|
|
||||||
if not face_in_scene:
|
if not face_in_scene:
|
||||||
|
probes_used += 1
|
||||||
|
next_probe = frame_idx + probe_stride
|
||||||
try:
|
try:
|
||||||
results = model.predict(frame, conf=args.conf,
|
results = model.predict(frame, conf=args.conf,
|
||||||
iou=args.iou, imgsz=args.imgsz,
|
iou=args.iou, imgsz=args.imgsz,
|
||||||
|
|||||||
Reference in New Issue
Block a user