我有一个用黑白像素填充的二维图像。现在,对于每个白色像素,我想知道(距离最近)黑色像素,以及我想知道的每个黑色像素(距离)最近的白色像素。
一个天真的算法是:
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。
答案 0 :(得分:1)
术语:你有 4 for
循环:两个外环扫描点和两个内循环找到最近点。
您正在逐行扫描图像,查看每个点。
一旦您知道找到了您想要的内容,就应该从最近到最远的位置以螺旋线扫描点:
你的观点是X
,你按照1,2,3的顺序扫描点......如图所示。
(请注意,在20
找到一个像素并不意味着您可以停止 - 您可以在22
找到更近的像素。
(使用Gimp创建 - 我应该使用什么?!)
如果为每个已处理的点保留最近的点,则只需扫描每个下一个点的图像部分即可实现额外的加速。
您需要仔细考虑需要寻找的位置,但通常情况下,您可以获得4倍的加速。
你最糟糕的情况是白色图像,角落里有一个黑点。 在这种情况下,我的改进不会给你带来任何好处。