「検出した枠や線」の中点や距離を測定する

8 views (last 30 days)
tsuyoshi tsunoda
tsuyoshi tsunoda on 25 Dec 2021
Commented: tsuyoshi tsunoda on 26 Dec 2021
分からない部分が多く、一つの質問でまとめて失礼します。
現在、両目を検出後、目の枠を3分割して1コマ目と3コマ目を目として設定しています。
「両目を検出した枠の重心(目の1コマ目と3コマ目の重心を結んだ中点)から垂線をおろした線の追加」
「顔検出した枠の両サイドの線から垂線がどれぐらいの距離があるのか」
という事をやりたいです。イメージは画像のようにピンクの線の部分を出来るようにしたいです。
プログラムの間違っているとこも含めてご教授願います。
I = imread('画像');
for Obj = {'FrontalFaceCART','EyePairBig'} % 学習済カスケード分類モデル毎に繰り返す
ObjDet = vision.CascadeObjectDetector(Obj{:}); % カスケード検出器のオブジェクト作成
ObjBox = ObjDet(I); % 検出枠の[x, y, width, height]情報
if(~strcmp(Obj,'FrontalFaceCART')) % 顔の検出時以外に行う処理
I = insertObjectAnnotation(I, 'rectangle', ObjBox, Obj,'FontSize',48); % 画像に検出枠を追記
end
if(strcmp(Obj,'EyePairBig')) % 両目の検出時に行う処理
for wd = 0:1
EyeBox = [ObjBox(:,1)+ObjBox(:,3)*(wd*2)/3, ObjBox(:,2), ObjBox(:,3)/3, ObjBox(:,4)];
EyeCen = get_centroid(EyeBox); % 検出枠の重心[x,y]座標
I = insertShape(I,'rectangle', EyeBox, 'Color', 'red', 'LineWidth', 3);
I = insertShape(I, 'FilledCircle', [EyeCen ones(size(ObjBox,1),1)*5]);
end
end
release(ObjDet);
end
imshow(I)
function Center = get_centroid(xywh) % 検出枠の重心[x,y]座標を求める
Center = [xywh(:,1) + xywh(:,3)/2, xywh(:,2) + xywh(:,4)/2];
end
  2 Comments
tsuyoshi tsunoda
tsuyoshi tsunoda on 26 Dec 2021
そのような課題があるのですね
「両目検出した枠」と「顔検出した枠」の対応についてですが、「両目検出した枠」の中点の部分が「顔検出した枠」の内側にあれば良いと考えています。
2つ目の課題に対しては、どのくらいの精度で可能なのかを試してみたいため、どんな結果でも良いのでお力添えいただければ幸いです。

Sign in to comment.

Accepted Answer

Atsushi Ueno
Atsushi Ueno on 26 Dec 2021
Edited: Atsushi Ueno on 26 Dec 2021
上記回答に加え距離を求める要求事項を反映しました。
>「両目を検出した枠の重心(目の1コマ目と3コマ目の重心を結んだ中点)から垂線をおろした線の追加」
上記回答のコメントを反映し、更に重心を求める関数get_centroid()に置き換えました。
>「顔検出した枠の両サイドの線から垂線がどれぐらいの距離があるのか」
inRectangle関数を作成し、中でinpolygon関数を使いました。
I = imread('画像');
for Obj = {'FrontalFaceCART','EyePairBig'} % 学習済カスケード分類モデル毎に繰り返す
ObjDet = vision.CascadeObjectDetector(Obj{:}); % カスケード検出器のオブジェクト作成
ObjBox = ObjDet(I); % 検出枠の[x, y, width, height]情報
if(strcmp(Obj,'FrontalFaceCART'))
FaceBox = ObjBox; % 顔の検出枠は目の重心と比較する為に保存しておく
end
I = insertObjectAnnotation(I, 'rectangle', ObjBox, Obj,'FontSize',10); % 画像に検出枠を追記
if(strcmp(Obj,'EyePairBig')) % 両目の検出時に行う処理
ObjCen = get_centroid(ObjBox); %「両目を検出した枠の重心から垂線をおろした線の追加
I = insertShape(I,'Line', [ObjCen ObjCen(:,1) ObjCen(:,2)+100], 'Color', 'magenta', 'LineWidth', 5); %%%%%%%%%%%%%%%
%「両目検出した枠」の中点の部分が「顔検出した枠」の内側にあるか判定し、左右端との距離を求める
[row, ~] = find(inRectangle(ObjCen, FaceBox));
distance = [ObjCen(:,1)-FaceBox(row,1) FaceBox(row,1)+FaceBox(row,3)-ObjCen(:,1)]
for wd = 0:1
EyeBox = [ObjBox(:,1)+ObjBox(:,3)*(wd*2)/3, ObjBox(:,2), ObjBox(:,3)/3, ObjBox(:,4)];
EyeCen = get_centroid(EyeBox); % 検出枠の重心[x,y]座標
I = insertShape(I,'rectangle', EyeBox, 'Color', 'red', 'LineWidth', 3);
I = insertShape(I, 'FilledCircle', [EyeCen ones(size(ObjBox,1),1)*5]);
end
end
release(ObjDet);
end
imshow(I)
function Center = get_centroid(xywh) % 検出枠の重心[x,y]座標を求める
Center = [xywh(:,1) + xywh(:,3)/2, xywh(:,2) + xywh(:,4)/2];
end
function in = inRectangle(Cen, BBox) % 中心点[x1,y1;x2,y2;...]と検出枠[x1,y1,w1,h1;x2,y2,w2,h2;...]の内外判定
for k = 1:size(BBox,1)
x = [BBox(k,1) BBox(k,1)+BBox(k,3) BBox(k,1)+BBox(k,3) BBox(k,1)];
y = [BBox(k,2) BBox(k,2) BBox(k,2)+BBox(k,4) BBox(k,2)+BBox(k,4)];
in(k,:) = inpolygon(Cen(:,1), Cen(:,2), x, y);
end
end
  1 Comment
tsuyoshi tsunoda
tsuyoshi tsunoda on 26 Dec 2021
ここまでまとめていただきありがとうございます。
プログラムの理解をしながら進めていこうと思います。

Sign in to comment.

More Answers (1)

Atsushi Ueno
Atsushi Ueno on 26 Dec 2021
>「両目を検出した枠の重心(目の1コマ目と3コマ目の重心を結んだ中点)から垂線をおろした線の追加」
→下記のコードをfor文内(13行目)に追記すれば追加されます
if wd % 「両目を検出した枠の重心(目の1コマ目と3コマ目の重心を結んだ中点)から垂線をおろした線の追加」
EyeLin = [(EyeCen(:,1)+oldEyeCen(:,1))/2, (EyeCen(:,2)+oldEyeCen(:,2))/2];
I = insertShape(I,'Line', [EyeLin EyeLin(:,1) EyeLin(:,2)+100], 'Color', 'magenta', 'LineWidth', 5);
else
oldEyeCen = EyeCen;
end
  1 Comment
Atsushi Ueno
Atsushi Ueno on 26 Dec 2021
>「両目を検出した枠の重心(目の1コマ目と3コマ目の重心を結んだ中点)から垂線をおろした線の追加」
→「両目を検出した枠の重心」と「目の1コマ目と3コマ目の重心を結んだ中点」は同じです。
  下記の方がよりシンプルで両目分のfor文に入れる必要も無くなりますね。
if(strcmp(Obj,'EyePairBig')) % 両目の検出時に行う処理
% 「両目を検出した枠の重心から垂線をおろした線の追加
EyeLin = [ObjBox(:,1)+ObjBox(:,3)/2, ObjBox(:,2)+ObjBox(:,4)/2];
I = insertShape(I,'Line', [EyeLin EyeLin(:,1) EyeLin(:,2)+100], 'Color', 'magenta', 'LineWidth', 5);

Sign in to comment.

Tags

Community Treasure Hunt

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

Start Hunting!