指定した領域で輝度値の平均と最大値を求める.

イメージにおいて,領域を指定してそこでの輝度値の平均・最大値を求めるにはどうすればよいでしょうか.
この領域とは,以下のプログラムを実行して得られた円形領域です.
data = ['42deg_cam1_ (12).jpg']; % ここでファイル名を変える
pic = imread(data);
gray = rgb2gray(pic);
bw = imbinarize(gray);
bw2 = bwareaopen(bw,30); % ノイズ除去,例として30ピクセル以下
[B,L] = bwboundaries(bw2,'noholes');
figure; % imshowはfigureの全画素を更新,hold onの効果なし,新しくfigureを立ち上げる
C = label2rgb(L,@jet,[.5 .5 .5]);
imshow(C);
hold on
for k = 1:length(B) % 境界線と色分け
boundary = B{k};
plot(boundary(:,2),boundary(:,1),'w','LineWidth',2)
end
stats = regionprops(L,'Area','Centroid'); % ここから円形オブジェクトの検出コマンド
threshold = 0.80; % 閾値(円で1,他は1未満)
for k = 1:length(B)
boundary = B{k};
delta_sq = diff(boundary).^2;
perimeter = sum(sqrt(sum(delta_sq,2)));
area = stats(k).Area;
metric = 4*pi*area/perimeter^2;
metric_string = sprintf('%2.2f',metric);
if metric > threshold
centroid = stats(k).Centroid;
plot(centroid(1),centroid(2),'ko');
end
text(boundary(1,2)-35,boundary(1,1)+13,metric_string,'Color','y',...
'FontSize',14,'FontWeight','bold')
end

2 Commenti

Atsushi Ueno
Atsushi Ueno il 1 Ott 2021
もう少し背景情報を加えて頂けるとより的確な回答に繋がります。
タグに記載された"sprintf", "bordaries"(?)との関連性も良く分かりません。
Egoshi
Egoshi il 5 Ott 2021
Ueno様,失礼しました.
質問文を更新いたしました.よろしくお願いいたします.

Accedi per commentare.

 Risposta accettata

Y Nakanishi
Y Nakanishi il 1 Ott 2021
Modificato: Y Nakanishi il 1 Ott 2021

2 voti

イメージの領域を指定する方法として,関心領域(ROI)で切り抜くことができます.以下のコードでは,インタラクティブな画面でのROI取得と表示を行い,グレースケール化した領域の輝度値の平均と最大値を求めるコードを示しています.
なお,切り抜く対象の領域がすでに決定済みである場合は,ROIベース処理の項目が参考になるかと思います.
3行目のdrawrectangle関数で行っている処理を適宜変更することで他の図形や,すでに決定している領域の選択が可能です.
取得したROIの領域を用いてimcrop関数で領域のみの処理を行うために切り抜きを行い,イメージをグレースケール画像へ変換しています.
グレースケールへ変換するrgb2gray関数は,輝度を保持したまま色相情報と彩度情報を削除する関数になります.
そのため,グレースケール化した画像の持つ画素値を平均することによって輝度値の平均(meanLuminance),最大値を求めることによって輝度値の最大値(maxLuminance)を求めることが可能です.
I = imread('pears.png'); % イメージのロード
imshow(I) % オリジナル画像の表示
roi = drawrectangle('StripeColor','y'); % 四角形領域でのROI
cropimg = imcrop(I,roi.Position); % 指定領域での切り抜き
imshow(cropimg) % 指定領域で切り抜いた画像の表示
grayimg = rgb2gray(cropimg); % クロップ画像のグレースケール化
meanLuminance = mean(grayimg,'all') % 平均輝度値
maxLuminance = max(grayimg,[],'all') % 最大輝度値

6 Commenti

Egoshi
Egoshi il 5 Ott 2021
ありがとうございます,これはdrawfreehandを使用できますか?
Y Nakanishi
Y Nakanishi il 5 Ott 2021
更新されましたコードについて拝見しました.
drawfreehandでも可能だと思いますが,コード中に含まれるbwboundariesにて取得された領域のアウトラインを利用することで切り出すことが可能であると思われます.次のBは画像中における指定した領域のアウトラインをcell配列(xとyの座標)として複数保持しているため,こちらを利用してみるのはいかがでしょうか.
[B,L] = bwboundaries(bw2,'noholes');
以下に1つだけ切り出した場合における例を示します.
この際に,領域外の0埋めされた箇所である輝度値0に当たる部分については,https://jp.mathworks.com/matlabcentral/answers/860935- こちらのAnswerで示されている手法にて除外することが可能ですので,こちらを参照すると良いかと思われます.
data = ['42deg_cam1_ (12).jpg']; % ここでファイル名を変える
pic = imread(data);
gray = rgb2gray(pic);
bw = imbinarize(gray);
bw2 = bwareaopen(bw,30); % ノイズ除去,例として30ピクセル以下
[B,L] = bwboundaries(bw2,'noholes');
roi = roipoly(bw2,B{1,1}(:,2),B{1,1}(:,1)) % 例として1つ目を切り出す(logical)
imshow(roi);
r = gray;
r(~roi) = 0;
figure(); imshow(r)
Egoshi
Egoshi il 6 Ott 2021
ありがとうございます,私が実現したいものにかなり近づきました.
例として1つ目とありますが,何基準の1つ目なのでしょうか.
これをi番目とすることは可能でしょうか.
Egoshi
Egoshi il 6 Ott 2021
補足しますと,i枚のイメージをまとめて処理するとき,i番目の領域の輝度値が求めるようなコードを書きたいと思っています.
Y Nakanishi
Y Nakanishi il 7 Ott 2021
> 例として1つ目とありますが,何基準の1つ目なのでしょうか.
bwboundariesによる検出順の1つ目になります.具体的にはドキュメントのアルゴリズムを参照になると良いと思います.
i番目の領域を処理するのであればfor文やif文を用いて別途指定することで選択できると思います.
[B,L,n,A] = bwboundaries(___)
のnは,検出した数となるため,これをもちいてfor i = 1:nのようにn個分画像処理したのちに,i番目のもののみを抜き出した上で,輝度値を求めると良いのではないでしょうか.
参考になれば幸いです.
Egoshi
Egoshi il 8 Ott 2021
Nakanishi 様,何回もご丁寧にご教授くださり,ありがとうございます.
参考にさせていただきます.

Accedi per commentare.

Più risposte (0)

Prodotti

Release

R2019a

Community Treasure Hunt

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

Start Hunting!