【问题标题】:Matlab how to find out if a matrix is in another martrixMatlab如何找出一个矩阵是否在另一个矩阵中
【发布时间】:2012-07-06 10:18:38
【问题描述】:

让我用一个例子来描述我的问题。假设我们有矩阵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-by-n,而Bp-by-q ,然后总是 m > pp > q

提前致谢。

【问题讨论】:

  • 你想过这个吗??考虑一下如果 A 是一个全部包含 1 的 4x4 矩阵,您希望返回什么?这将与 A 相同 - 这实际上对您有用吗?也许这正是您想要的,只是指出以防您没有考虑过。
  • @Ehsan 你能详细说明一下吗。例如,您在 [A(2,2) A(2,3);A(3,2) A(3,3)] 中匹配了模式 B。但是为什么不能和[A(1,1) A(2,1);A(1,3) A(2,3)]匹配。是因为您在 A 中寻找的模式必须是连续的吗?
  • @Abhinav 是的,它应该是连续的,而且我确信 A 中的 B 总是会有一个匹配位置。
  • @mathematician1975 看看我的编辑老兄:)
  • @Ehsan 你的意思是“至少一场比赛”或“最多一场比赛”或“一个且唯一一场确定性比赛”?

标签: matlab


【解决方案1】:

最高效的需要信号处理工具箱。然后你可以简单地使用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

【讨论】:

    【解决方案2】:

    我会做一个循环来检查 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);
    

    【讨论】:

      【解决方案3】:

      也许有一些矢量方式,但这是一个直接的函数,它只是在 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。如果你想在第一场比赛结束后退出,你可以在 if 子句中加入 return 语句。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-11-21
        • 2019-02-06
        • 2015-03-27
        • 2015-03-19
        • 2012-12-11
        • 1970-01-01
        • 2015-12-28
        • 2020-05-19
        相关资源
        最近更新 更多