Main Content

CAMShift 法を使用した顔の検出と追跡

この例では、顔の検出と追跡を自動的に行う方法を説明します。

はじめに

オブジェクトの検出と追跡は、アクティビティ認識、自動車安全性、監視など、多くのコンピューター ビジョン アプリケーションにおいて重要です。この例では、追跡問題を 3 つの別々の問題に分けることで、シンプルな顔追跡システムを作成します。

  1. 追跡する顔の検出

  2. 追跡する顔の特徴の識別

  3. 顔の追跡

手順 1: 追跡する顔の検出

顔の追跡を始めるには、その前にまず顔を検出する必要があります。vision.CascadeObjectDetector を使用して、ビデオ フレーム内の顔の位置を検出します。カスケード型オブジェクト検出器では、Viola-Jones 検出アルゴリズムと、検出用に学習済みの分類モデルを使用します。既定では、検出器は顔を検出するよう構成されていますが、他のオブジェクト タイプ用に構成することも可能です。

% Create a cascade detector object.
faceDetector = vision.CascadeObjectDetector();

% Read a video frame and run the detector.
videoFileReader = VideoReader('visionface.avi');
videoFrame      = readFrame(videoFileReader);
bbox            = step(faceDetector, videoFrame);

% Draw the returned bounding box around the detected face.
videoOut = insertObjectAnnotation(videoFrame,'rectangle',bbox,'Face');
figure, imshow(videoOut), title('Detected face');

カスケード型オブジェクト検出器を使用すると、連続するビデオ フレームを通して顔を追跡できます。ただし、顔が傾いたり、その人が振り向いた場合は、追跡できなくなることがあります。この制限は、検出に使用される学習済み分類モデルのタイプが原因で生じます。この問題を避けるために、またすべてのビデオ フレーム内で顔を検出するには計算量が多くなることから、この例ではシンプルな顔の特徴を使って追跡を行います。

手順 2: 追跡する顔の特徴の識別

ビデオ内で顔が見つかったら、次のステップは顔の追跡に役立つ特徴を識別することです。たとえば、形状、テクスチャ、色などを使用できます。そのオブジェクトに固有の、オブジェクトが移動しても変わらない特徴を選択します。

この例では、追跡する特徴として肌の色合いを使用します。肌の色合いは、顔と背景の間に十分なコントラストを提供し、顔の向きが変わったり動いたりしても変わりません。

HSV 色空間に変換されたビデオ フレームから色相を抽出して、肌の色合いの情報を取得します。

[hueChannel,~,~] = rgb2hsv(videoFrame);

% Display the Hue Channel data and draw the bounding box around the face.
figure, imshow(hueChannel), title('Hue channel data');
rectangle('Position',bbox(1,:),'LineWidth',2,'EdgeColor',[1 1 0])

手順 3: 顔の追跡

追跡する特徴として肌の色合いを選択したら、vision.HistogramBasedTracker を使用して追跡を行うことができます。ヒストグラム ベースのトラッカーでは、ピクセル値のヒストグラムを使用してオブジェクトを追跡できる CAMShift アルゴリズムを使用します。この例では、検出した顔の鼻の領域から色相チャネルのピクセルを抽出します。これらのピクセルを使用して、トラッカー用にヒストグラムを初期化します。例ではこのヒストグラムを使用し、連続するビデオ フレームを通してオブジェクトを追跡します。

顔の領域内で鼻を検出します。鼻は背景のピクセルを含まないため、ここから肌の色合いをより正確に測定できます。

noseDetector = vision.CascadeObjectDetector('Nose', 'UseROI', true);
noseBBox     = step(noseDetector, videoFrame, bbox(1,:));

% Create a tracker object.
tracker = vision.HistogramBasedTracker;

% Initialize the tracker histogram using the Hue channel pixels from the
% nose.
initializeObject(tracker, hueChannel, noseBBox(1,:));

% Create a video player object for displaying video frames.
videoPlayer  = vision.VideoPlayer;

% Track the face over successive video frames until the video is finished.
while hasFrame(videoFileReader)

    % Extract the next video frame
    videoFrame = readFrame(videoFileReader);

    % RGB -> HSV
    [hueChannel,~,~] = rgb2hsv(videoFrame);

    % Track using the Hue channel data
    bbox = step(tracker, hueChannel);

    % Insert a bounding box around the object being tracked
    videoOut = insertObjectAnnotation(videoFrame,'rectangle',bbox,'Face');

    % Display the annotated video frame using the video player object
    step(videoPlayer, videoOut);

end

% Release resources
release(videoPlayer);

まとめ

この例では、1 つの顔を自動的に検出して追跡する、シンプルな顔の追跡システムを作成しました。入力ビデオを変更して、顔を追跡できるかどうか試してみてください。良好な追跡結果が得られない場合は、色相チャネルのデータをチェックして、顔の領域と背景の間に十分なコントラストがあるかどうかを確認してください。

参考文献

[1] G.R. Bradski "Real Time Face and Object Tracking as a Component of a Perceptual User Interface", Proceedings of the 4th IEEE Workshop on Applications of Computer Vision, 1998.

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