#!/usr/bin/env python3 """ Webcam motion presence detector using frame differencing. Exit codes: 0 = motion detected, 1 = no motion, 2 = camera error (busy/unavailable) Usage: presence_detect.py [camera_id] """ import sys import cv2 import numpy as np FRAMES_TO_CHECK = 6 DIFFS_NEEDED = 2 # require motion in at least N consecutive-frame diffs PIXEL_DELTA_THRESHOLD = 25 # per-pixel grayscale delta to count as "changed" MOTION_AREA_RATIO = 0.02 # fraction of pixels that must change to call it motion BLUR_KSIZE = (21, 21) # Gaussian blur kernel to suppress sensor noise def detect(camera_id: int) -> int: cap = cv2.VideoCapture(camera_id) if not cap.isOpened(): return 2 motion_diffs = 0 prev_gray = None try: for _ in range(FRAMES_TO_CHECK): ok, frame = cap.read() if not ok: continue gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) gray = cv2.GaussianBlur(gray, BLUR_KSIZE, 0) if prev_gray is not None: delta = cv2.absdiff(prev_gray, gray) changed = np.count_nonzero(delta > PIXEL_DELTA_THRESHOLD) if changed / delta.size >= MOTION_AREA_RATIO: motion_diffs += 1 prev_gray = gray finally: cap.release() return 0 if motion_diffs >= DIFFS_NEEDED else 1 if __name__ == "__main__": camera_id = int(sys.argv[1]) if len(sys.argv) > 1 else 0 sys.exit(detect(camera_id))