大きな二次元配列から​不特定の間隔かつ特定​サイズの二次元行列を​for loopを使わずに取り出す方法に関して

23 views (last 30 days)
K.S.
K.S. on 26 Feb 2021
Commented: K.S. on 21 Mar 2021
目的としては、大きな二次元の配列(画像等)から特定の大きさを持つ配列を抽出し、それをCell配列や通常のArrayとして格納したいと考えています。
具体的な状況は添付の写真のように、大きな二次元配列中に決まった間隔ではない、特定の大きさで、互いに接触しない1で識別された領域が存在するとします。この大きな配列から添付写真に示すような1で構成された3x3の像を初期の大きな像における位置関係を保持したまま、cell配列ないしは通常の配列変数としてfor loopを行わずに並び替えたいと考えています。
現時点で試したこととして、findや論理インデックスを利用して取り出す方法などを試していますが、この方法では1に対応する配列が列ごとに並び替えられて出力されてしまい、目的の形状に変形し保存が難しい状況にあります。結局やりたいこととしては、0に対応するすべての配列を削除し、残っている配列を位置関係を保持したまま結合させたいということです。
こちらのコードもforとifを利用して実装することはできるのですが、仮に何らかの0などの数値を除去する関数等があってループを使用せずに目的配列のデータが取得する事ができればすごく助かります。
ご不明な点が有ればコメントいただけると嬉しいです。よろしくお願いいたします。

Accepted Answer

Hernia Baby
Hernia Baby on 27 Feb 2021
まずは下準備
clc,clear,close all;
% 抜き出す部分行列はk×kとする
k = 3;
% ランダムな行列を作成
X = randn(11,12);
% 図と同じ分布を作る
A = zeros(11,12);
strt = [2, 2; 3,9; 7,7; 8,3];
for i = 1:size(strt(:,1))
A(strt(i,1):strt(i,1)+k-1,strt(i,2):strt(i,2)+k-1) = 1;
end
次に各部分行列の最初の行番号と列番号のみを抽出します。
それにそってk×kの行列を抜き出せばいいからです。
% 各部分行列の最初の(行,列)のみ抽出
vec_l = zeros(size(A(1,:)));
vec_r = zeros(size(A(:,1)));
A_lslide = [vec_l; A(1:end-1,:)];
A_lxor = xor(A,A_lslide);
A_l = A.*A_lxor;
A_l_rslide = [vec_r,A_l(:,1:end-1)];
A_l_rs_xor = xor(A_l,A_l_rslide);
A_lr = A_l.*A_l_rs_xor
A_lr =
0 0 0 0 0 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 1 0 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
ができました
次に該当するセルの行番号、列番号を抜き出します。
今回は列の低い順(左から右)に進む順に番号を割り当てています。
ここまで行けば部分行列を抜き出せるので好きに連結できます。
[x, y] = find(A_lr ~= 0);
[x, y] % チェック用
ans =
2 2
8 3
7 7
3 9
最後に部分行列を抜き出して連結します。
length(x)分の部分行列(今回は4つ)ができますので、2×2にいったん分けます。
縦方向に連結した後に、横方向に連結しています。
% 連結
X_ph_s = X_p(:,:,1);
X_ph_f = X_p(:,:,length(x)/2+1);
cnt = 1;
while cnt < length(x)/2
X_ph_s = vertcat(X_ph_s,X_p(:,:,cnt+1));
X_ph_f = vertcat(X_ph_f,X_p(:,:,length(x)/2+cnt+1));
cnt = cnt + 1;
end
X_ex = horzcat(X_ph_s,X_ph_f)
X_ex =
-0.7049 1.3229 -0.7501 -0.0275 3.4553 -0.4563
0.8029 -0.4669 1.3345 2.6822 0.2942 -0.6431
-0.3228 -0.1699 0.0159 1.9408 -0.8317 -0.6652
-0.5139 -0.5316 1.7985 -2.6426 2.3228 -1.1011
-0.0719 -0.3853 -0.3498 0.8617 -1.5182 0.9805
0.4289 1.2715 0.0501 -1.3336 -0.3510 -0.5748
確認用に元のXで該当する部分だけを見てみましょう
X.*A
  6 Comments
Hernia Baby
Hernia Baby on 20 Mar 2021
K.S.
K.S. on 21 Mar 2021
ありがとうございます!!!!!
こちらも、いくつか実行時エラーが出てきていましたので事前に領域区分した状態で数値が存在している部分を探索するようなコードを記述して解決してきました。まだ、Hernia様のコードは確認できておりませんが、取り急ぎお礼のご連絡まで。

Sign in to comment.

More Answers (0)

Categories

Find more on Shifting and Sorting Matrices in Help Center and File Exchange

Products


Release

R2020a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!