【问题标题】:How to fill circle with increasing radius?如何用增加的半径填充圆?
【发布时间】:2011-07-17 06:13:30
【问题描述】:

作为更复杂算法的一部分,我需要以下内容:

  • 假设我在离散网格上绘制了一个半径为 R1 的圆(图片)(下图中的绿色)
  • 我想用一个像素绘制半径 R2 大于 R1 的圆(下图中为红色)。
  • 在每个算法步骤中,以每次我有一个实心圆的方式绘制半径增加的圆。

如何在每个步骤中找到要填充的点,以便在每个步骤结束时我已完全归档圆圈?

我在考虑一些圆形光栅化算法,但这会导致填充时出现一些空白。另一种方法是使用一些数学形态学运算,例如膨胀,但这似乎计算成本很高。

我通常正在寻找在任意形状上执行此操作的方法,但最初的圆形算法就足够了。

【问题讨论】:

  • 每一步的形状会隐藏之前的吗?
  • 在每一步我都在寻找一组点(红色),这些点被添加以增加大约 1 个像素的半径。

标签: algorithm image image-processing geometry


【解决方案1】:

您最好的选择是绘制并填充一个稍大的红色圆圈,然后绘制并填充绿色圆圈。然后在下一次迭代中重做。

只绘制 1px 的边框是相当棘手的。您的示例图像甚至不是很一致。在某些地方,白色像素与绿色像素成对角线,而在其他地方,该像素为红色。

编辑:

  • borderPixels = emptySet
  • 对于每个绿色像素,p
    • 对于每个邻居 np
      • 如果 n 是白色的
        • n 添加到 *borderPixels`
  • borderPixels 做任何你想做的事(比如把它们涂成红色)

【讨论】:

  • 图像只是其外观的近似示例。我可以接受可以在某些点改变 1-2 个像素的算法,尤其是对于任意形状。然后,这条“前线”用于检查其他一些图形对象是否有交叉。
  • 谢谢,这个算法是我的第一个解决方案,但是找到“对于每个邻居”基本上是一个 3x3 掩码和它的最大操作的膨胀。我在想存在一些计算成本较低的算法。
  • 如果您要处理任意形状,我不相信。
  • 可爱的算法。我想它可以稍微优化一下,这样您就不会扫描所有内部绿色像素,而只在边界像素上前进。您可能需要维护 2 套 innerBorder(绿色)、outerBorder(白色)。需要以某种方式初始化 innerBorder 以启动算法
  • @davka,不,如果形状有孔,则不会。 (@Ross 指出圆圈只是一个例子,他实际上是在处理任意形状)
【解决方案2】:

我目前的圆形解决方案。

基于众所周知的Midpoint circle algorithm

  • 为 R1 半径的 1 个八分圆创建点集(浅绿色像素)
  • 为 R2 半径的 1 个八分圆创建一组点(深橙色像素)
  • 对于图像中的每一行,比较橙色和绿色像素的 X 坐标,并获得 0 或 1(或其他)之间的像素数(浅橙色)。
  • 对每个八分圆重复(对于某些八分圆,必须比较列而不是行)

此算法可应用于其他类型的参数形状(例如基于贝塞尔曲线)

对于非参数形状(基于像素)图像卷积(膨胀),具有中心对称(圆形)的内核。换句话说,对于形状中的每个像素,寻找具有小半径的圆形邻居并将它们设置为集合的一部分。 (昂贵的计算)

【讨论】:

  • 享受平行贝塞尔曲线的乐趣!...估计我的方法计算成本更低,即使您必须消耗一些内存来创建缓冲区并将结果组合回来...
  • 这也许是我不明白,但你的方式并没有降低计算成本。和我的方案类似,只是做了最后没有用到的操作。例如,不需要填充绿色部分。 “燃烧”内存不是选项。预期结果是像素列表,而不是必须再次处理才能找到它们的图像。
【解决方案3】:

另一种选择是绘制一个带有 2 像素宽的红色边框的圆形/形状,然后绘制一个没有边框的绿色填充圆形/形状。这应该留下 大约 1px 宽的边缘。 这取决于您使用的任何技术如何将线条解析为像素。

圆算法倾向于针对画圆进行优化.....See the link here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-22
    • 2014-08-03
    • 1970-01-01
    • 2020-05-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多