Main Content

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

ライブ ビデオ取得を使用した、顔の検出と追跡

この例では、KLT アルゴリズムを使用してライブ ビデオ ストリーム内の顔を自動的に検出し追跡する方法を説明します。

概要

オブジェクトの検出と追跡は、アクティビティ認識、自動車安全性、監視など、多くのコンピューター ビジョン アプリケーションにおいて重要です。この例では、Web カメラでキャプチャしたライブ ビデオ ストリーム中の 1 つの顔を追跡する、シンプルなシステムを作成します。MATLAB は、ハードウェア サポート パッケージによって Web カメラのサポートを提供しています。この例を実行するには、このパッケージをダウンロードしてインストールする必要があります。サポート パッケージはサポート パッケージ インストーラーから入手できます。

この例の顔追跡システムは、検出と追跡という 2 つのモードのうちいずれかの状態にあります。検出モードでは、vision.CascadeObjectDetector オブジェクトを使用して現在のフレーム内にある顔を検出できます。顔が検出された場合、顔のコーナー ポイントを検出し、vision.PointTracker オブジェクトを初期化してから、追跡モードに切り替えなければなりません。

追跡モードでは、ポイント トラッカーを使用して点を追跡しなければなりません。点を追跡する時に、それらのいくつかはオクルージョンのためになくなります。追跡している点の数がしきい値より低くなると、その顔はもはや追跡されていないことになります。その場合は検出モードに戻って顔を取得し直さなければなりません。

設定

顔の検出、点の追跡、ビデオ フレームの取得と表示を行うオブジェクトを作成します。

% Create the face detector object.
faceDetector = vision.CascadeObjectDetector();

% 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]);

検出と追跡

顔を検出し追跡するため、ループを使って Web カメラからビデオ フレームをキャプチャし、処理します。ループは 400 フレーム分、あるいはビデオ プレーヤーのウィンドウが閉じるまで実行されます。

runLoop = true;
numPts = 0;
frameCount = 0;

while runLoop && frameCount < 400

    % Get the next frame.
    videoFrame = snapshot(cam);
    videoFrameGray = im2gray(videoFrame);
    frameCount = frameCount + 1;

    if numPts < 10
        % Detection mode.
        bbox = faceDetector.step(videoFrameGray);

        if ~isempty(bbox)
            % Find corner points inside the detected region.
            points = detectMinEigenFeatures(videoFrameGray, 'ROI', bbox(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(bbox(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, '+', 'MarkerColor', '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] = estgeotform2d(...
                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, '+', 'MarkerColor', '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(faceDetector);

参考文献

Viola, Paul A. and Jones, Michael J. "Rapid Object Detection using a Boosted Cascade of Simple Features", IEEE CVPR, 2001.

Bruce D. Lucas and Takeo Kanade. An Iterative Image Registration Technique with an Application to Stereo Vision. International Joint Conference on Artificial Intelligence, 1981.

Carlo Tomasi and Takeo Kanade. Detection and Tracking of Point Features. Carnegie Mellon University Technical Report CMU-CS-91-132, 1991.

Jianbo Shi and Carlo Tomasi. Good Features to Track. IEEE Conference on Computer Vision and Pattern Recognition, 1994.

Zdenek Kalal, Krystian Mikolajczyk and Jiri Matas. Forward-Backward Error: Automatic Detection of Tracking Failures. International Conference on Pattern Recognition, 2010