Matlab如何找出矩阵是否在另一个矩阵中

时间:2012-07-06 10:18:39

标签: matlab

让我用一个例子来描述我的问题。假设我们有矩阵A

A =

     1     0     1
     1     1     1
     0     1     1

和矩阵B

B =

     1     1
     1     1

如何编写功能C = func(A, B)以检查B中是否存在A?  如果它存在于A中,则函数返回C = [0 0 0; 0 1 1; 0 1 1],如果不存在,则函数返回C = [0 0 0; 0 0 0; 0 0 0];

修改
应该提到的是,如果A m -by- n B p -by- q ,然后 m > p p >总是 q

提前致谢。

3 个答案:

答案 0 :(得分:4)

效率最高的是信号处理工具箱。然后,您只需使用xcorr2()即可。按照您的示例,以下内容应该有效:

C = xcorr2 (A, B);
[Row, Col] = find (C == max (C(:)));
%% these are not the coordinates for the center of the best match, you will
%% have to find where those really are
%% The best way to understand this is to strip the "padding"
row_shift = (size (B, 1) - 1)/2;
col_shift = (size (B, 2) - 1)/2;
C = C(1+row_shift:end-row_shift, 1+col_shift:end-col_shift)
[Row, Col] = find (C == max (C(:)));
if (B == A(Row-row_shift:Row+row_shift, Col-col_shift:Col+col_shift))
    disp ("B shows up in A");
endif

上面的代码看起来有点复杂,因为我试图覆盖任何大小的输入(仍然只是奇数大小),但应该可以工作。

如果您没有此工具箱,我认为您可以使用Octave code for it,这只需要很小的调整。基本上,只有三行重要(注意代码在GPL下):

[ma,na] = size(a);
[mb,nb] = size(b);
c = conv2 (a, conj (b (mb:-1:1, nb:-1:1)));

在Octave中,如果您至少使用信号包1.2.0,xcorr2还可以采用额外选项“coeff”来计算归一化的互相关。当匹配完美时,它的值为1,因此您可以使用以下方法简化:

C = xcorr2 (A, B, "coeff");
if (any (C(:) == 1)
    display ("B shows up in A");
endif

答案 1 :(得分:1)

我会做一个循环来检查A的已调整大小的子矩阵。我的代码在找到B之后停止,但可以更新它以计算找到的出现次数。

A = [1 0 1; 1 1 1; 0 1 1; 0 0 0];
B = [1 1; 1 1]; 

[m n] = size(A);
[p q] = size(B);

found = 0;
x = 0;

while ~found && (x+p-1 < m)
    y = 0;
    x = x + 1;
    while ~found && (y+q-1 < n)
        y = y + 1;
        A(x:x+p-1,y:y+q-1)
        found = isequal(A(x:x+p-1,y:y+q-1),B);
    end
end

fprintf('Found Matrix B in A(%d:%d, %d:%d)\n',x,x+p-1,y,y+q-1);

答案 2 :(得分:0)

也许有一些矢量方式,但这是一个直接的功能,只是滑过A并检查B:

function ret=searchmat(A,B)
    ret=zeros(size(A));
    for k=0:size(A,1)-size(B,1)
        for l=0:size(A,2)-size(B,2)
            if isequal(A(1+k:size(B,1)+k,1+l:size(B,2)+l),B)
                ret(1+k:size(B,1)+k,1+l:size(B,2)+l)=1; % or B as you wish
            end
        end
    end
end

如果B被发现不止一次,它也标有一个。如果你想在第一场比赛后退出,你可以在if子句中加入return语句。