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

조회 수: 1 (최근 30일)
tsuyoshi tsunoda
tsuyoshi tsunoda 2021년 12월 25일
댓글: tsuyoshi tsunoda 2021년 12월 26일
分からない部分が多く、一つの質問でまとめて失礼します。
現在、両目を検出後、目の枠を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
Atsushi Ueno
Atsushi Ueno 2021년 12월 26일
>「顔検出した枠の両サイドの線から垂線がどれぐらいの距離があるのか」
こちらは複数の課題がありますね
  • 「両目検出した枠」と「顔検出した枠」の対応(単純に「前者が後者の内部なら対応」で良いか)
  • 「顔検出した枠の両サイド」は必ずしも顔の端に沿っている訳でなないので要求を満足するか疑問
tsuyoshi tsunoda
tsuyoshi tsunoda 2021년 12월 26일
そのような課題があるのですね
「両目検出した枠」と「顔検出した枠」の対応についてですが、「両目検出した枠」の中点の部分が「顔検出した枠」の内側にあれば良いと考えています。
2つ目の課題に対しては、どのくらいの精度で可能なのかを試してみたいため、どんな結果でも良いのでお力添えいただければ幸いです。

댓글을 달려면 로그인하십시오.

채택된 답변

Atsushi Ueno
Atsushi Ueno 2021년 12월 26일
편집: Atsushi Ueno 2021년 12월 26일
上記回答に加え距離を求める要求事項を反映しました。
>「両目を検出した枠の重心(目の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
tsuyoshi tsunoda
tsuyoshi tsunoda 2021년 12월 26일
ここまでまとめていただきありがとうございます。
プログラムの理解をしながら進めていこうと思います。

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Atsushi Ueno
Atsushi Ueno 2021년 12월 26일
>「両目を検出した枠の重心(目の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
Atsushi Ueno
Atsushi Ueno 2021년 12월 26일
>「両目を検出した枠の重心(目の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);

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Eye Tracking에 대해 자세히 알아보기

태그

Community Treasure Hunt

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

Start Hunting!