图像之间的欧几里德距离 [英] Euclidean distance between images

查看:200
本文介绍了图像之间的欧几里德距离的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两张图片,比如 P S ,大小8192×200,我想计算它们之间的自定义欧几里德距离。目前我使用以下步骤:

I have two images, say P and S, of size 8192×200, and I want to calculate a custom "Euclidean distance" between them. Currently I use the following steps:


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

  1. Reshape the images into a pair of column and row vectors:

Ip = Ip(:).';
Is = Is(:);


  • 计算指标矩阵, 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

    where r is a global parameter that varies from 0 to 20, say, and d is the distance between pixel i and pixel j. E.g., if pixel i is (k,l) and pixel j is (k1,l1), then d = sqrt((k-k1)^2 + (l-l1)^2);. Pixel 1 will be (1,1), Pixel 2 will be (1,2), and so on. Therefore, the size of matrix G will be 1638400×1638400.

    计算两张图像之间的最终(标量)欧几里德距离,使用:

    Compute the final (scalar) Euclidean distance between two images, using:

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


  • 我已经使用mex编写了一些代码功能,但在给出结果(5-6小时)之前需要很长时间 - 参见这个问题以及对此的更多讨论。

    I have already written some code using a mex function, but it is taking too long before giving the results (5-6 Hours) - see this SO question for code and more discussion on this.

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

    Please help me to optimize this; I would ideally like it to run in a matter of seconds. Note that I am not interested in solutions involving the GPU.

    推荐答案

    如果我理解正确,您应该能够执行以下操作,并让它在2s以下运行:

    If I've understood correctly, you should be able to do the following, and have it run in under 2s:

    样本数据:

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

    以上约需25秒。要降低到2秒,您需要使用更快的基于fft的卷积替换标准的 conv2 。请参阅这个

    The above takes about 25s. To get down to 2s, you need to replace the standard conv2 with a faster, fft based convolution. See this and this:

    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 )将运行得更快。

    Incidentally, if you still want it to go faster, you could make use of the fact that exp(-d^2/r^2) gets very close to zero for fairly small d: so you can actually crop your kernel to just a tiny rectangle, rather than the huge thing suggested above. A smaller kernel means conv2fft (or especially conv2) will run faster.

    这篇关于图像之间的欧几里德距离的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    相关文章
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆