让我用一个例子来描述我的问题。假设我们有矩阵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 。
提前致谢。
答案 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
语句。