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

조회 수: 5(최근 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!