求助:如何在直播视频中选取感兴趣区域(ROI)实现插队越界告警
Hey there! Let's tackle this queue-jumping detection project step by step—sounds like a practical, real-world use case for live video analysis. Since I can’t see your reference image, I’ll cover the most common interactive ROI/boundary selection workflows that align with typical queue monitoring setups, plus the cross-boundary alert logic you need.
1. Interactive ROI/Boundary Selection for Live Video
First, you’ll need a way to let users draw a boundary (polygonal or rectangular) on the live feed. Pausing the stream temporarily for selection makes this intuitive—here’s a quick OpenCV-based implementation that lets users draw a polygonal boundary (perfect for curved or irregular queue lines):
import cv2 import numpy as np # Global variables to track user's drawing roi_points = [] drawing = False boundary_confirmed = False def mouse_draw_callback(event, x, y, flags, param): global roi_points, drawing, boundary_confirmed temp_frame = param.copy() if event == cv2.EVENT_LBUTTONDOWN: # Start drawing on left click drawing = True roi_points = [(x, y)] elif event == cv2.EVENT_MOUSEMOVE and drawing: # Preview the boundary as user drags the mouse cv2.polylines(temp_frame, [np.array(roi_points + [(x, y)])], False, (0, 255, 0), 2) cv2.imshow("Select Queue Boundary", temp_frame) elif event == cv2.EVENT_LBUTTONUP: # Finalize the boundary on release drawing = False roi_points.append((x, y)) boundary_confirmed = True print("Boundary selected! Resuming live analysis...") # Initialize live stream (replace 0 with your RTSP/HTTP stream URL if needed) cap = cv2.VideoCapture(0) # Pause stream to let user select boundary ret, initial_frame = cap.read() cv2.namedWindow("Select Queue Boundary") cv2.setMouseCallback("Select Queue Boundary", mouse_draw_callback, initial_frame) # Wait until user confirms the boundary while not boundary_confirmed: cv2.imshow("Select Queue Boundary", initial_frame) if cv2.waitKey(1) & 0xFF == ord('q'): break cv2.destroyWindow("Select Queue Boundary")
2. Detecting Cross-Boundary Queue Jumps
Once the boundary is set, you’ll need to detect people and check if they cross it. Using a lightweight real-time model like YOLOv8 works perfectly here—here’s how to integrate detection and alerting:
from ultralytics import YOLO # Load pre-trained YOLOv8 model (nano version for speed) model = YOLO("yolov8n.pt") def point_crosses_boundary(point, boundary): # Ray-casting algorithm to check if a point crosses the boundary (adjust direction as needed) x, y = point n = len(boundary) inside_queue = False for i in range(n): j = (i + 1) % n xi, yi = boundary[i] xj, yj = boundary[j] # Check if point crosses the boundary line if ((yi > y) != (yj > y)) and (x < (xj - xi) * (y - yi) / (yj - yi) + xi): inside_queue = not inside_queue # Return True if point moves from non-queue side to queue side (tweak based on your setup) return inside_queue # Process live stream and monitor for queue jumps while cap.isOpened(): ret, frame = cap.read() if not ret: break # Detect only people (COCO class 0) results = model(frame, classes=0, verbose=False) for result in results: for box in result.boxes: # Get bounding box coordinates and center point x1, y1, x2, y2 = box.xyxy[0] center_x = (x1 + x2) / 2 center_y = (y1 + y2) / 2 # Check if the person's center crosses the boundary if point_crosses_boundary((center_x, center_y), roi_points): # Trigger alert: draw red box and text cv2.rectangle(frame, (int(x1), int(y1)), (int(x2), int(y2)), (0, 0, 255), 3) cv2.putText(frame, "QUEUE JUMP ALERT!", (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1.2, (0, 0, 255), 3) cv2.imshow("Queue Jump Detection", frame) if cv2.waitKey(1) & 0xFF == ord('q'): break # Cleanup cap.release() cv2.destroyAllWindows()
3. Customization for Your Reference Image
- If your reference image uses a rectangular ROI, simplify the selection logic to track just the top-left and bottom-right mouse clicks instead of multiple polygon points.
- Add object tracking (YOLOv8 has built-in tracking with
model.track()) to reduce false alarms from occlusions or quick movements. - Adjust the
point_crosses_boundaryfunction to match your queue’s direction—e.g., only trigger if the person moves from the "non-queue" side to the "queue" side, not the other way around.
Let me know if you need help tweaking this to match your exact reference image’s ROI style or troubleshooting any part of the code!
内容的提问来源于stack exchange,提问作者Nad

