给定 OpenCV/Python 中勾勒出“S”形状边缘的轮廓,可以使用哪些方法沿着形状中心追踪曲线?

问题描述 投票:0回答:2

给定字母 S 边缘的轮廓(例如,在漫画中),我怎样才能沿着该字母的脊柱获得一系列点,以便稍后使用直线、三次样条或其他曲线表示来表示该形状技术? 我想在 Python/OpenCV 中使用 30-40 个点来处理和表示形状。

形态骨架化可以对此有所帮助,但该操作似乎总是会产生错误的分支。 有没有更好的方法将轮廓折叠成字母的“S”形状?

enter image description here

在下面的示例中,您可以看到由形态骨架化产生的错误的“蛇舌”状树枝。 我不知道如果算法应该这样做的话,说它们是错误的是否公平,但对我来说,我不希望它们在那里。

enter image description here

以下是无字母漫画:

enter image description here

骨架化的另一个问题是它的计算成本很高,但如果你知道一种方法让它能够鲁棒地形成像树枝一样的“蛇舌”,那么我会尝试一下。

python opencv image-processing computer-vision mathematical-morphology
2个回答
8
投票

实际上,矢量化字体并不是一个小问题,而且相当棘手。要使用贝塞尔曲线正确矢量化字体,您需要跟踪。有许多库可以用于跟踪图像,例如Potrace。我不了解如何使用 python,但根据我的经验,我使用如下所述的 c++ 完成了类似的项目:

A。使用三次贝塞尔曲线拟合轮廓

虽然需要做很多工作,但这个方法非常简单。我相信如果你想拟合通过细化获得的骨架,这也很有效。

  1. 寻找物体的轮廓/边缘,可以使用OpenCV函数findContours()
  2. 整个形状无法使用单个三次贝塞尔曲线表示,因此请使用 Ramer-Douglas-Peucker (RDP) 将它们分成几个部分。这一步中重要的是,不要删除任何点,仅使用 RDP 来分割点。请参阅下图中的彩色部分。
  3. 对于每个线段,其中 S 是一组 n 个点 S = (s0, s1,...Sn),使用 最小二乘拟合
  4. 拟合三次贝塞尔曲线

enter image description here

最小二乘拟合示意图:

enter image description here

B.分辨率 分辨率独立曲线渲染

论文中描述的这种方法非常复杂,但却是可用于显示矢量字体的最佳算法之一:

  1. 求轮廓(同方法A)
  2. 使用RDP,与方法A不同,使用RDP去除点,从而可以简化轮廓。
  3. 进行 delaunay 三角测量。
  4. 使用论文中描述的方法在外边缘绘制贝塞尔曲线

enter image description here


2
投票

以下简单的想法可能有用。

  1. 计算外轮廓的中轴。这将确保曲线的连通性。

  2. 找出分支点。根据其长度,您可以删除它们以消除“蛇舌”问题。

希望有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.