如何优化CV2提取图表曲线的代码?去网格后仍存残留噪声
问题描述
想要从指定图表图像中提取曲线(其中一条曲线较细),计划先去除曲线周围的干扰元素(网格线和文字)。目前已编写如下去除网格的CV2代码:
import numpy as np import cv2 gray = cv2.imread('test.png') edges = cv2.Canny(gray,50,150,apertureSize = 3) lines = cv2.HoughLinesP(image=edges,rho=0.01,theta=np.pi/90, threshold=100,lines=np.array([]), minLineLength=100,maxLineGap=80) a,b,c = lines.shape for i in range(a): cv2.line(gray, (lines[i][0][0], lines[i][0][1]), (lines[i][0][2], lines[i][0][3]), (255, 255, 255), 3, cv2.LINE_AA) cv2.imwrite('result.png',gray)
处理后图像仍存在噪声,且曲线有轻微截断(无需完美修复)。现寻求更优解决方案或优化建议,比如先去除文字、直接检测曲线而非先去除网格等。
优化方案与建议
一、优先去除文字干扰
文字属于小尺寸不规则区域,可通过形态学开运算过滤,避免后续处理误判:
import numpy as np import cv2 # 读取图像并转灰度(原代码未做灰度转换,需修正) img = cv2.imread('test.png') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 用3x3矩形核做开运算,多次迭代过滤文字 kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3)) no_text_img = cv2.morphologyEx(gray, cv2.MORPH_OPEN, kernel, iterations=2) cv2.imwrite('no_text.png', no_text_img)
二、精准去除网格线
原代码HoughLinesP参数易误检测曲线片段,可通过限制检测角度、调整阈值优化:
# 对去文字后的图像做边缘检测 edges = cv2.Canny(no_text_img, 50, 150, apertureSize=3) # 仅检测水平/垂直线(角度误差控制在5度内) lines = cv2.HoughLinesP(edges, rho=1, theta=np.pi/180, threshold=150, minLineLength=200, maxLineGap=10) if lines is not None: for line in lines: x1, y1, x2, y2 = line[0] angle = np.arctan2(y2 - y1, x2 - x1) * 180 / np.pi # 只擦除水平或垂直线条 if abs(angle) < 5 or abs(angle - 90) < 5: cv2.line(no_text_img, (x1, y1), (x2, y2), (255, 255, 255), 2, cv2.LINE_AA) cv2.imwrite('no_grid.png', no_text_img)
三、直接提取曲线(跳过网格去除)
若曲线连续性较好,可通过轮廓检测直接提取,过滤网格和文字干扰:
# 读取原图转灰度并二值化(反转后曲线为白色) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) _, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY_INV) # 提取外部轮廓,过滤小区域 contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) curve_img = np.zeros_like(gray) for cnt in contours: # 保留长度超过100的轮廓(过滤网格、文字) if cv2.arcLength(cnt, False) > 100: cv2.drawContours(curve_img, [cnt], 0, 255, 1) cv2.imwrite('extracted_curve.png', curve_img)
四、噪声收尾处理
若最终图像仍有零星噪声,用中值滤波去除:
denoised_img = cv2.medianBlur(curve_img, 3) cv2.imwrite('final_curve.png', denoised_img)
内容的提问来源于stack exchange,提问作者bananaconda
相关产品推荐
相关产品推荐

