如何在OpenCV中仅检测位于其他轮廓内部的轮廓?
检测图像内部4个正方形轮廓的实现方案
核心思路
通过轮廓的层级结构区分内外轮廓:外层正方形会包含子轮廓,而你需要的内部正方形没有子轮廓,结合形状特征筛选即可。
具体操作(以OpenCV Python为例)
图像预处理
- 转灰度图:
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) - 二值化(根据图像明暗调整阈值,这里用反相二值化适配深色轮廓):
ret, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY_INV) - 可选:用形态学开运算去噪点:
binary = cv2.morphologyEx(binary, cv2.MORPH_OPEN, np.ones((3,3), np.uint8))
- 转灰度图:
提取轮廓与层级信息
- 用
RETR_TREE模式获取完整层级,每个轮廓的层级数据是[next, prev, child, parent],其中child=-1表示该轮廓没有子轮廓:contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
- 用
筛选目标轮廓
- 遍历轮廓,同时满足三个条件:是四边形、无子女轮廓、长宽比接近1(正方形):
target_contours = [] for cnt, hier in zip(contours, hierarchy[0]): # 多边形近似,减少轮廓点数 epsilon = 0.04 * cv2.arcLength(cnt, True) approx = cv2.approxPolyDP(cnt, epsilon, True) # 判断四边形+无子女轮廓+正方形比例 if len(approx) == 4 and hier[2] == -1: x, y, w, h = cv2.boundingRect(cnt) if 0.9 < w/h < 1.1: target_contours.append(cnt)
- 遍历轮廓,同时满足三个条件:是四边形、无子女轮廓、长宽比接近1(正方形):
验证结果
- 绘制筛选出的轮廓:
cv2.drawContours(img, target_contours, -1, (0,255,0), 2) - 查看效果:
cv2.imshow("Inner Squares", img); cv2.waitKey(0)
- 绘制筛选出的轮廓:
注意事项
- 阈值、近似系数
epsilon和面积阈值(如果需要)要根据你的实际图像微调,确保精准识别 - 如果有其他小干扰轮廓,可以加个面积判断:比如
cv2.contourArea(cnt) > min_area过滤掉太小的轮廓
内容的提问来源于stack exchange,提问作者Tom Blums
相关产品推荐
相关产品推荐

