Canny边缘清晰但cv2.findContours检测轮廓破碎,无法获取大矩形外轮廓如何解决
问题原因及解决方案
问题确实和你当前使用的cv2.findContours参数直接相关,调整参数+补充少量图像处理步骤即可拿到包裹大矩形的单个闭合外轮廓,具体修改点如下:
- 轮廓检索模式替换:你当前用的
cv2.RETR_LIST会提取图像中所有独立轮廓,不区分内外层级,自然不会直接输出最外层的大矩形轮廓。把该参数替换为cv2.RETR_EXTERNAL,该参数只会返回所有轮廓的最外层结果,直接过滤掉内层的琐碎小轮廓。 - 补充边缘闭合处理:肉眼看起来连续的Canny边缘可能存在像素级的微小断裂,会导致轮廓被拆分为多段。可以在Canny检测之后、轮廓查找之前,增加一次闭运算操作,将边缘的缝隙补全,保证轮廓是闭合的。
- 轮廓筛选优化:拿到所有外轮廓后,可按轮廓面积从大到小排序,面积最大的结果就是你需要的大矩形外轮廓,无需遍历所有轮廓绘制。
cv2.CHAIN_APPROX_SIMPLE参数无需更换,该参数仅做轮廓点的压缩存储,不会影响轮廓的完整性。
修改后的核心代码片段
# [get edges] cannyIm = cv2.Canny(dilatedIm, lowThreshold, lowThreshold*cannyThresholdRatio) # 新增:闭运算补全边缘缝隙,保证轮廓闭合 close_kernel = np.ones((3,3), np.uint8) closedIm = cv2.morphologyEx(cannyIm, cv2.MORPH_CLOSE, close_kernel, iterations=2) # [FIND CONTOURS] 替换RETR_LIST为RETR_EXTERNAL cnts, hier = cv2.findContours(closedIm, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # [筛选最大轮廓] 按面积降序排序,取第一个就是大矩形外轮廓 cnts = sorted(cnts, key=cv2.contourArea, reverse=True) max_cnt = cnts[0] # [DRAW CONTOURS] 只绘制最大的外轮廓 color = (random.randint(0,255), random.randint(0,255), random.randint(0,255)) cv2.drawContours(rawIm, [max_cnt], -1, color , 6)
内容的提问来源于stack exchange,提问作者KJ Ang
相关产品推荐
相关产品推荐

