使用OpenCV findContours提取工程图纸表格结果异常的问题求助
工程图纸表格区域提取修复方案
问题排查
你的原代码存在2处核心逻辑错误:
- 首次轮廓检测后将所有四边形轮廓填充为白色,直接清除了表格的边框特征,导致后续无法识别到有效表格区域
- 形态学操作误用了
cv2.MORPH_OPEN,应该使用闭运算来连接断裂的表格线,且原核尺寸参数不匹配当前图纸的表格宽高比例
修复后可运行代码
import cv2 import numpy as np image = cv2.imread('01.png') original = image.copy() gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) blur = cv2.GaussianBlur(gray, (3,3), 0) thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1] # 分别提取水平和垂直直线,组合成表格边框 # 提取水平直线 horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (40,1)) detect_horizontal = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, horizontal_kernel, iterations=2) cnts_horizontal = cv2.findContours(detect_horizontal, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cnts_horizontal = cnts_horizontal[0] if len(cnts_horizontal) == 2 else cnts_horizontal[1] for c in cnts_horizontal: cv2.drawContours(thresh, [c], -1, 255, 2) # 提取垂直直线 vertical_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1,40)) detect_vertical = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, vertical_kernel, iterations=2) cnts_vertical = cv2.findContours(detect_vertical, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cnts_vertical = cnts_vertical[0] if len(cnts_vertical) == 2 else cnts_vertical[1] for c in cnts_vertical: cv2.drawContours(thresh, [c], -1, 255, 2) # 闭运算连接表格边框,形成完整的外框 kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (10,10)) close = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel, iterations=3) # 提取外轮廓,过滤非表格区域 cnts = cv2.findContours(close, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cnts = cnts[0] if len(cnts) == 2 else cnts[1] # 按面积倒序,取最大的四边形就是目标表格 cnts = sorted(cnts, key=cv2.contourArea, reverse=True) for c in cnts: peri = cv2.arcLength(c, True) approx = cv2.approxPolyDP(c, 0.02 * peri, True) if len(approx) == 4: x,y,w,h = cv2.boundingRect(approx) # 增加面积和宽高比过滤,避免识别到小矩形 if cv2.contourArea(c) > 10000 and 1 < w/h < 5: cv2.drawContours(image, [approx], -1, (36,255,12), 3) crop = original[y:y+h, x:x+w] break cv2.imwrite('image.png', image) cv2.imwrite('ROI.png', crop) cv2.waitKey() cv2.destroyAllWindows()
优化点说明
- 新增了水平/垂直直线单独提取逻辑,过滤掉图纸中无关的文字、线条干扰
- 降低了轮廓拟合的epsilon参数从0.05到0.02,避免漏识别边缘有轻微变形的表格外框
- 增加了轮廓面积、宽高比过滤规则,以及按面积倒序取最大四边形的逻辑,适配工程图纸中目标表格为最大矩形的特征
- 调整了形态学运算类型和参数,保证表格边框的完整性
内容的提问来源于stack exchange,提问作者Fayne
相关产品推荐
相关产品推荐

