[英]Fit a smooth curve in binary image
我想在二进制图像中插入平滑线。
该图像是使用对比度,轮廓,骨架,最近邻,轮廓分离等进行预处理的结果。初始图像
我认为一旦我得到一个白色圆点阵列(x,y),拟合曲线会更容易。 但是当我尝试在此图像中拟合曲线时,由于某个x处的多个值,会出现锯齿形线。 我需要一个解决我问题的通用解决方案。 我的图片可能会有所不同(我正在制作应用)。 对于特定x,它可以具有4-5个值,反之亦然。
方法我试过:
最近邻连接。 (图像不顺畅)
scipy interpolate(由于多个y @x出现之字形线)
matplotlib样条曲线
建议我如何在这些图像中拟合平滑曲线。
我理解这个问题意味着你想通过数据找到曲线作为x和y坐标的列表。
选择一个点开始,例如,在图的边或边缘有高密度的点。
找到一方或另一方的中位数,排除传单并找到平均值。 移过去,再做一次。
对于具有两条线的区域,您可以将中位数中考虑的点的范围限制为当前或前一点的某个范围内的点。
中位数将避免对远点进行超重,并且倾向于在x(或y,如果你愿意)的那一点强烈地朝向数据的中心拉动。
平均值通常与您可能正在检查的物理理论或模型有更强的关系。
您可以对不同的数据点集群重复此操作,以查找所有行。
最后比较所有曲线并修剪重复,例如通过平方差的总和检测。
这可以通过使用以下步骤来解决,代码如下:
首先连接所有最近的邻居点。 这将以曲线或图形的方式提供数组。
然后使用单变量样条平滑来使曲线平滑。
问题已解决 - 根据曲线,曲折线将变得平滑。
用于连接所有最近邻居的代码:
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.