1

让我用一个例子来描述我的问题。假设我们有矩阵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];

编辑:
应该提到的是,如果Am × n并且Bp × q,那么m > pp > q总是。

提前致谢。

4

3 回答 3

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 代码,这应该只需要小的调整。基本上,重要的只有三行(注意代码在 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
于 2012-08-23T02:34:52.343 回答
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);
于 2012-07-06T12:55:51.310 回答
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 被发现不止一次,它也会被标记为 1。如果你想在第一场比赛后退出,你可以return在 if 子句中加入一条语句。

于 2012-07-06T12:35:18.733 回答