画像内の各色毎の割合算出方法について

15 views (last 30 days)
Kogalab
Kogalab on 23 Nov 2021
Commented: Kogalab on 1 Dec 2021
深層学習を使用したセマンティックセグメンテーションでの画像のセグメント後に、各ラベル毎の画像内に占める割合を算出したいのですが方法がわかりません。解決策がありましたらご回答の程よろしくお願い致します。

Accepted Answer

Atsushi Ueno
Atsushi Ueno on 27 Nov 2021
Edited: Atsushi Ueno on 28 Nov 2021
まず、質問のリンク先から入力データ(画像2枚とピクセルラベルイメージデータ2枚の計4枚)を抜き出し、これらをイメージデータストア、ピクセルラベルデータストアとして読み込み、「深層学習を使用したセマンティックセグメンテーションでの画像のセグメント後」の例を作成しました。
mkdir labels % ピクセルラベルイメージデータ格納用のフォルダを作成(画像はカレントフォルダ)
movefile 0016E5_08430_L.png labels % ピクセルラベルイメージデータをlabelsフォルダに移動
movefile Seq05VD_f00840_L.png labels % ピクセルラベルイメージデータをlabelsフォルダに移動
cmap = [128 128 128;128 0 0;192 192 192;128 64 128;60 40 222;128 128 0;192 128 128;64 64 128;64 0 128;64 64 0;0 128 192] ./ 255;
classes = ["Sky" "Building" "Pole" "Road" "Pavement" "Tree" "SignSymbol" "Fence" "Car" "Pedestrian" "Bicyclist"];
labelIDs = {[128 128 128] [000 128 064; 128 000 000; 064 192 000; 064 000 064; 192 000 128] [192 192 128; 000 000 064] [128 064 128; 128 000 192; 192 000 064] [000 000 192; 064 192 128; 128 128 192] [128 128 000; 192 192 000] [192 128 128; 128 128 064; 000 064 064] [064 064 128] [064 000 128; 064 128 192; 192 128 192; 192 064 128; 128 064 064] [064 064 000; 192 128 064; 064 000 192; 064 128 064] [000 128 192; 192 000 192]};
imds = imageDatastore(pwd); % 添付した'Seq05VD_f00840.png'と'0016E5_08430.png'を読む
pxds = pixelLabelDatastore([pwd '/labels'],classes,labelIDs); % 添付した'Seq05VD_f00840_L.png'と'0016E5_08430_L.png'を読む
質問のリンク先における「データセット統計の解析」の内容を、データセットを分割し画像1枚分毎に実行しました。countEachLabel関数により各ラベル毎の画像内に占める割合を算出しました。
n = numpartitions(pxds);
for i = 1:n
subimds = partition(imds,n,i); % データセットを分割し1枚ずつ取り出す
subpxds = partition(pxds,n,i); % データセットを分割し1枚ずつ取り出す
I = histeq(readimage(subimds,1)); % 元画像の読み込みとコントラスト加工
C = readimage(subpxds,1); % ピクセルラベルイメージデータの読み込み
B = labeloverlay(I,C,'ColorMap',cmap); % 重ねる
figure; imshow(B); colormap(gca,cmap); % 表示する
c = colorbar('peer', gca); c.TickLabels = classes; numClasses = size(cmap,1); c.Ticks = 1/(numClasses*2):1/numClasses:1; c.TickLength = 0;
% ===================================================================================
% ここから下が、countEachLabel関数により各ラベル毎の画像内に占める割合を算出する方法です。
tbl = countEachLabel(subpxds) % 各ラベル毎の画素数及び画像全体の画素数を出力する
frequency = tbl.PixelCount/sum(tbl.PixelCount); % 各ラベル毎の画像内に占める割合を計算
figure; bar(1:numel(classes),frequency); % 表示する
xticks(1:numel(classes)); xticklabels(tbl.Name); xtickangle(45); ylabel('Frequency');
end
tbl = 11×3 table
Name PixelCount ImagePixelCount ______________ __________ _______________ {'Sky' } 39444 6.912e+05 {'Building' } 3.0893e+05 6.912e+05 {'Pole' } 6367 6.912e+05 {'Road' } 2.5472e+05 6.912e+05 {'Pavement' } 31607 6.912e+05 {'Tree' } 0 0 {'SignSymbol'} 7702 6.912e+05 {'Fence' } 0 0 {'Car' } 12009 6.912e+05 {'Pedestrian'} 11762 6.912e+05 {'Bicyclist' } 12914 6.912e+05
tbl = 11×3 table
Name PixelCount ImagePixelCount ______________ __________ _______________ {'Sky' } 1.0242e+05 6.912e+05 {'Building' } 2.719e+05 6.912e+05 {'Pole' } 7721 6.912e+05 {'Road' } 1.9967e+05 6.912e+05 {'Pavement' } 69511 6.912e+05 {'Tree' } 7458 6.912e+05 {'SignSymbol'} 4396 6.912e+05 {'Fence' } 7719 6.912e+05 {'Car' } 2292 6.912e+05 {'Pedestrian'} 2509 6.912e+05 {'Bicyclist' } 591 6.912e+05
  1 Comment
Kogalab
Kogalab on 1 Dec 2021
Ueno様
ご回答いただきありがとうございます、理解することができました。
またなにかありましたらご相談に乗っていただけると幸いです。

Sign in to comment.

More Answers (1)

Kogalab
Kogalab on 28 Nov 2021
Edited: Kogalab on 28 Nov 2021
Ueno様
ご回答ありがとうございます。データセット内の割合を算出する方法が理解できました。
追加で質問させていただいてもよろしいでしょうか。上記の方法はデータセット内全ての画像のラベル割合を算出する方法だと思うのですが、学習後のネットワークを用いて任意の画像一枚のみの割合を算出するにはどうすればよろしいでしょうか。
任意の画像をセグメント化し、Skyに当たる部分の割合を算出しようと以下のコードを実行しました。
%画像のセグメント化
x=imread('SS写真ex.jpg');
xx=imresize(x,[720 960]);
z=semanticseg(xx,net);
y=labeloverlay(xx,z,'Colormap',cmap,'transparency',0);
figure,imshow(y)
pixelLabelColorbar(cmap,classes);
%skyの割合算出
skyClassIds = uint8([1]);
skyPixels = ismember(y(:),skyClassIds);
validPixels = (y~=0);
numskyPixels = sum(skyPixels(:));
numValidPixels = sum(validPixels(:));
percentskyCover = (numskyPixels/numValidPixels)*100;
fprintf('The percentage of sky cover is %3.2f%%.',percentskyCover);
実行結果はThe percentage of sky cover is 0.08%.>>となるのですが、セグメント後の画像を見るに割合が合っていないと思います。これはSkyのラベルIDが1ではないからなのでしょうか。
  2 Comments
Atsushi Ueno
Atsushi Ueno on 28 Nov 2021
私はMATLAB Answersのlive editorで実行する事だけを考えた為、その点回答を端折ってしまいました。countEachLabel関数の対象は(イメージ)データストアです。画像1枚分のデータストアに対しては1枚分の結果を表示します。しかしそれでは本質問の主旨に対する回答になりませんよね。
質問の趣旨(複数の画像が含まれるデータストアの処理に関して、画像1枚だけの結果を表示したい)に対しては、データストアを分割する必要があります。その点後ほど1番目の回答に追記致します。
Atsushi Ueno
Atsushi Ueno on 29 Nov 2021
そうですね。下記のように色々と疑問点があります。
skyClassIds = uint8([1]); これはSkyのラベルID1ではないからなのでしょうか⇒そう思います
skyPixels = ismember(y(:),skyClassIds); 画素値とクラスIDを比較する根拠は?
validPixels = (y~=0); ← 単に縦×横で良く、画素値=0を除く必要は無いのでは?
numskyPixels = sum(skyPixels(:))   ← カラー画像なので3倍の値になる
numValidPixels = sum(validPixels(:)) ← カラー画像なので3倍の値になる
せっかくImage Processing Toolboxを使ってるのですから、回答に挙げたcountEachLabel関数を使うのはいかがでしょうか。

Sign in to comment.

Categories

Find more on 深層学習、セマンティック セグメンテーション、検出 in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!