Real-time person detection & zone intrusion alert system built on Jetson Nano. Draw any polygon zone on the live stream — get an alert the moment a person enters it. YOLOv5n · SAM polygon · Flask MJPEG.
nanocamera opens the CSI camera at 640×480 @ 30fps.
Each frame is read in the gen_frames() generator loop,
resized, and passed directly into YOLOv5 for inference. No intermediate buffering — latency stays minimal.
.engine (TensorRT) file is loaded for maximum GPU utilization on Nano.
model.classes = [0] restricts detections to person only.
Output results.xyxy[0] gives bounding box corners + confidence per detection.
<canvas> overlaid perfectly on the live
<img> MJPEG feed. Each click adds a vertex to the polygon.
Pressing Set Polygon POSTs the coordinate array to
/set_polygon, which updates the server-side
drawing_points list and sets polygon_defined = True.
(cx, cy) = ((x1+x2)//2, (y1+y2)//2)
is tested against the polygon using
cv2.pointPolygonTest(polygon_np, (cx,cy), False) >= 0.
Returns positive if inside, negative if outside — O(n vertices) complexity.
time.time() - last_play_time > cooldown (3s)
before triggering. This prevents alert flooding from a stationary person.
alert_count is incremented and drawn live on the frame.
cv2.imencode('.jpg', frame)
and yielded as a
multipart/x-mixed-replace
HTTP response. The browser's native <img> tag handles the stream — no WebSocket, no JS decode loop needed.
Flask-CORS is enabled for cross-origin frontend access.
.engine file via TensorRT. Full GPU acceleration on Jetson Nano's Maxwell architecture. Filters to class 0 (person) only — no wasted inference on other objects.POST /set_polygon.cv2.pointPolygonTest to test each detected person's bounding box center against the defined polygon. Runs server-side per detection per frame. Handles concave polygons correctly.alert_count is rendered directly onto each frame using cv2.putText.multipart/x-mixed-replace response. Standard browser <img> tag handles the stream natively — no WebSocket, no frontend decode loop, no dependencies.drawing_points, polygon_defined, alert_count) is shared between the Flask request thread (/set_polygon) and the streaming generator. Flask-CORS handles cross-origin preflight.