基于Python实现图像中黄红两色重叠椭圆的检测与参数提取技术问询
Detecting Overlapping Yellow-Red Ellipses and Extracting Their Parameters with OpenCV
Great start with your segmentation code! To get the exact ellipse parameters (center, axes lengths, rotation angle), we'll build on your existing work by expanding the color mask to include red and using OpenCV's cv2.fitEllipse() function—perfect for extracting precise ellipse data.
Step-by-Step Solution
1. Expand the Color Mask
Your current mask only captures yellow; since your ellipses are yellow-red, we need to add HSV ranges for red (which has two separate ranges in HSV due to the color wheel wrap-around).
2. Filter Noise and Fit Ellipses
We'll filter out small contours to avoid noise, then use cv2.fitEllipse() on valid contours. This function returns a tuple containing:
- Center coordinates
(x, y) - Axes lengths
(major_axis, minor_axis) - Rotation angle (in degrees, relative to the horizontal axis)
Full Modified Code
import numpy as np import cv2 # Load image image = cv2.imread('SamplePaintImage.png') original = image.copy() # Convert to HSV color space hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) # Define HSV ranges for yellow and red # Yellow range lower_yellow = np.array([22, 93, 0], dtype="uint8") upper_yellow = np.array([45, 255, 255], dtype="uint8") mask_yellow = cv2.inRange(hsv, lower_yellow, upper_yellow) # Red ranges (two parts due to HSV color wheel wrap) lower_red1 = np.array([0, 93, 0], dtype="uint8") upper_red1 = np.array([10, 255, 255], dtype="uint8") mask_red1 = cv2.inRange(hsv, lower_red1, upper_red1) lower_red2 = np.array([170, 93, 0], dtype="uint8") upper_red2 = np.array([180, 255, 255], dtype="uint8") mask_red2 = cv2.inRange(hsv, lower_red2, upper_red2) # Combine red masks and then combine with yellow mask mask_red = cv2.bitwise_or(mask_red1, mask_red2) mask = cv2.bitwise_or(mask_yellow, mask_red) # Find contours from combined mask cnts = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cnts = cnts[0] if len(cnts) == 2 else cnts[1] # List to store ellipse information ellipse_details = [] # Process each contour for idx, contour in enumerate(cnts): # Skip small contours (adjust threshold based on your image size) contour_area = cv2.contourArea(contour) if contour_area < 100: continue # Fit ellipse (requires at least 5 contour points) if len(contour) >= 5: ellipse = cv2.fitEllipse(contour) center_x, center_y = int(ellipse[0][0]), int(ellipse[0][1]) width, height = int(ellipse[1][0]), int(ellipse[1][1]) rotation_angle = ellipse[2] # Store details ellipse_details.append({ "id": idx + 1, "center_x": center_x, "center_y": center_y, "width": width, "height": height, "rotation_angle": round(rotation_angle, 2) }) # Draw ellipse and label on original image cv2.ellipse(original, ellipse, (0, 255, 0), 2) cv2.putText(original, f"E{idx+1}", (center_x - 20, center_y + 10), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2) # Print ellipse details print("Detected Ellipse Parameters:") for detail in ellipse_details: print(f"\nEllipse {detail['id']}:") print(f" Center: ({detail['center_x']}, {detail['center_y']})") print(f" Width: {detail['width']}") print(f" Height: {detail['height']}") print(f" Rotation Angle: {detail['rotation_angle']}°") # Display results cv2.imshow('Combined Color Mask', mask) cv2.imshow('Detected Ellipses', original) cv2.waitKey(0) cv2.destroyAllWindows()
Key Notes:
- Color Range Adjustment: If your yellow/red shades differ, tweak the HSV lower/upper bounds (use an HSV color picker tool to get precise values).
- Noise Filtering: The
contour_area < 100threshold filters tiny noise contours—adjust this based on your image's scale. - Ellipse Validity:
cv2.fitEllipse()requires at least 5 contour points, so we add a check to avoid errors.
Example Output:
Detected Ellipse Parameters: Ellipse 1: Center: (150, 200) Width: 80 Height: 40 Rotation Angle: 35.2° Ellipse 2: Center: (250, 180) Width: 60 Height: 75 Rotation Angle: 120.5°
内容的提问来源于stack exchange,提问作者vishal sowrirajan
相关产品推荐
相关产品推荐

