指定した領域の重心を結んだ中点の検出方法

6 ビュー (過去 30 日間)
tsuyoshi tsunoda
tsuyoshi tsunoda 2022 年 1 月 14 日
コメント済み: tsuyoshi tsunoda 2022 年 1 月 15 日
以下のプログラムはPhotoshopで切り抜いた領域の重心を結んだ三角形を求め顔の向きを検出するプログラムです。
今回、教えて頂きたいのは目の領域の重心同士を結んだ中点(EyeMid)の検出方法です。
目の領域の指定方法等が分からずつまずいてしまいました。ご教授頂きたいです。
%% Photoshop画像読込
Icolor = imread('画像');
I = rgb2gray(Icolor); % グレースケール化
bgc = I(10,10); % 背景色の選択
%% 目と口の重心を求める
BW = I > bgc + 1 | I < bgc - 1; % (ほぼ)背景と背景以外で2値化(imbinarize)
s = regionprops(BW,'centroid'); % イメージ内の連結要素の重心を計算
Areas = regionprops(BW,'Area'); % 各重心位置計算されたエリアの面積
centroids = cat(1,s.Centroid); % 重心を格納する構造体配列を単一の行列に連結
centroids = centroids(cat(1,Areas.Area) > 10, :); % 面積の大きな連結要素のみ選択
%% 目と口の重心点を結んだ三角形の重心を求める
triangle = polyshape(centroids(:,1),centroids(:,2)); % 重心点を結んだ三角形を定義
[trcntx,trcnty] = centroid(triangle); % 三角形の重心
sorted = sort(centroids(:,1)); % 目と口の重心点(x座標)をソート
%% グラフィック表示
imshow(Icolor);
hold on;
plot(triangle);
plot(trcntx,trcnty,'*','Color','w');
if sorted(2) - trcntx < 0 %(口の重心点)-(三角形の重心点)<0 なら右向きと表示
text(trcntx-40,trcnty-350,'右向き','Color','w','FontSize',40);
elseif (-30 < sorted(2) - trcntx) && (sorted(2) - trcntx < 30)
text(trcntx-40,trcnty-350,'正面','Color','w','FontSize',40);
else
text(trcntx-40,trcnty-350,'左向き','Color','w','FontSize',40);
end
hold off;

採用された回答

Atsushi Ueno
Atsushi Ueno 2022 年 1 月 15 日
%% Photoshop画像読込
Icolor = imread('image.png');
I = rgb2gray(Icolor); % グレースケール化
bgc = I(10,10); % 背景色の選択
%% 目と口の重心を求める
BW = I > bgc + 1 | I < bgc - 1; % (ほぼ)背景と背景以外で2値化(imbinarize)
s = regionprops(BW,'centroid'); % イメージ内の連結要素の重心を計算
Areas = regionprops(BW,'Area'); % 各重心位置計算されたエリアの面積
centroids = cat(1,s.Centroid); % 重心を格納する構造体配列を単一の行列に連結
centroids = centroids(cat(1,Areas.Area) > 100, :); % 面積の大きな連結要素のみ選択
EyeIdx = find(centroids(:,2)~=max(centroids(:,2))); % Y座標より目の重心2つを特定する
EyeMid = mean(centroids(EyeIdx,:)); % 目の領域の重心同士を結んだ中点
%% 目と口の重心点を結んだ三角形の重心を求める
triangle = polyshape(centroids(:,1),centroids(:,2)); % 重心点を結んだ三角形を定義
[trcntx,trcnty] = centroid(triangle); % 三角形の重心
sorted = sort(centroids(:,1)); % 目と口の重心点(x座標)をソート
%% グラフィック表示
imshow(Icolor);
hold on;
plot(triangle);
plot(trcntx,trcnty,'*','Color','w');
plot(EyeMid(1),EyeMid(2),'*','Color','w'); % 目の領域の重心同士を結んだ中点
if sorted(2) - trcntx < 0 %(口の重心点)-(三角形の重心点)<0 なら右向きと表示
text(trcntx-40,trcnty-350,'右向き','Color','w','FontSize',40);
elseif (-30 < sorted(2) - trcntx) && (sorted(2) - trcntx < 30)
text(trcntx-40,trcnty-350,'正面','Color','w','FontSize',40);
else
text(trcntx-40,trcnty-350,'左向き','Color','w','FontSize',40);
end
hold off;
【解説】
regionpropsは2値化した画像からあらゆる連続領域を抽出するので、面積の大きさが大きい順に目2つと口を特定します。
目と口の面積はほぼ同じなので、特定された3個の領域の内、重心のY座標が最も大きい領域を口と特定し、口ではない残りの領域2つを目と特定しました。
EyeIdx = find(centroids(:,2)~=max(centroids(:,2))); % Y座標より目の重心2つを特定する
中点は、目の領域の重心2点のX/Y座標の平均値としました。
EyeMid = mean(centroids(EyeIdx,:)); % 目の領域の重心同士を結んだ中点
  1 件のコメント
tsuyoshi tsunoda
tsuyoshi tsunoda 2022 年 1 月 15 日
そのような方法で目として検出すればいいのですね、勉強になりました。
ありがとうございます。

サインインしてコメントする。

その他の回答 (0 件)

タグ

Community Treasure Hunt

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

Start Hunting!