基于OpenCV的含噪声干扰图像矩形检测问题咨询
重叠遮挡场景下矩形检测问题排查
请问当图像中的矩形与噪声线条、其他形状存在接触重叠时,是否可以成功检测到该矩形?
现有代码
轮廓检测函数
def findContours(img_in): w, h, c = img_in.shape # img_in is the input image resize_coeff = 0.25 img_in = cv2.resize(img_in,(int(resize_coeff * h), int(resize_coeff * w))) img_in = ip.findObjects(img_in) blr = cv2.GaussianBlur(img_in, (9, 9), 0) img = cv2.Canny(blr, 50, 250, L2gradient=False) kernel = np.ones((5, 5), np.uint8) img_dilate = cv2.dilate(img, kernel, iterations=1) img = cv2.erode(img_dilate, kernel, iterations=1) contours, hierarchy = cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) max_index, max_area = max(enumerate([cv2.contourArea(x) for x in contours]), key=lambda x: x[1]) max_contour = contours[max_index] img_out = cv2.resize(img, (int(resize_coeff * h), int(resize_coeff * w))) cv2.drawContours(img_in, [max_contour], 0, (0, 0, 255), 2) re.rectangle(img, [max_contour]) cv2.imshow("test",img_in) cv2.imshow("test1",img) cv2.waitKey() return img
矩形形状检测函数
def rectangle(img, contours): for contour in contours: approx = cv2.approxPolyDP(contour, 0.01 * cv2.arcLength(contour, True), True) print(len(approx)) x = approx.ravel()[0] y = approx.ravel()[1] - 5 if len(approx) == 4: print("Rect") x, y, w, h = cv2.boundingRect(approx) aspectRatio = float(w) / h print(aspectRatio) cv2.putText(img, "rectangle", (x, y), cv2.FONT_HERSHEY_COMPLEX, 0.5, (0, 0, 0))
问题现象
- 实际检测结果:提取到的轮廓拟合后得到15个顶点,无法识别为矩形
- 预期结果:正确提取到与噪声线条重叠的目标矩形
- 原始输入为带交叉噪声线条的矩形图像
问题定位
- 轮廓提取逻辑缺陷:重叠的噪声线条和目标矩形会被识别为同一个连通域,直接取最大面积轮廓会将噪声形变也带入后续判断,导致轮廓自带大量毛刺凹凸点
- 多边形拟合参数过严:当前
approxPolyDP的epsilon参数取0.01倍轮廓周长,精度过高会把轮廓上的微小毛刺都识别为独立顶点,最终输出15个角的异常结果 - 形态学操作适配性差:当前的开闭运算参数无法消除重叠带来的轮廓毛刺,也无法拆分粘连的连通域
可行解决方法
- 调整多边形拟合参数:将epsilon调整为0.05~0.1倍的轮廓周长,允许拟合时忽略小的毛刺形变,大概率可得到4个顶点的矩形拟合结果
- 优化轮廓筛选逻辑:不要直接取最大面积轮廓,可结合目标矩形的长宽比、面积范围等先验信息过滤,也可直接使用轮廓的最小外接矩形代替原始轮廓做形状判断
- 调整形态学操作:可尝试先做闭运算再做开运算,也可使用距离变换+分水岭算法拆分重叠连通域,分离目标矩形和噪声线条
- 替换检测前置逻辑:如果目标矩形的颜色、灰度特征稳定,可先做颜色/阈值分割再提取轮廓,从根源降低重叠干扰
内容的提问来源于stack exchange,提问作者jan
相关产品推荐
相关产品推荐

