高效计算距离图

时间:2017-06-15 19:13:17

标签: algorithm 2d dynamic-programming

我有一个用黑白像素填充的二维图像。现在,对于每个白色像素,我想知道(距离最近)黑色像素,以及我想知道的每个黑色像素(距离)最近的白色像素。

一个天真的算法是:

for(var y = 0; y < height; y++)
{
    for(var x = 0; x < width; x++)
    {
        var min = float.MaxValue;
        var me = image[x,y];

        for(var sy = 0; sy < height; sy++)
        {
            for(var sx = 0; sx < width; sx++)
            {
                var target = image[sx,sx];

                if(target != me)
                {
                    // target is the opposite color
                    var distance = Distance(x, y, sx, sy);
                    if(distance < min)
                    {
                        min = distance;
                    }
                }       
            }
        }

        distanecImage[x,y] = min;
    }
}

我认为这是二次复杂性。有什么方法可以加快速度吗?我有一个想法,如果你知道所有邻居最近的目标像素,你可以计算你自己的最近距离,而不必遍历整个图像。但是我在使用这个想法生成算法时遇到了麻烦,或者如何调用这样的算法。

我仅限于DirectX9级硬件,但如果需要,我可以使用GPU来加快速度。最大大小约为256x256。

1 个答案:

答案 0 :(得分:1)

术语:你有 4 for循环:两个外环扫描点和两个内循环找到最近点。

大幅加速内循环

您正在逐行扫描图像,查看每个点。

一旦您知道找到了您想要的内容,就应该从最近到最远的位置以螺旋线扫描点:

spiral

你的观点是X,你按照1,2,3的顺序扫描点......如图所示。 (请注意,在20找到一个像素并不意味着您可以停止 - 您可以在22找到更近的像素。

(使用Gimp创建 - 我应该使用什么?!)

使用旧结果加快速度

如果为每个已处理的点保留最近的点,则只需扫描每个下一个点的图像部分即可实现额外的加速。

enter image description here

您需要仔细考虑需要寻找的位置,但通常情况下,您可以获得4倍的加速。

考虑最坏的情况

你最糟糕的情况是白色图像,角落里有一个黑点。 在这种情况下,我的改进不会给你带来任何好处。