基于到像素的距离的渐变

时间:2013-02-13 16:28:09

标签: image-processing

我有一个算法可以根据到掩码中最近像素的距离创建灰度渐变。我通过构造一个半径增加的圆圈并将掩模中的所有像素与圆形像素进行采样来找到像素:

for (x = 0; x < width; x++){ 
   for (y = 0; y < height; y++) {
      bool pixelFound = false;
      for (radius = 0; radius < resolution, pixelFound == false; radius++) {
         for (alpha = 0; alpha < 2 * PI; alpha += 1/radius) {
            xx = x + cos(alpha)*radius;
            yy = y + sin(alpha)*radius;

            if ( MaskHasPixel(xx, yy) ) {
               pixelFound = true;
               gradient = 1 - Magnitude(xx-x, yy-y) / resolution;
               WriteGradientForPixel(x,y, gradient);
            }
         }
      }
   }
}

目前算法非常慢 - 对于512x512的图像和128x128的掩码大小,它将需要进行512 * 512 * 384 * 41 = 4 127 195 136比较,这需要花费大量时间来计算中央处理器。其中一个选项是在GPU上进行计算,但是是否可以优化此算法以使其更快地工作?我希望最终能够相对快速地获得一个漂亮的平滑渐变。

谢谢!

2 个答案:

答案 0 :(得分:1)

嗯,后续的扩张。它们可以用改进的算法完成。假设你在零背景上有一些掩码。将其放置在您的图像上(通过放大零背景,此阶段的图像可能是unsigned shortunsigned int的数组,具体取决于其大小 - 我们需要将其像素值放入距离中)

下一步操作是距离计算。为了更快地完成它,首先我们找到掩码的边界并将其保存到坐标数组。在它之后,我们通过该数组并填充8个连接的非零像素,同时填充一个新的边界数组。

在第一次迭代结束free()第一个边界数组并使用新数组运行第二次迭代,将2放到邻居并填充下一个边界数组。

重复迭代,直到最后一个边界数组有0个成员。


另一种变体是直接算法,与您的一样。计算并存储蒙版的边框。好。现在开始扫描扩展到图像大小蒙版的所有像素。

如果像素值== 0,我们遍历所有边界像素,计算距离它们并存储最小距离。它将是渐变的值。

这个算法可以通过计算距离我们点侧面的边界像素的距离来改进。为此,我们不仅应该存储边界像素的坐标,还应该存储从掩模的重心到它们的角度。然后在扫描边界时,我们可以丢弃从当前图像点开始的角度相等的像素和掩模重心±某个值(π/ 2?)。

另一种更快速地进行计算的方法是将鼻窦和表格列表。 cosinuses有一些步骤,很小,相邻成员之间的值可以忽略不计。该步骤可以是从其中心开始的图像角度的角度像素尺寸。甚至更大。


当然,对于这个问题还有很多其他不同的优化方法,也许其中一些可能会更快。这是一个调查问题。

答案 1 :(得分:0)

我找到了一种使算法速度提高3倍的方法: 1.计算我的边框蒙版的几何中心。 2.计算从当前像素到上述中心的方向:dir =(center - pixel).normalized 3.检查我朝向中心的每个像素是否是边框像素。 如果是,那么搜索就结束了。 5.如果未找到朝向中心的边框像素,则使用原始较慢的方法。

另一种加快速度的方法是缩小原始图像的尺寸。这将有很大帮助。