手绘曲线图像多项式拟合问题:拟合后出现密集区域而非平滑曲线
手绘曲线多项式拟合优化方案
你当前的问题在于提取了所有非背景像素点——手绘曲线本身有粗细,每个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
相关产品推荐
相关产品推荐

