如何改进图像处理校准?添加HSV/阈值滑动条实现无人机形状检测
Got it, let's build a robust shape detection system with trackbar-based calibration tailored for your drone footage needs. Your existing code struggles with non-ideal lighting, so adding real-time HSV and threshold controls will let you fine-tune parameters on the fly. Here's a complete, optimized implementation:
import argparse import cv2 import time import datetime # Initialize global variables for trackbar values h_low, h_high = 0, 179 s_low, s_high = 0, 255 v_low, v_high = 0, 255 threshold_val = 127 # Empty callback function for trackbars (required by OpenCV) def nothing(x): pass def detect_shape(contour): # Approximate contour to simplify polygon edges peri = cv2.arcLength(contour, True) approx = cv2.approxPolyDP(contour, 0.04 * peri, True) # Classify shape based on vertex count if len(approx) == 3: return "Triangle" elif len(approx) == 4: # Distinguish square from rectangle using aspect ratio x, y, w, h = cv2.boundingRect(approx) aspect_ratio = float(w) / h if 0.95 <= aspect_ratio <= 1.05: return "Square" else: return "Rectangle" elif len(approx) > 4: return "Circle" else: return "Custom Shape" # Extend this for your specific target def main(): # Parse command line arguments for video input ap = argparse.ArgumentParser() ap.add_argument("-v", "--video", help="path to drone video file") args = vars(ap.parse_args()) # Initialize video capture: use webcam if no video path provided if args.get("video", None) is None: cap = cv2.VideoCapture(0) time.sleep(2.0) # Warm up camera else: cap = cv2.VideoCapture(args["video"]) # Create windows for trackbars and output visualization cv2.namedWindow("Trackbars", cv2.WINDOW_NORMAL) cv2.namedWindow("Original", cv2.WINDOW_NORMAL) cv2.namedWindow("Mask", cv2.WINDOW_NORMAL) # Create trackbars for HSV range and threshold calibration cv2.createTrackbar("H Low", "Trackbars", h_low, 179, nothing) cv2.createTrackbar("H High", "Trackbars", h_high, 179, nothing) cv2.createTrackbar("S Low", "Trackbars", s_low, 255, nothing) cv2.createTrackbar("S High", "Trackbars", s_high, 255, nothing) cv2.createTrackbar("V Low", "Trackbars", v_low, 255, nothing) cv2.createTrackbar("V High", "Trackbars", v_high, 255, nothing) cv2.createTrackbar("Threshold", "Trackbars", threshold_val, 255, nothing) while True: ret, frame = cap.read() if not ret: break # Exit loop if video ends # Resize frame for better visibility (adjust based on drone resolution) frame = cv2.resize(frame, (640, 480)) # Reduce noise with Gaussian blur (critical for aerial footage) blurred = cv2.GaussianBlur(frame, (5, 5), 0) # Convert to HSV color space (more lighting-resistant than RGB) hsv = cv2.cvtColor(blurred, cv2.COLOR_BGR2HSV) # Get current trackbar values h_low = cv2.getTrackbarPos("H Low", "Trackbars") h_high = cv2.getTrackbarPos("H High", "Trackbars") s_low = cv2.getTrackbarPos("S Low", "Trackbars") s_high = cv2.getTrackbarPos("S High", "Trackbars") v_low = cv2.getTrackbarPos("V Low", "Trackbars") v_high = cv2.getTrackbarPos("V High", "Trackbars") threshold_val = cv2.getTrackbarPos("Threshold", "Trackbars") # Create HSV mask and apply binary threshold lower_hsv = (h_low, s_low, v_low) upper_hsv = (h_high, s_high, v_high) mask = cv2.inRange(hsv, lower_hsv, upper_hsv) _, thresh = cv2.threshold(mask, threshold_val, 255, cv2.THRESH_BINARY) # Find contours in the processed mask contours, _ = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # Process each detected contour for c in contours: # Filter out tiny contours (adjust based on 100ft target size) area = cv2.contourArea(c) if area < 500: # Lower this if your target is smaller at 100ft continue # Identify the shape shape = detect_shape(c) # Draw contour and label on original frame M = cv2.moments(c) if M["m00"] != 0: cX = int(M["m10"] / M["m00"]) cY = int(M["m01"] / M["m00"]) cv2.drawContours(frame, [c], -1, (0, 255, 0), 2) cv2.putText(frame, shape, (cX - 50, cY), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2) # Capture timestamped image when shape is detected timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S") capture_path = f"shape_capture_{timestamp}.jpg" cv2.imwrite(capture_path, frame) print(f"Captured target: {capture_path}") # Display output windows cv2.imshow("Original", frame) cv2.imshow("Mask", thresh) # Exit on 'q' key press if cv2.waitKey(1) & 0xFF == ord('q'): break # Cleanup resources cap.release() cv2.destroyAllWindows() if __name__ == "__main__": main()
Key Features Breakdown
- Real-Time Trackbar Calibration: The
Trackbarswindow lets you tweak HSV ranges and threshold values live, so you can adapt to cloudy, sunny, or shaded conditions instantly. - Drone-Optimized Preprocessing: Gaussian blur cuts down on aerial noise, and HSV color space handles lighting shifts better than standard RGB.
- Adaptive Shape Detection: The
detect_shapefunction uses contour approximation to identify common shapes—extend it by adding vertex checks for your custom target. - Automated Image Capture: Timestamped filenames ensure you never overwrite captures, and the system saves frames only when valid shapes are detected.
- Adjustable Contour Filtering: The area threshold (
500) is set for 100ft targets—lower it if your shape is smaller, or raise it to filter out noise.
How to Use
- Run the Code: Use
python shape_detector.pyfor webcam testing, orpython shape_detector.py --video path/to/drone_footage.mp4to analyze recorded video. - Calibrate: Adjust trackbars until the
Maskwindow shows only your target shape (no background clutter). - Capture: The system automatically saves frames when shapes are detected—check your working directory for the files.
- Customize: Modify the
detect_shapefunction to add support for your specific custom shape, or tweak the contour area threshold for your target size.
Troubleshooting Tips
- Small Targets: If your shape is hard to detect at 100ft, reduce the
area < 500threshold or increase the video resolution. - Flickering Mask: Widen the HSV ranges slightly or add a morphological operation like
cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, (3,3))to clean up noise. - Jittery Contours: Add a frame buffer to average contour positions over time, or use
cv2.boundingRectto track the target more smoothly.
内容的提问来源于stack exchange,提问作者Andromedan
相关产品推荐
相关产品推荐

