我有一个numpy数组,描绘了一个像素宽,离散,连接曲线。该曲线通过图像处理的 Skeletonization 操作获得。我试图在任意点找到上面曲线的曲率,以检测弯曲/扭结(它将具有高曲率值)。
我尝试使用general formula for curvature实现上述功能。然而,由于这是一个像素化的离散曲线,其生成函数未知,我试图使用numpy RadioButton
代替。
我在上面看到的问题是,由于曲线一个像素宽,在任何一点斜率都可以只有0,1或无穷大中的一个 即可。结果,我得到的曲率值大多没有意义或无用。
我正在寻找一些建议,从哪里开始,以便从上面得到一条平滑的曲线,这样我就可以用更有意义的方式计算曲率。有人可以建议我可以应用任何数学运算或卷积来实现同样的目标吗?下面是我的代表性二进制图像。
P.S。我对图像处理非常非常新,所以对标准算法(在数学书籍中)或库实现的引用会非常有用。
答案 0 :(得分:3)
确定的方法是使用两个或多个相邻点将低阶参数曲线拟合到每个骨架化点。然后使用拟合曲线参数和分析公式计算该点的曲率。可以使用几种曲线模型。两个主要模型是:
numpy.polyfit
来适应此模型。一种简单的策略是首先通过拟合局部线(例如,使用1阶曲线的polyfit)来估计该点处的切向量。旋转点以使切线向量与x轴对齐。最后,使用polyfit将1D二次方f(x)拟合到旋转点。制作任何曲率估计器的棘手问题是曲率可以在不同的尺度上估算。例如,我是否希望我的估算器对高频细节敏感或者这实际上是噪声?这个决定体现在邻里大小的选择上。太小,来自噪声和离散化的误差导致估计不稳定。但是太大,并且可能存在大的建模误差(通过将曲线近似为参数函数而出现误差)。一般来说,你必须自己选择最好的邻里大小。
你也会在连接点处得到一些不良的曲率估计值,但这在很大程度上是不可避免的,因为曲率在那里没有明确定义。一个天真的修复可能是在连接点处分割所有路径,然后单独估计每条路径上的曲率。
答案 1 :(得分:2)
Toby对连接点提出了一个很好的建议:检测连接点,并在每个连接点之间取出每条线。
检测连接点(和端点)。这非常简单:设置并具有两个以上邻居的所有像素都是连接点。设置并且恰好具有一个邻居的所有像素都是端点。检测所有这些点并将其坐标放在列表中。
查找点对之间的行。从列表中的每个坐标开始,查找从那里开始的行。请注意,对于交接点,您将至少有三条线从那里开始。如果你这样做,你会发现每一行两次。您可以通过反转它们开始位置左侧的线来删除重复项(如果两个端点位于同一图像列上,请将顶部的一个作为开头)。现在它们可以直接比较,因此您可以删除重复项(或者不首先存储它们)。请注意,仅仅比较起点和终点是不够的,因为您可以使用具有相同起点和终点的不同行。
跟踪每一行。上述步骤要求您跟踪每一行。看看你是否能搞清楚,这很有趣!跟踪物体轮廓的Here is a description of an algorithm,你可以用它作为灵感,因为这个问题非常相似。存储具有x坐标的矢量和每行具有y坐标的矢量。
平滑线条。正如您所注意到的,连续的步骤是在8个方向之一,因此角度是强烈离散的。您可以通过平滑坐标向量来防止这种情况。这是一个快速而肮脏的技巧,但它确实有效。将这些矢量视为一维图像,并应用平滑滤波器(我更喜欢高斯滤波器for many reasons)。在这里,您使用x坐标分别过滤带有y坐标的矢量。
计算曲率。最后,您可以计算曲线的曲率,如norm of the derivative of the unit normal to the curve。计算衍生物时,不要忘记考虑点之间的距离!