如何对霍夫变换检测到的邻近直线求平均以提取正确的门矩形?
门检测相关问题
我需要从图像中检测符合门的面积、长宽比条件的合适矩形来识别门。我首先使用Canny边缘检测提取边缘,再通过霍夫变换提取边缘对应的直线,得到的结果如下图所示:
目前我已经能提取出满足“门条件”的矩形对应的直线,但如图所示,大量邻近直线会生成多个符合条件的矩形。我希望将邻近直线替换为它们的平均直线来减少直线数量,但实现逻辑复杂度太高,我尝试编写了如下代码:
def segregateLines(tobesegLines): while True: noLinesLeft = True for i in range(0 , len(tobesegLines)): closeLineFound = False for j in range(0, len(tobesegLines)): if abs(tobesegLines[i][0][0] - tobesegLines[j][0][0]) < 50: closeLineFound = True noLinesLeft = False newLines.append([[(abs(tobesegLines[i][0][0] +tobesegLines[j][0][0])) /2, tobesegLines[i][0][1]]]) if not closeLineFound: newLines.append(tobesegLines[i]) if noLinesLeft: break segregateLines(newLines) return newLines
但运行时出现了内存错误。请问有没有在Python中实现邻近直线求平均的方案?或者有没有其他从直线中提取正确矩形来识别门的思路?
补充说明
- 我已获取每条直线到原点的距离rho,且已将直线区分为近似水平和近似垂直两类。
解决方案
现有代码内存报错原因
- 未在每次循环/递归入口初始化
newLines变量,全局共用同一个列表不断追加内容,导致内存占用无限膨胀 - 逻辑存在重复合并问题:i和j遍历所有两两组合,同组直线会被重复计算无数次,递归逻辑错误
- 缺失被合并直线的删除逻辑:合并后没有移除原有两条直线,反而新增了更多直线,导致直线数量越合并越多
邻近直线合并实现方案
因为你已经把直线区分为近似水平、近似垂直两类,两类的rho参数物理意义独立,可以分开处理,用排序后贪心合并的方案就能高效解决问题,复杂度仅为O(nlogn),不会出现内存溢出问题:
def merge_near_lines(lines, rho_threshold=50): # 按rho值从小到大排序 lines_sorted = sorted(lines, key=lambda x: x[0][0]) merged_groups = [] for line in lines_sorted: if not merged_groups: merged_groups.append([line]) continue # 和最后一个分组的rho差值小于阈值就归为同一组 last_group = merged_groups[-1] if abs(line[0][0] - last_group[0][0][0]) < rho_threshold: last_group.append(line) else: merged_groups.append([line]) # 对每个分组的直线求平均rho和平均theta,生成合并后的直线 merged_lines = [] for group in merged_groups: avg_rho = sum(l[0][0] for l in group) / len(group) avg_theta = sum(l[0][1] for l in group) / len(group) merged_lines.append([[avg_rho, avg_theta]]) return merged_lines
使用方式如下:
# 分别处理垂直、水平两类直线,两类的阈值可以根据场景调整 merged_vertical = merge_near_lines(vertical_lines, rho_threshold=50) merged_horizontal = merge_near_lines(horizontal_lines, rho_threshold=30) # 合并后所有直线用于后续矩形检测 all_lines = merged_vertical + merged_horizontal
其他门识别优化思路
- 矩形校验阶段增加过滤规则:
- 长宽比过滤:室内门常规长宽比在1.8~3区间,可以根据你的实际场景调整阈值,过滤不符合比例的矩形
- 内部像素校验:门的内部通常是相对均匀的低边缘区域,统计矩形框内的边缘像素占比,占比低于阈值才判定为候选门
- 非极大值抑制:生成多个重叠矩形时,设置IOU阈值合并重叠度高的矩形,只保留置信度最高的结果
- 轮廓检测替代纯直线检测:可以先提取图像中的闭合轮廓,再拟合最小外接矩形后校验属性,冗余结果比纯直线检测少很多
内容的提问来源于stack exchange,提问作者SameeranZingre
相关产品推荐
相关产品推荐

