Main Content

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

混合ガウス モデルを使用した自動車の検出

この例では、混合ガウス モデル (GMM) に基づく前景検出器を使用してビデオ シーケンスから自動車を検出し、その数をカウントする方法を説明します。

はじめに

自動車の検出とカウントは交通パターンの解析に使用できます。検出は、タイプ別に車両の追跡や分類を行う場合など、さらに高度なタスクを実行する前の最初の手順でもあります。

この例では、前景検出器とブロブ解析を使用してビデオ シーケンス内の自動車を検出し、カウントする方法を説明します。カメラは静止しているものと仮定します。この例ではオブジェクトの検出に焦点を当てています。オブジェクトの追跡の詳細については、動きに基づく複数のオブジェクトの追跡という表題の例を参照してください。

手順 1 - ビデオのインポートと前景検出器の初期化

この例では、ビデオ全体を直ちに処理するのではなく、まず最初のビデオ フレームを取得して、動くオブジェクトを背景からセグメント化します。これは、ビデオの処理に使用されるステップを徐々に導入するうえで役立ちます。

前景検出器では、混合ガウス モデルを初期化するために特定数のビデオ フレームが必要です。この例では最初の 50 フレームを使用して、混合モデル内の 3 つのガウス モードを初期化します。

foregroundDetector = vision.ForegroundDetector('NumGaussians', 3, ...
    'NumTrainingFrames', 50);

videoReader = VideoReader('visiontraffic.avi');
for i = 1:150
    frame = readFrame(videoReader); % read the next video frame
    foreground = step(foregroundDetector, frame);
end

学習を行うと、検出器で出力されるセグメンテーションの結果の信頼性が高まります。以下の 2 つの図は、ビデオ フレームの 1 つと、検出器で計算された前景マスクを示しています。

figure; imshow(frame); title('Video Frame');

figure; imshow(foreground); title('Foreground');

手順 2 - 最初のビデオ フレームでの自動車検出

前景のセグメンテーションは完璧ではなく、望ましくないノイズが含まれることが多々あります。この例ではモルフォロジー オープニングを使用してノイズを除去し、検出されたオブジェクト内の隙間を塗りつぶします。

se = strel('square', 3);
filteredForeground = imopen(foreground, se);
figure; imshow(filteredForeground); title('Clean Foreground');

次に、vision.BlobAnalysis オブジェクトを使用して、走行する自動車に対応する各連結要素の境界ボックスを見つけます。このオブジェクトは 150 ピクセル未満のブロブを棄却して、検出された前景をさらにフィルター処理します。

blobAnalysis = vision.BlobAnalysis('BoundingBoxOutputPort', true, ...
    'AreaOutputPort', false, 'CentroidOutputPort', false, ...
    'MinimumBlobArea', 150);
bbox = step(blobAnalysis, filteredForeground);

検出された自動車を強調表示するため、その周りに緑のボックスを描画します。

result = insertShape(frame, 'Rectangle', bbox, 'Color', 'green');

境界ボックスの数は、ビデオ フレーム内で検出された自動車の台数に対応します。処理したビデオ フレームの左上隅に、検出された自動車の数を表示します。

numCars = size(bbox, 1);
result = insertText(result, [10 10], numCars, 'BoxOpacity', 1, ...
    'FontSize', 14);
figure; imshow(result); title('Detected Cars');

手順 3 - 残りのビデオ フレームの処理

最後の手順では残りのビデオ フレームを処理します。

videoPlayer = vision.VideoPlayer('Name', 'Detected Cars');
videoPlayer.Position(3:4) = [650,400];  % window size: [width, height]
se = strel('square', 3); % morphological filter for noise removal

while hasFrame(videoReader)

    frame = readFrame(videoReader); % read the next video frame

    % Detect the foreground in the current video frame
    foreground = step(foregroundDetector, frame);

    % Use morphological opening to remove noise in the foreground
    filteredForeground = imopen(foreground, se);

    % Detect the connected components with the specified minimum area, and
    % compute their bounding boxes
    bbox = step(blobAnalysis, filteredForeground);

    % Draw bounding boxes around the detected cars
    result = insertShape(frame, 'Rectangle', bbox, 'Color', 'green');

    % Display the number of cars found in the video frame
    numCars = size(bbox, 1);
    result = insertText(result, [10 10], numCars, 'BoxOpacity', 1, ...
        'FontSize', 14);

    step(videoPlayer, result);  % display the results
end

出力ビデオでは自動車の周りに境界ボックスが表示されます。また、ビデオの左上隅に自動車の台数も表示されます。