From 04f9529c999e3f2dcdb4b5eb87b1f648a0b65c9b Mon Sep 17 00:00:00 2001 From: dev01 Date: Thu, 4 Jun 2026 18:11:49 +0800 Subject: [PATCH] perf: optimize rectangle detection algorithm - Check only first child contour instead of iterating all siblings - Add area threshold check on inner contour - Require inner contour to be rectangular with no deeper nesting --- .../algorithm_pkg/vision_node.py | 36 ++++++++++--------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/workspace/src/algorithm_pkg/algorithm_pkg/vision_node.py b/workspace/src/algorithm_pkg/algorithm_pkg/vision_node.py index ed30a3a..f724d5b 100755 --- a/workspace/src/algorithm_pkg/algorithm_pkg/vision_node.py +++ b/workspace/src/algorithm_pkg/algorithm_pkg/vision_node.py @@ -160,25 +160,29 @@ class VisionNode(Node): best_inner_idx = -1 for i, cnt in enumerate(contours): area = cv2.contourArea(cnt) + # 筛选:面积必须大于阈值 if area < THRESHOLD_AREA: continue - if not _is_rect(cnt): - continue - # Require an inner rectangular child contour - child_idx = hierarchy[0][i][2] - has_inner_rect = False - while child_idx != -1: - if _is_rect(contours[child_idx]) and hierarchy[0][child_idx][2] == -1: - has_inner_rect = True - break - child_idx = hierarchy[0][child_idx][0] # next sibling - if not has_inner_rect: - continue + # 筛选:外轮廓必须是矩形 approx = cv2.approxPolyDP(cnt, 0.02 * cv2.arcLength(cnt, True), True) - if area > best_area: - best_area = area - best = approx.reshape(4, 2) - best_inner_idx = child_idx + if not (len(approx) == 4 and cv2.isContourConvex(approx)): + continue + # 筛选:必须有子轮廓 + # 取第一个子轮廓的索引 + child_idx = hierarchy[0][i][2] + # 这个子轮廓需要满足以下要求: + # 1.无平行轮廓(兄弟轮廓); + # 2.内轮廓不能有子轮廓; + # 3.内轮廓必须满足面积要求; + # 4.内轮廓必须是矩形; + if hierarchy[0][child_idx][0] == -1\ + and hierarchy[0][child_idx][2] == -1\ + and cv2.contourArea(contours[child_idx]) > THRESHOLD_AREA\ + and _is_rect(contours[child_idx]): + if area > best_area: + best_area = area + best = approx.reshape(4, 2) + best_inner_idx = child_idx # Draw all contours on closed for debugging vis = cv2.cvtColor(closed, cv2.COLOR_GRAY2BGR)