白黒画像における領域の検知方法について

6 views (last 30 days)
雅晶
雅晶 on 31 Oct 2022
Commented: 雅晶 on 1 Nov 2022
上記のような BW という白黒の図から白の領域を検知するために、以下のようなスクリプトを作成したのですが、
%% find bound area
BW = bwselect(BW,1:size(BW,2),ones(1,size(BW,2)),4);
BW = bwselect(BW,1:size(BW,2),ones(1,size(BW,2))*size(BW,1),4);
figure
[B,L,N,A] = bwboundaries(BW);
imshow(BW); hold on;
colors=['g' 'b' 'r' 'y' 'm' 'c'];
for k=1:length(B)
boundary = B{k};
cidx = mod(k,length(colors))+1;
plot(boundary(:,2), boundary(:,1),...
colors(cidx),'LineWidth',2);
rndRow = ceil(length(boundary)/(mod(rand*k,7)+1));
col = boundary(rndRow,2); row = boundary(rndRow,1);
h = text(col+1, row-1, num2str(L(row,col)));
set(h,'Color',colors(cidx),'FontSize',14,'FontWeight','bold');
end
上記の図にある1つ目の白黒画像は無事領域が検知できたのに対し、2つ目の白黒画像は検知できませんでした。
その理由とどうすれば検知できるようになるのか教えていただきたいです。
  1 Comment
Hernia Baby
Hernia Baby on 31 Oct 2022
画像添付できますでしょうか?試してみたいです。

Sign in to comment.

Accepted Answer

Atsushi Ueno
Atsushi Ueno on 31 Oct 2022
1つ目の白黒画像は領域が検知できた理由bwselect関数によって白い連続領域を全て検出出来たから
下記のプログラムは、白黒画像の上端および下端(青い線)と重なる「白ピクセルの繋がり」を含むバイナリイメージを返します。千切れた領域がある様にも見えますが、白い領域は全て連結しているので、2つのbwselect関数に対する入力と出力は全て同じ画像になります。
%% find bound area
BW = bwselect(BW,1:size(BW,2),ones(1,size(BW,2)),4);
BW = bwselect(BW,1:size(BW,2),ones(1,size(BW,2))*size(BW,1),4);
2つ目の白黒画像は領域が検知できなかった理由bwselect関数によって白い連続領域を一つも検出出来なかったから
2つ目の白黒画像に対する上記プログラムを実行した結果、同一サイズで真っ黒な画像が出力されました。真っ黒な画像に対して続く境界の検出や表示処理を行っても何も表示されません。
正確には、1行目を実行した直後は下右図の様に「上端に接する白い連続領域のみの画像」が返されました。では2行目を実行すると「下端に接する白い連続領域のみの画像」が返されるのかというとそうはなりません。なぜなら2行目の入力は1行目の結果(下右図)だからです。入力のBWと出力のBWを同じ変数にすると、入力データを出力データで上書きしてしまいます。これはプログラマの責任で把握出来ていれば問題にはなりませんが、今回の様な問題を避ける為には避けるべき方法です。一般的なコーディング規約でも変数の上書きは避けるべき事とされています。
また、一部の白い領域は当該画像の上端にも下端にも接していない為、この方法では連続体として検出されません。
%% find bound area
BW = bwselect(BW,1:size(BW,2),ones(1,size(BW,2)),4);
BW = bwselect(BW,1:size(BW,2),ones(1,size(BW,2))*size(BW,1),4);
      
どうすれば検知できるようになるのかbwselect関数によって画像外枠の4辺に接する白い連続領域を抽出する
%% find bound area % 上端と下端の2辺⇒画像外枠の4辺に接する白い連続領域を抽出する様に拡張する
[rn,cn] = size(BW);
c = [1:cn,1:cn,ones(1,rn),cn*ones(1,rn)];
r = [ones(1,cn),rn*ones(1,cn),1:rn,1:rn];
BW = bwselect(BW,c,r,4);
 
同じプログラムでどっちも無事領域が検知出来ました。
  1 Comment
雅晶
雅晶 on 1 Nov 2022
非常に丁寧な回答ありがとうございます。参考にさせていただきます。

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!