Shape Detection and Edge Analysis with OpenCV
Contour Extraction
findContours retrieves pixel edge points grouped into contour arrays by calculating image gradient variations.
edge_groups, hierarchy = cv2.findContours(binary_frame, mode, approximation)
Parameters
binary_frame: Input 8-bit single-channel binary image. Convert color images to grayscale and apply binarization first.mode: Contour retrieval modeMode Value Description cv2.RETR_EXTERNAL Only detect outermost contours cv2.RETR_LIST Detect all contours without hierarchy relationships cv2.RETR_CCOMP Detect all contours and build a two-level hierarchy cv2.RETR_TREE Detect all contours and build a tree-structured hierarchy approximation: Contour point approximation methodMethod Value Description cv2.CHAIN_APPROX_NONE Store every contour pixel point cv2.CHAIN_APPROX_SIMPLE Only store endpoints of horizontal/vertical/diagonal line segments cv2.CHAIN_APPROX_TC89_L1 Use one variant of the Teh-Chin algorithm cv2.CHAIN_APPROX_TC89_KCOS Use another variant of the Teh-Chin algorithm
Returns
edge_groups: List where each element is a NumPy array of contour pixel coordinates.hierarchy: NumPy array representing contour hierarchy relationships.
drawContours renders contours directly onto an input image.
rendered_frame = cv2.drawContours(input_frame, edge_groups, index, bgr_color, stroke_width, line_style, hierarchy, max_depth, offset)
Parameters
input_frame: Original image to draw on (supports multi-channel RGB/BGR).edge_groups: Contours list from findContours.index: Index of the contour to draw (-1 for all contours).bgr_color: Draw color in BGR format.stroke_width: Optional; brush thickness. A value of -1 fills the contour solid.line_style: Optional; line type for rendering.hierarchy: Optional; hierarchy from findContours.max_depth: Optional; maximum hierarchy level of contours to draw.offset: Optional; pixel offset to shift the rendered contours.
Returns
rendered_frame: Same asinput_framewith contours overlaid; modifications affect the original array directly.
Contour Fitting
boundingRect computes the minimal axis-aligned rectangular bounding box for a contour.
x_min, y_min, box_width, box_height = cv2.boundingRect(contour_array)
Parameters
contour_array: Single contour pixel coordinate array.
Returns
x_min, y_min: Coordinates of the top-left corner.box_width, box_height: Width and height of the minimal rectangle.
minEnclosingCircle calculates the minimal enclosing circle for a contour.
center_coords, radius_val = cv2.minEnclosingCircle(contour_points)
Parameters
contour_points: Single contour pixel coordinate array.
Returns
center_coords: Tuple of floating-point values representing circle center (x, y).radius_val: Floating-point minimal circle radius.
Convex Hull Calculation
convexHull identifies the smallest convex polygon that encloses all points in a contour.
convex_polygon = cv2.convexHull(contour_array, clockwise_order, return_xy)
Parameters
contour_array: Single contour pixel coordinate array.clockwise_order: Optional; boolean. If True, convex polygon points are sorted clockwise; False for counterclockwise.return_xy: Optional; boolean. If True, returns pixel coordinates; False returns point indices within the contour. Defaults to True.
Returns
convex_polygon: NumPy array of convex polygon pixel coordinates.
Canny Edge Detection
Canny detects fine-grained, continuous edges using gradient thresholding and non-maximum suppression.
edge_mask = cv2.Canny(input_img, low_threshold, high_threshold, sobel_aperture, use_L2_gradient)
Parameters
input_img: Original grayscale or color image.low_threshold: First threshold for gradient hysteresis, typical the lower value.high_threshold: Second threshold for gradient hysteresis, typically the higher value.sobel_aperture: Optional; Sobel operator kernel size (must be odd, default 3).use_L2_gradient: Optional; boolean. If True, uses the more accurate L2 norm for gradient magnitude calculation; False uses L1.
Returns
edge_mask: Binary edge image.
Adjusting low_threshold and high_threshold controls edge detail. Lower values capture more fine edges, while higher values filter out minor variations.
Hough Transform for Shape Detection
Line Detection (HoughLinesP for Line Segments)
HoughLinesP identifies finite-length line segments using accumulator-based voting.
line_segments = cv2.HoughLinesP(edge_input, rho_step, theta_step, vote_threshold, min_length, max_gap)
Parameters
edge_input: Binary edge image (e.g., from Canny).rho_step: Radius resolution of the accumulator grid.theta_step: Angular resolution of the accumulator grid in radians.vote_threshold: Minimum number of votes a line segment must receive to be detected.min_length: Optional; Minimum length of valid line segments.max_gap: Optional; Maximum gap between colinear pixels to treat as a single segment.
Returns
line_segments: 3D NumPy array where each segment is stored as[[[x1, y1, x2, y2]]].
Caution: Apply noise reduction (e.g., Gaussian blur) before detection to avoid false positives.
Circle Detection (HoughCircles)
HoughCircles detects circles using a two-stage accumulator voting process.
detected_circles = cv2.HoughCircles(grayscale_img, cv2.HOUGH_GRADIENT, dp_ratio, min_center_dist, canny_high, vote_count, min_rad, max_rad)
Parameters
grayscale_img: Input grayscale image.cv2.HOUGH_GRADIENT: Only available circle detection method in OpenCV ≤ 4.0.0.dp_ratio: Inverse ratio of accumulator resolution to image resolution.min_center_dist: Minimum distance between detected circle centers.canny_high: Optional; High threshold for Canny edge detection.vote_count: Opptional; Minimum number of votes a candidate circle must receive in the first voting stage.min_rad: Optional; Minimum radius of valid circles.max_rad: Optional; Maximum radius of valid circles.
Returns
detected_circles: 3D NumPy array where each circle is stored as[[[x, y, r]]].
The Canny edge mask used as an intermediate step may contain discontinuous edges.