Dotfiles/desktopenvs/hyprlua/scripts/python/presence_detect.py

49 lines
1.5 KiB
Python
Executable File

#!/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))