gpt4 book ai didi

image - 图像之间的欧氏距离

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:59:38 26 4
gpt4 key购买 nike

enter image description here我有两张图像,比如 PS,大小为 8192×200,我想计算它们之间的自定义“欧氏距离”。目前我使用以下步骤:

  1. 将图像 reshape 为一对列向量和行向量:

    Ip = Ip(:).';
    Is = Is(:);
  2. 计算一个度量矩阵G,其元素由公式给出

    G(i,j) = 1/(2*pi*r*r) * exp((-d*d)/(2*r*r));

    其中 r 是一个从 0 到 20 的全局参数,例如,d 是像素 i 和像素 j。例如,如果像素 i(k,l) 并且像素 j(k1,l1),那么d = sqrt((k-k1)^2 + (l-l1)^2);。像素 1 将为 (1,1),像素 2 将为 (1,2),依此类推。因此,矩阵 G 的大小将为 1638400×1638400

  3. 计算两个图像之间的最终(标量)欧氏距离,使用:

    ImEuDist = sqrt( (Ip-Is) * G * (Ip-Is).' );  

我已经使用 mex 函数编写了一些代码,但在给出结果之前花费的时间太长(5-6 小时)- 参见 this SO question有关代码和更多讨论。

请帮我优化一下;理想情况下,我希望它能在几秒钟内运行。请注意,我对涉及 GPU 的解决方案不感兴趣。

最佳答案

如果我没理解错的话,您应该能够执行以下操作,并让它在 2 秒内运行:

示例数据:

s1 = 8192; s2 = 200;
img_a = rand(s1, s2);
img_b = rand(s1, s2);
r = 2;

和计算本身:

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);

以上大约需要25s。要缩短到 2 秒,您需要用更快的、基于 fft 的卷积替换标准的 conv2。参见 thisthis :

function c = conv2fft(X, Y)
% ignoring small floating-point differences, this is equivalent
% to the inbuilt Matlab conv2(X, Y, 'same')
X1 = [X zeros(size(X,1), size(Y,2)-1);
zeros(size(Y,1)-1, size(X,2)+size(Y,2)-1)];
Y1 = zeros(size(X1));
Y1(1:size(Y,1), 1:size(Y,2)) = Y;
c = ifft2(fft2(X1).*fft2(Y1));
c = c(size(X,1)+1:size(X,1)+size(X,1), size(X,2)+1:size(X,2)+size(X,2));
end

顺便说一句,如果您仍然希望它运行得更快,您可以利用 exp(-d^2/r^2) 变得非常接近对于相当小的 d: 为零,因此您实际上可以将内核裁剪成一个很小的矩形,而不是上面建议的巨大矩形。较小的内核意味着 conv2fft(或者尤其是 conv2)运行得更快。

关于image - 图像之间的欧氏距离,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36985718/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com