You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优化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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 18:30:43