MATLAB Answers

リアルタイムで目を認​識して,認識した時に​スクリーンショットを​取りたい

8 ビュー (過去 30 日間)
tsuyoshi tsunoda
tsuyoshi tsunoda 2021 年 5 月 11 日
コメント済み: tsuyoshi tsunoda 2021 年 5 月 12 日
パソコンのカメラのリアルタイム表示映像から目を認識させ,認識したら静止画を取得するプログラムを作成しようとしているのですが,
リアルタイム表示で目を認識させるところまでは出来たのですが,そこからどのようにしたらいいか分かりません.
% Create the face detector object.
eyeDetector=vision.CascadeObjectDetector('EyePairBig');
% Create the point tracker object.
pointTracker = vision.PointTracker('MaxBidirectionalError', 2);
% Create the webcam object.
cam = webcam();
% Capture one frame to get its size.
videoFrame = snapshot(cam);
frameSize = size(videoFrame);
% Create the video player object.
videoPlayer = vision.VideoPlayer('Position', [100 100 [frameSize(2), frameSize(1)]+30]);
runLoop = true;
numPts = 0;
frameCount = 0;
while runLoop && frameCount < 400
% Get the next frame.
videoFrame = snapshot(cam);
videoFrameGray = rgb2gray(videoFrame);
frameCount = frameCount + 1;
if numPts < 10
% Detection mode.
bboxeye = eyeDetector.step(videoFrameGray);
if ~isempty(bboxeye)
% Find corner points inside the detected region.
points = detectMinEigenFeatures(videoFrameGray, 'ROI', bboxeye(1, :));
% Re-initialize the point tracker.
xyPoints = points.Location;
numPts = size(xyPoints,1);
release(pointTracker);
initialize(pointTracker, xyPoints, videoFrameGray);
% Save a copy of the points.
oldPoints = xyPoints;
% Convert the rectangle represented as [x, y, w, h] into an
% M-by-2 matrix of [x,y] coordinates of the four corners. This
% is needed to be able to transform the bounding box to display
% the orientation of the face.
bboxPoints = bbox2points(bboxeye(1, :));
% Convert the box corners into the [x1 y1 x2 y2 x3 y3 x4 y4]
% format required by insertShape.
bboxPolygon = reshape(bboxPoints', 1, []);
% Display a bounding box around the detected face.
videoFrame = insertShape(videoFrame, 'Polygon', bboxPolygon, 'LineWidth', 3);
% Display detected corners.
videoFrame = insertMarker(videoFrame, xyPoints, '+', 'Color', 'white');
end
else
% Tracking mode.
[xyPoints, isFound] = step(pointTracker, videoFrameGray);
visiblePoints = xyPoints(isFound, :);
oldInliers = oldPoints(isFound, :);
numPts = size(visiblePoints, 1);
if numPts >= 10
% Estimate the geometric transformation between the old points
% and the new points.
[xform, inlierIdx] = estimateGeometricTransform2D(...
oldInliers, visiblePoints, 'similarity', 'MaxDistance', 4);
oldInliers = oldInliers(inlierIdx, :);
visiblePoints = visiblePoints(inlierIdx, :);
% Apply the transformation to the bounding box.
bboxPoints = transformPointsForward(xform, bboxPoints);
% Convert the box corners into the [x1 y1 x2 y2 x3 y3 x4 y4]
% format required by insertShape.
bboxPolygon = reshape(bboxPoints', 1, []);
% Display a bounding box around the face being tracked.
videoFrame = insertShape(videoFrame, 'Polygon', bboxPolygon, 'LineWidth', 3);
% Display tracked points.
videoFrame = insertMarker(videoFrame, visiblePoints, '+', 'Color', 'white');
% Reset the points.
oldPoints = visiblePoints;
setPoints(pointTracker, oldPoints);
end
end
% Display the annotated video frame using the video player object.
step(videoPlayer, videoFrame);
% Check whether the video player window has been closed.
runLoop = isOpen(videoPlayer);
end
% Clean up.
clear cam;
release(videoPlayer);
release(pointTracker);
release(eyeDetector);
分かる方がいらっしゃったら教えていただきたいです.
  2 件のコメント
Atsushi Ueno
Atsushi Ueno 2021 年 5 月 11 日
>(目を)認識したら静止画を取得する
一番外側のループ処理内で「静止画の取得」を実施しています
% Get the next frame.
videoFrame = snapshot(cam);
「目を認識した時」=「認識した特徴点(numPts)が10個以上になった時」の静止画(videoFrame)を取得すれば良いのですね。

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

採用された回答

Atsushi Ueno
Atsushi Ueno 2021 年 5 月 12 日
静止画をPCのフォルダ内に保存する※この回答を適用する場合、前回の回答の適用は不要です
snapshot関数はRGB配列データを出力し、imshow関数などで表示できる事が分かりました。動作確認していませんがimwrite関数でグラフィックスファイルに書き込めると思います。
imwrite(videoFrame,'C:\Users\%USERNAME%\Desktop\eye_snapshot.png');
問題は静止画の保存をどのタイミングで実行するかです。画像から抽出した特徴点が10個未満の時は検出モードを実行し続けますが、検出モード内で抽出した特徴点が10個以上と判った時点で、その静止画を保存すれば良いと思います。特徴点が10個以上検出されたので次のフレームからは特徴点が10個未満に減るまで追跡モードでトラッキング処理されます。その間は静止画保存は行いません。
% Re-initialize the point tracker.
xyPoints = points.Location;
numPts = size(xyPoints,1);
if numPts >= 10 % save snapshot into a PNG file. ←ここからの部分を追加する
imwrite(videoFrame,'C:\Users\%USERNAME%\Desktop\eye_snapshot.png');% パスは適宜変えてください
end % ←ここまでの部分を追加する
release(pointTracker);
initialize(pointTracker, xyPoints, videoFrameGray);
具体的な動作イメージ例:対象画像に映る目が3回瞬きする場合、4枚の静止画が保存される(瞬きをするまでトラッキングが外れないと仮定した場合)(下記プログラムではファイル名を変更しないので上書きされます)
  1 件のコメント
tsuyoshi tsunoda
tsuyoshi tsunoda 2021 年 5 月 12 日
とても分かりやすく,関数や参考サイトまでも
教えていただきありがとうございます.
やりたかった事が出来るようになりました.

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

その他の回答 (1 件)

Atsushi Ueno
Atsushi Ueno 2021 年 5 月 11 日
「目を認識した時」=「認識した特徴点(numPts)が10個以上になった時」に、静止画(videoFrame)を別の変数にコピーする処理です。
else
detectedFrame = videoFrame;
% Tracking mode.
現状のプログラムは、目を認識したら認識モードから追跡モードに移り、特徴点(numPts)が10個未満に減るまで追跡モードの処理を続け、その結果動画が表示されてしまい、目的の静止画情報(videoFrame)はそのまま次のフレームに流れ消えてしまいます。
上記処理を加えれば、目を認識した時の静止画(detectedFrame)が、次に目を認識する時まで保持されています。
  3 件のコメント
Atsushi Ueno
Atsushi Ueno 2021 年 5 月 12 日
もちろんデータが在るので保存する事は出来ますよ。
私はcomputer vision toolboxを持ってないので動作確認できませんが、関数の仕様を調べてやってみます。

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

Community Treasure Hunt

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

Start Hunting!