with open("zones.json") as f: config = json.load(f)
def main(): cap = cv2.VideoCapture(0) bg_subtractor = cv2.createBackgroundSubtractorMOG2() webcam zone trigger
while True: ret, frame = cap.read() if not ret: break height, width = frame.shape[:2] fgmask = bg_subtractor.apply(frame) fgmask = cv2.medianBlur(fgmask, 5) contours, _ = cv2.findContours(fgmask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) active_zones = set() for cnt in contours: if cv2.contourArea(cnt) < 500: continue # min area M = cv2.moments(cnt) if M["m00"] == 0: continue cx = int(M["m10"] / M["m00"]) cy = int(M["m01"] / M["m00"]) for zone in zones: if point_in_polygon(cx, cy, zone["polygon"]): active_zones.add(zone["id"]) for zone in zones: triggered = zone["id"] in active_zones if triggered and not zone["occupied"]: print(f"TRIGGER ENTER: zone['id']") # Send signal (e.g., MQTT, GPIO, HTTP POST) elif not triggered and zone["occupied"]: print(f"TRIGGER EXIT: zone['id']") zone["occupied"] = triggered # Visual feedback: draw zones and centroids for zone in zones: color = (0,255,0) if zone["occupied"] else (0,0,255) cv2.polylines(frame, [zone["polygon"]], True, color, 2) cv2.imshow("Zone Trigger", frame) if cv2.waitKey(1) & 0xFF == ord('q'): break with open("zones
"zones": [ "id": "entrance", "type": "polygon", "points": [[0.4,0.2], [0.6,0.2], [0.7,0.8], [0.3,0.8]], "trigger_on": "enter" ] _ = cv2.findContours(fgmask
zones = [] for z in config["zones"]: pts = np.array([[int(p[0]*width), int(p[1]*height)] for p in z["points"]], np.int32) zones.append("id": z["id"], "polygon": pts, "occupied": False)