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
This commit is contained in:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user