nag*_*wal 5 algorithm matlab image
我有两个图像,比如P和S,大小为 8192×200,我想计算它们之间的自定义“欧几里德距离”。目前我使用以下步骤:
将图像重塑为一对列向量和行向量:
Ip = Ip(:).';
Is = Is(:);
Run Code Online (Sandbox Code Playgroud)计算一个度量矩阵,G,其条目由公式给出
G(i,j) = 1/(2*pi*r*r) * exp((-d*d)/(2*r*r));
Run Code Online (Sandbox Code Playgroud)
其中r是一个从 0 到 20 变化的全局参数,例如,d是 pixeli和 pixel之间的距离j。例如,如果像素i是(k,l)并且像素j是(k1,l1),则d = sqrt((k-k1)^2 + (l-l1)^2);。像素 1 将是(1,1),像素 2 将是(1,2),依此类推。因此,矩阵的大小G将为1638400×1638400。
计算两个图像之间的最终(标量)欧几里得距离,使用:
ImEuDist = sqrt( (Ip-Is) * G * (Ip-Is).' );
Run Code Online (Sandbox Code Playgroud)我已经使用 mex 函数编写了一些代码,但是在给出结果之前花费的时间太长(5-6 小时) - 请参阅此 SO 问题以获取代码以及对此的更多讨论。
请帮我优化一下;理想情况下,我希望它在几秒钟内运行。请注意,我对涉及 GPU 的解决方案不感兴趣。
如果我理解正确,您应该能够执行以下操作,并让它在 2 秒内运行:
样本数据:
s1 = 8192; s2 = 200;
img_a = rand(s1, s2);
img_b = rand(s1, s2);
r = 2;
Run Code Online (Sandbox Code Playgroud)
以及计算本身:
s1 = 8192; s2 = 200;
img_a = rand(s1, s2);
img_b = rand(s1, s2);
r = 2;
Run Code Online (Sandbox Code Playgroud)
以上大约需要25s。为了降低到 2 秒,您需要用conv2更快的基于 fft 的卷积替换标准。看看这个和这个:
img_diff = img_a - img_b;
kernel = bsxfun(@plus, (-s1:s1).^2.', (-s2:s2).^2);
kernel = 1/(2/pi/r^2) * exp(-kernel/ (2*r*2));
g = conv2(img_diff, kernel, 'same');
res = g(:)' * img_diff(:);
res = sqrt(res);
Run Code Online (Sandbox Code Playgroud)
顺便说一句,如果您仍然希望它运行得更快,您可以利用相当小的 d非常接近于exp(-d^2/r^2)零的事实:因此您实际上可以将内核裁剪为一个很小的矩形,而不是上面建议的巨大的东西。较小的内核意味着(或者特别是)运行速度更快。conv2fftconv2