4

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

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

在此处输入图像描述

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

在此处输入图像描述

以下是漫画无字母:

在此处输入图像描述

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

4

2 回答 2

7

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

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

这种方法很简单,虽然需要做很多工作。我相信如果您想拟合从细化中获得的骨骼,这也很有效。

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

在此处输入图像描述

最小二乘拟合图示:

在此处输入图像描述

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

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

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

在此处输入图像描述

于 2014-02-19T06:34:15.977 回答
2

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

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

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

希望能帮助到你。

于 2014-02-19T18:26:27.800 回答