繁体   English   中英

在二进制图像中拟合平滑曲线

[英]Fit a smooth curve in binary image

我想在二进制图像中插入平滑线。

该图像是使用对比度,轮廓,骨架,最近邻,轮廓分离等进行预处理的结果。初始图像

我认为一旦我得到一个白色圆点阵列(x,y),拟合曲线会更容易。 但是当我尝试在此图像中拟合曲线时,由于某个x处的多个值,会出现锯齿形线。 我需要一个解决我问题的通用解决方案。 我的图片可能会有所不同(我正在制作应用)。 对于特定x,它可以具有4-5个值,反之亦然。

方法我试过:

  1. 凸壳的凸面图像(图像不平滑)

  1. 最近邻连接。 (图像不顺畅)

  2. scipy interpolate(由于多个y @x出现之字形线)

  3. matplotlib样条曲线

建议我如何在这些图像中拟合平滑曲线。

我理解这个问题意味着你想通过数据找到曲线作为x和y坐标的列表。

选择一个点开始,例如,在图的边或边缘有高密度的点。

找到一方或另一方的中位数,排除传单并找到平均值。 移过去,再做一次。

对于具有两条线的区域,您可以将中位数中考虑的点的范围限制为当前或前一点的某个范围内的点。

中位数将避免对远点进行超重,并且倾向于在x(或y,如果你愿意)的那一点强烈地朝向数据的中心拉动。

平均值通常与您可能正在检查的物理理论或模型有更强的关系。

您可以对不同的数据点集群重复此操作,以查找所有行。

最后比较所有曲线并修剪重复,例如通过平方差的总和检测。

这可能是有用的,我不能肯定地说,因为我不知道所有目标图像的特征。

  1. 将图像转换为灰度
  2. 根据您定义的停止条件(根据某些指标,如连接的组件,可能)对您的图像应用侵蚀以执行一些步骤

在形态转换部分中检查OpenCV库以获取相关的API调用。

以下是几个步骤对图像进行侵蚀的示例。

在此输入图像描述

这可以通过使用以下步骤来解决,代码如下:

  1. 首先连接所有最近的邻居点。 这将以曲线或图形的方式提供数组。

  2. 然后使用单变量样条平滑来使曲线平滑。

问题已解决 - 根据曲线,曲折线将变得平滑。

用于连接所有最近邻居的代码:

def distance(P1, P2):
    return ((P1[0] - P2[0])**2 + (P1[1] - P2[1])**2) ** 0.5

def optimized_path(coords, start=None):
    if start is None:
        start = coords[0]
    pass_by = coords
    path_connected = [start]
    pass_by.remove(start)
    while pass_by:
        nearest = min(pass_by, key=lambda x: distance(path_connected[-1], x))
        path_connected.append(nearest)
        pass_by.remove(nearest)
    return path_connected

start = None
    points=[[i,j] for i,j in zip(x_data,y_data)]
    points = optimized_path(points,start)

平滑最近邻点的代码:

# Smoothing
distance_smooth = np.cumsum( np.sqrt(np.sum( np.diff(points, axis=0)**2, axis=1 )) )
distance_smooth = np.insert(distance_smooth, 0, 0)/distance_smooth[-1]
splines = [UnivariateSpline(distance_smooth, coords, k=5, s=None) for coords in points.T]
alpha = np.linspace(0, 1, 75)
points_fitted = np.vstack( spl(alpha) for spl in splines ).T

这是最终图像 - 平滑图像

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM