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

手绘曲线图像多项式拟合问题:拟合后出现密集区域而非平滑曲线

手绘曲线多项式拟合优化方案

你当前的问题在于提取了所有非背景像素点——手绘曲线本身有粗细,每个x坐标对应多个y值(反之亦然),直接用这些密集且多值的点做拟合,自然会得到混乱的密集区域而非平滑曲线。

核心解决思路

先对提取的点做降噪与精简,确保每个自变量(比如x)对应唯一的因变量(y),再进行多项式拟合。以下是两种可行方案:


方案1:骨架化处理(推荐)

先把粗线条转换成单像素宽度的曲线骨架,从根源上避免多值点问题:

import cv2
import numpy as np

# 假设gray_image是已读取的灰度图像
# 二值化:将曲线转为白色,背景转为黑色
_, binary_img = cv2.threshold(gray_image, 254, 255, cv2.THRESH_BINARY_INV)
# 骨架化操作,得到单像素宽度曲线
skeleton = cv2.ximgproc.thinning(binary_img)

# 提取骨架上的坐标点
OP = []
for row in range(skeleton.shape[0]):
    for col in range(skeleton.shape[1]):
        if skeleton[row, col] == 255:
            OP.append((col, row))  # 存储为(x,y)格式

# 按x坐标排序,确保点的顺序符合曲线走向
OP.sort(key=lambda p: p[0])
points = np.array(OP)
x, y = points[:, 0], points[:, 1]

# 执行多项式拟合(示例为3次多项式,可根据曲线复杂度调整degree)
degree = 3
coeffs = np.polyfit(x, y, degree)
poly_func = np.poly1d(coeffs)

# 生成拟合后的平滑曲线点
x_fit = np.linspace(x.min(), x.max(), 100)
y_fit = poly_func(x_fit)

方案2:对原始点分组去重

如果不想用OpenCV的骨架化,可直接对提取的点按x坐标分组,取每组y值的中位数来精简点集:

import numpy as np
from collections import defaultdict

# 假设OP是你原来提取的所有非255像素点
point_groups = defaultdict(list)
for x, y in OP:
    point_groups[x].append(y)

# 对每个x坐标,保留y值的中位数(比均值更抗噪)
filtered_points = []
for x in sorted(point_groups.keys()):
    y_median = np.median(point_groups[x])
    filtered_points.append((x, y_median))

filtered_points = np.array(filtered_points)
x, y = filtered_points[:, 0], filtered_points[:, 1]

# 多项式拟合
degree = 3
coeffs = np.polyfit(x, y, degree)
poly_func = np.poly1d(coeffs)

内容的提问来源于stack exchange,提问作者akhil

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 07:16:07