基于OpenCV矩检测白色物体,实现区域停留5秒触发不同操作需求
Solution for Timer-Based Action Trigger in OpenCV Object Detection
Got it, let's work through this problem step by step. The core idea is to track how long the white object stays in a specific zone, trigger actions only after a 5-second delay, and reset everything when the object disappears. Here's a complete implementation that builds on your existing code:
Full Code Implementation
import cv2 import time # Initialize timer state variables start_time = None current_zone = None # Can be 'upper', 'lower', or None action_triggered = False # Prevent repeated triggers after first activation cap = cv2.VideoCapture(0) cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480) def upper_zone_action(): """Define your action for upper zone here""" print("Object stayed in upper zone for 5 seconds! Executing upper action...") # Add your actual operation here (e.g., send signal, control device) def lower_zone_action(): """Define your action for lower zone here""" print("Object stayed in lower zone for 5 seconds! Executing lower action...") # Add your actual operation here while True: ret, frame = cap.read() if not ret: break # --- Your existing white object detection code --- # Convert to HSV for better color filtering (adjust ranges as needed) hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) lower_white = (0, 0, 200) upper_white = (180, 25, 255) mask = cv2.inRange(hsv, lower_white, upper_white) contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) moments = None if contours: largest_contour = max(contours, key=cv2.contourArea) moments = cv2.moments(largest_contour) # --- Timer and action logic --- if moments and moments['m00'] > 0: x = int(moments['m10'] / moments['m00']) y = int(moments['m01'] / moments['m00']) # Determine current zone if 0 < x <= 640 and 0 < y <= 240: zone = 'upper' elif 0 < x <= 640 and 240 < y <= 480: zone = 'lower' else: zone = None # Object is outside valid frame area if zone: # First time detecting object in this zone if current_zone != zone: start_time = time.time() current_zone = zone action_triggered = False # Reset trigger flag when zone changes # Check if 5 seconds have passed elapsed_time = time.time() - start_time if elapsed_time >= 5 and not action_triggered: if zone == 'upper': upper_zone_action() else: lower_zone_action() action_triggered = True # Prevent repeated triggers # Draw debug info (optional) cv2.circle(frame, (x, y), 5, (0, 255, 0), -1) cv2.putText(frame, f"Zone: {zone}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2) else: # No object detected: reset all timer states start_time = None current_zone = None action_triggered = False cv2.putText(frame, "No object detected", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2) cv2.imshow('Frame', frame) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows()
Key Details Explained
- State Tracking: We use
start_time,current_zone, andaction_triggeredto keep track of when the object entered a zone, which zone it's in, and whether we've already triggered the action for that zone. - Zone Detection: We explicitly check if the object's centroid is within valid frame bounds (0 < x ≤640, 0 < y ≤480) before assigning a zone.
- Timer Logic: When the object enters a new zone, we reset the start time. If it stays in the same zone for 5 seconds and we haven't triggered the action yet, we run the corresponding function.
- Reset on Loss of Detection: As soon as no object is detected, we reset all state variables to prevent false triggers from leftover timer values.
- Debug Visualization: Optional circles and text help you verify the centroid position and zone status in real-time.
Customization Tips
- Adjust the HSV ranges for
lower_whiteandupper_whiteto match your specific white object's color (lighting conditions can affect this). - Replace the
upper_zone_action()andlower_zone_action()functions with your actual operations (e.g., controlling a motor, sending a network request). - If you want to re-trigger the action after the first trigger (e.g., if the object stays in the zone for another 5 seconds), remove the
action_triggeredflag and logic.
内容的提问来源于stack exchange,提问作者Luisito




