1

私の問題を例で説明しましょう。行列があるとしますA:

A =

     1     0     1
     1     1     1
     0     1     1

および行列B:

B =

     1     1
     1     1

に存在するC = func(A, B)かどうかを確認する関数をどのように記述すればよいですか? に存在する場合、関数は を返し、存在しない場合、関数は を返します。BA
AC = [0 0 0; 0 1 1; 0 1 1]C = [0 0 0; 0 0 0; 0 0 0];

編集:mn 列、かつpq列の場合、常にm > pおよび p > qである
ことに注意してください。AB

前もって感謝します。

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 コードを使用できると思いますが、これにはわずかな調整しか必要ありません。基本的に、重要な 3 行のみが続きます (コードは 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が1回検出されるとコードは停止しますが、検出されたオカレンスの数をカウントするように更新できます。

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 に答える