我有一个 2D 形状存储为 SVG 中的路径元素。形状由贝塞尔曲线和线段组成。
我还有一组沿我使用弧长参数化生成的形状的等距点。
如何使用 SVG 或这些点来确定形状的中轴?
我正在使用 Python,但任何类型的伪代码或算法建议将不胜感激。
以下是我正在处理的形状类型的示例,红点是我沿曲线的采样点。
我有一个 2D 形状存储为 SVG 中的路径元素。形状由贝塞尔曲线和线段组成。
我还有一组沿我使用弧长参数化生成的形状的等距点。
如何使用 SVG 或这些点来确定形状的中轴?
我正在使用 Python,但任何类型的伪代码或算法建议将不胜感激。
以下是我正在处理的形状类型的示例,红点是我沿曲线的采样点。
有点晚了,但这里有:
上面的图片显示:(我已经使用在线工具将 OP 的图像转换为 SVG,因此边界参差不齐,这是红点的伪影) 1. 叠加的中间轴和比例轴变换(MAT和SAT)。2. 仅缩放轴变换。3. 仅中轴变换。4. 许多2 爪之一(见下文)。5. SAT中的单三叉戟( MAT中有很多)。
要找到中轴 (MA)或中轴变换 (MAT)(上图中的紫色曲线),可以使用以下算法(基于 Choi、Choi、Moon 和 Wee的论文- 请参阅此处的演示实现,它还处理相交的形状和带孔的形状)。其他算法也存在。
该算法比查找二进制图像(例如位图)骨架(又名草火或离散变换)更难实现,但具有几个优点(例如可分析)。为简化起见,下面的讨论仅处理没有孔的简单(非相交)形状的情况。
最后找到 n >= 3 的n 叉。从每个接触点开始:
如果发生上述 1 或 2 次迭代,则移动到边界 上的下一个接触点(使用next)。但是,如果需要 3 次或更多次迭代,则可以证明存在3 叉分支点,并且应该在cp1和cp1之间的每个边界块 上插入接触点s 。接下来。
在这种情况下,插入3-prong(请参阅下文了解如何找到这些)并返回第 1 步,再次从cp1开始。
我将在这里总结,但 Choi 等人的论文。这部分解释得很清楚,很容易理解。
在边界上选择一个点,它将成为我们2 叉的第一个接触点,并将其命名为bp1。从边界点画一条向内的法线 (即要找到的2 叉的第一个“叉”)。现在迭代:
在这里,我们通过构造外接圆而不是使用势函数来偏离论文。
请随时询问是否有任何不清楚的地方。
你可以从 skimage (scikit-image) 看到代码。您将找到骨架化代码和中间轴代码 (skimage.morphology.medial_axis)
源代码可在此地址获得:https ://github.com/scikit-image/scikit-image/blob/v0.12.2/skimage/morphology/_skeletonize.py#L103
该算法将图像的中轴变换计算为其距离变换的脊。
算法的不同步骤如下
A lookup table is used, that assigns 0 or 1 to each configuration of
the 3x3 binary square, whether the central pixel should be removed
or kept.
We want a point to be removed if it has more than one neighbor
and if removing it does not change the number of connected components.
The distance transform to the background is computed, as well as
the cornerness of the pixel.
The foreground (value of 1) points are ordered by
the distance transform, then the cornerness.
A cython function is called to reduce the image to its skeleton. It
processes pixels in the order determined at the previous step, and
removes or maintains a pixel according to the lookup table.
Because
of the ordering, it is possible to process all pixels in only one
pass.
我希望它会帮助你