Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在matlab中比较两幅图像中的所有面片?_Matlab_Optimization_Image Processing_Nearest Neighbor - Fatal编程技术网

如何在matlab中比较两幅图像中的所有面片?

如何在matlab中比较两幅图像中的所有面片?,matlab,optimization,image-processing,nearest-neighbor,Matlab,Optimization,Image Processing,Nearest Neighbor,我有两个图像,比如说A和B,它们的大小不需要相同Abe的尺寸为255×255,而Bbe的尺寸为100×100。对于我的问题,补丁的尺寸是5×5。我需要做的是将A中的所有补丁与B中的所有补丁进行比较 每个面片将与一些相邻面片重叠。要清除这一点,A中的第一个补丁将是A(1:5,1:5)(MATLAB表示法)。第二个补丁A(2:6,1:5)依此类推,一直到第一行末尾的A(251:255,1:5),一直到A(251:255251:255)中的最后一个补丁 我必须将这些补丁与B中的所有补丁进行比较。如您所

我有两个图像,比如说
A
B
,它们的大小不需要相同<代码>Abe的尺寸为255×255,而
B
be的尺寸为100×100。对于我的问题,补丁的尺寸是5×5。我需要做的是将
A
中的所有补丁与
B
中的所有补丁进行比较

每个面片将与一些相邻面片重叠。要清除这一点,
A
中的第一个补丁将是
A(1:5,1:5)
(MATLAB表示法)。第二个补丁
A(2:6,1:5)
依此类推,一直到第一行末尾的
A(251:255,1:5)
,一直到
A(251:255251:255)
中的最后一个补丁

我必须将这些补丁与
B
中的所有补丁进行比较。如您所见,在
A
中有
251*251
补丁,在
B
中有
96*96
补丁。因此,有很多比较需要进行。比较就是欧几里得距离,也就是说,我只取两个面片的差,然后求平方和。对于每个补丁比较,我将得到一个标量值作为结果

我在MATLAB中实现了这一点,但它需要几分钟的时间来执行。因此,请建议我最快的方法来实现这一点。这一部分是我整个项目的瓶颈。下面给出了我编写的代码。我显然不是专家,所以请原谅我的错误

row = size(A,1);    
col = size(A,2);

row2 = size(B,1);    
col2 = size(B,2);

patch_long = zeros(5,5,(row2-4)*(col2-4));

idx = 1;

for i = 1:row2-4    
    for j = 1:col2-4

        patch_long(:,:,idx) = B(i:i+4,j:j+4);

        idx = idx+1;

    end

end

%// I rearranged 'B' matrix as 3d matrix with each patch arranged like 
%// slide behind one by one

parfor m = 1:row-4    
    for n = 1:col-4

        temp1 = bsxfun(@minus,(A(m:m+4,n:n+4)),patch_long);
        temp2 = sum(sum(temp1.^2));

        count = sum(temp2 <=threshold);

        if count > 1 
            % Do xyzend
        end

    end
end

%// count counts how many patches in 'B' are close to a particular patch in 'A'.
row=大小(A,1);
col=尺寸(A,2);
第2行=尺寸(B,1);
col2=大小(B,2);
patch_long=零(5,5,(第2-4行)*(第2-4行));
idx=1;
对于i=1:第2-4行
对于j=1:col2-4
斑块长(:,:,idx)=B(i:i+4,j:j+4);
idx=idx+1;
结束
结束
%//我将“B”矩阵重新排列为3d矩阵,每个面片的排列方式如下
%//一个接一个地滑到后面
m=1的参数:第4行
对于n=1:col-4
temp1=bsxfun(@负,(A(m:m+4,n:n+4)),面片长;
temp2=sum(sum(temp1.^2));
计数=总和(temp2 1
%多西泽德
结束
结束
结束
%//计数计算“B”中与“a”中特定修补程序接近的修补程序的数量。
您可以使用来提取所有修补程序

pA = im2col( A, [5 5], 'sliding' );
pB = im2bol( B, [5 5], 'sliding' );
% compute squared difference
D = sum( bsxfun( @minus, permute( pA, [2 3 1] ), permute( pB, [3 2 1] ) ).^2, 3 );

顺便说一下,如果您不需要所有的距离,并且愿意为
k
近邻的近似值妥协,您可能会发现非常有用:

这是一个近似的
k
-最近邻算法,专门为图像修补程序量身定制。它在内存(空间)使用方面非常有效,速度也非常快。

正如Mikhail提到的那样,你的工作做得非常出色。你真的没有什么可以改进的

您只能做几件小事:

  • 交换矩阵的处理顺序
  • 交换循环顺序
  • 因为
    A
    小于
    B
    ,交换处理顺序将导致
    bsxfun
    承担更多的繁重工作。因为这比JIT'ed MATLAB循环“更接近硅”,这将是有益的

    a=rand(255)
    B=rand(10)
    做一个简单的
    tic…toc
    测试(我没有一整天的时间!)

    对于您的情况,差异当然会小一些,但这可能是非常重要的

    交换循环顺序(在内部循环的行上循环,在外部循环的列上循环)这是因为MATLAB以列主顺序存储数据。交换顺序意味着指针偏移计算可以在内部循环中重复使用,因此需要更少的操作。通常情况下,这可以弥补约30%的差异,但是,最新版本的MATLAB在此基础上有了很大的改进(仍然不确定如何改进),并且您不使用1列,而是5列…因此这可能没有那么重要

    使用不同的循环顺序进行相同的测试,得到:

    Elapsed time is 3.462599 seconds. %// original loop order
    Elapsed time is 3.272909 seconds. %// inverted loop order
    
    结合一切:

    Elapsed time is 1.571496 seconds. %// Both optimizations implemented
    
    我的代码:

    %// random data for testing
    A = rand(255);
    B = rand(10);
    threshold = rand;
    
    [rowA, colA] = size(A);
    [rowB, colB] = size(B);
    
    patch_long = zeros(5,5, (rowA-4)*(colA-4));
    
    tic
    
    %// re-arrange A into 3D array of 5×5 patches 
    idx = 1;
    for jj = 1:colA-4     
        c = jj:jj+4;      %// re-use column indices
        for ii = 1:rowA-4 %// inner loop is over the rows
    
            patch_long(:,:,idx) = A(ii:ii+4, c);        
            idx = idx+1;
    
        end
    
    end
    
    %// The heavy lifting
    for n = 1:colB-4     %// let bsxfun do more work; loop over smallest array here
        c = n:n+4;       %// re-use column indices
        for m = 1:rowB-4 %// inner loop is over the rows
    
            temp1 = bsxfun(@minus, B(m:m+4, c), patch_long);
            count = sum( sum(temp1.^2) <= threshold );
    
        end
    end
    
    toc
    

    但我认为这主要是因为我的工作电脑很差(AMD-A63650APU)

    你实际上做了一个很好的矢量化。看起来这不能明显改善。考虑算法的改进。比如,你真的需要比较所有的补丁吗?你碰巧有双精度的GPU吗?你有什么版本的Matlab?我不知道GPU。我的MATLAB版本是2012B.@你的意思是我应该在循环时先写“for cols”,然后写“for rows”?如果在命令提示符中键入
    gpuDevice
    ,你会看到什么?查看我的
    im2col
    实现(我现在在R2010b上),它没有做任何与OP已经做的不同的事情,除了使用更多的内存…除了缩短代码,我不能产生任何明显的速度差异。也许在以后的版本中实现发生了更改;你能用你的(较新)版本验证加速吗?@RodyOldenhuis我没有访问较新版本的权限。抱歉。@akhilc,在这种情况下,您只需要每个补丁的10个最近邻(NN):如果它们比阈值更接近,则使用所有,如果不是,则仅使用其中的一部分。要精确获得10个NN,您确实需要与所有其他补丁进行广泛比较。但是,如果您愿意进行一些近似,您可以获得(近似值)10 NN快得多。看看PatchMatch!如果我理解正确,PatchMatch是蛮力方法的早期版本。这意味着,它仍然是O(N²)最坏情况(只有最后一个补丁低于阈值)。这是否正确?@akhilc我在下载的版本中看到了一个
    readme.txt
    文件。非常感谢。让我试试这个,稍后再给你回复。我为a(255255)和B(50,50)运行了你的优化代码“行先列法”耗时30秒,建议的循环法耗时29.5秒。我认为,对于更大的图像,这可以节省我大量的时间。虽然你的第二个建议对我来说有点难以采纳。我的意思是使用“B”上的循环。因为“阈值”实际上是一个矩阵。对于
    %// random data for testing
    A = rand(255);
    B = rand(10);
    threshold = rand;
    
    [rowA, colA] = size(A);
    [rowB, colB] = size(B);
    
    patch_long = zeros(5,5, (rowA-4)*(colA-4));
    
    tic
    
    %// re-arrange A into 3D array of 5×5 patches 
    idx = 1;
    for jj = 1:colA-4     
        c = jj:jj+4;      %// re-use column indices
        for ii = 1:rowA-4 %// inner loop is over the rows
    
            patch_long(:,:,idx) = A(ii:ii+4, c);        
            idx = idx+1;
    
        end
    
    end
    
    %// The heavy lifting
    for n = 1:colB-4     %// let bsxfun do more work; loop over smallest array here
        c = n:n+4;       %// re-use column indices
        for m = 1:rowB-4 %// inner loop is over the rows
    
            temp1 = bsxfun(@minus, B(m:m+4, c), patch_long);
            count = sum( sum(temp1.^2) <= threshold );
    
        end
    end
    
    toc
    
    Elapsed time is 387.802798 seconds. %// original version, but without parfor
    Elapsed time is 362.991760 seconds. %// both optimizations, WITH parfor