Motion detect fraction small area of frame
This commit is contained in:
1 parent
9d9d5f903c
commit
ff87201a76
2 files changed
+30
-6
No files matched your search
+13
-4
@@ -138,11 +138,20 @@ CROSS_SNAPSHOT_CLEANUP_SEC=60
|
||||
|
||||
# --- Rate / performance ---
|
||||
# Enable motion detection pre-filter: skip inference on frames with no movement
|
||||
# (true/false, default: false). When enabled, frames below MOTION_THRESHOLD are
|
||||
# skipped, saving NPU/CPU load.
|
||||
# (true/false, default: false), saving NPU/CPU load. Motion is measured by the
|
||||
# fraction of pixels that changed (localized-motion aware), NOT the whole-frame
|
||||
# average, so an object entering the edge of the frame is detected immediately.
|
||||
MOTION_DETECTION_ENABLED=false
|
||||
# Mean absolute pixel difference threshold (0–255) to consider a frame as having
|
||||
# motion. Lower = more sensitive. Default 5.0.
|
||||
# Per-pixel intensity change (0-255) for a pixel to count as "moved". Lower = more
|
||||
# sensitive to subtle movement. Default 25.
|
||||
MOTION_PIXEL_DELTA=25
|
||||
# Fraction of frame pixels (0-1) that must change to trigger inference. Lower =
|
||||
# more sensitive / detects smaller or farther objects sooner. Default 0.002 (0.2%).
|
||||
MOTION_MIN_AREA_FRAC=0.002
|
||||
# Heartbeat: always run inference at least every N frames even with no detected
|
||||
# motion, so a slow or barely-moving object is never missed for long. Default 15.
|
||||
MOTION_HEARTBEAT_FRAMES=15
|
||||
# (Deprecated) old whole-frame mean-difference threshold; no longer used.
|
||||
MOTION_THRESHOLD=5.0
|
||||
# Sliding window in seconds for computing the crossing rate (objects/minute)
|
||||
RATE_WINDOW_SEC=60
|
||||
|
||||
+17
-2
@@ -111,6 +111,14 @@ IS_LIVE = SOURCE.lower().startswith(("rtsp://", "http://"))
|
||||
|
||||
MOTION_DETECTION_ENABLED = os.getenv("MOTION_DETECTION_ENABLED", "false").lower() == "true"
|
||||
MOTION_THRESHOLD = float(os.getenv("MOTION_THRESHOLD", "5.0"))
|
||||
# Per-pixel intensity change (0-255) for a pixel to count as "moved".
|
||||
MOTION_PIXEL_DELTA = int(os.getenv("MOTION_PIXEL_DELTA", "25"))
|
||||
# Fraction of frame pixels that must change (0-1) to trigger inference. Small,
|
||||
# so an object entering the edge of the frame is detected immediately.
|
||||
MOTION_MIN_AREA_FRAC = float(os.getenv("MOTION_MIN_AREA_FRAC", "0.002"))
|
||||
# Always run inference at least every N frames even if no motion (heartbeat), so a
|
||||
# slow/stationary object is never missed for long.
|
||||
MOTION_HEARTBEAT_FRAMES = int(os.getenv("MOTION_HEARTBEAT_FRAMES", "15"))
|
||||
|
||||
CROSS_FLASH_FRAMES = 12
|
||||
POPUP_LIFETIME = 20
|
||||
@@ -1078,6 +1086,7 @@ def run():
|
||||
frame_idx = 0
|
||||
inf_ms = 0.0
|
||||
prev_gray = None
|
||||
frames_since_infer = 0
|
||||
video_writer = None
|
||||
crossing_times = deque()
|
||||
counter_in = 0
|
||||
@@ -1138,15 +1147,21 @@ def run():
|
||||
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
|
||||
if prev_gray is not None:
|
||||
diff = cv2.absdiff(gray, prev_gray)
|
||||
mean_diff = cv2.mean(diff)[0]
|
||||
skip_inference = mean_diff < MOTION_THRESHOLD
|
||||
moved = int(np.count_nonzero(diff > MOTION_PIXEL_DELTA))
|
||||
moved_frac = moved / diff.size
|
||||
skip_inference = moved_frac < MOTION_MIN_AREA_FRAC
|
||||
if frames_since_infer >= MOTION_HEARTBEAT_FRAMES:
|
||||
skip_inference = False
|
||||
prev_gray = gray
|
||||
|
||||
detections = []
|
||||
if not skip_inference:
|
||||
frames_since_infer = 0
|
||||
inf_start = time.time()
|
||||
detections = model(frame)
|
||||
inf_ms = inf_ms * 0.9 + (time.time() - inf_start) * 1000 * 0.1
|
||||
else:
|
||||
frames_since_infer += 1
|
||||
|
||||
object_boxes_xyxy = []
|
||||
object_scores = []
|
||||
|
||||
Reference in new issue
Block a user