Main Content

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

交通量のビデオ内の車の検出

この例では、Image Processing Toolbox™ を使用してビデオやイメージ シーケンスの可視化や解析を行う方法を説明します。この例では、交通量のビデオ内で明るい色の車を検出するために、VideoReader (MATLAB®)、implay、および他の Image Processing Toolbox 関数を使用します。関数 VideoReader は、プラットフォーム固有の機能をもっており、プラットフォームによっては提供される Motion JPEG2000 ビデオを読み取れない場合があります。

手順 1: VideoReader を使用したビデオへのアクセス

関数 VideoReader は、マルチメディア ファイルからのビデオ データを読み取れるマルチメディア reader オブジェクトを作成します。ユーザーのプラットフォームでサポートされる形式の情報については、VideoReaderを参照してください。

関数 VideoReader を使用してビデオにアクセスし、基本情報を取得します。

trafficVid = VideoReader('traffic.mj2')
trafficVid = 

  VideoReader with properties:

   General Properties:
            Name: 'traffic.mj2'
            Path: '/mathworks/devel/bat/Bdoc23b/build/matlab/toolbox/images/imdata'
        Duration: 8
     CurrentTime: 0
       NumFrames: 120

   Video Properties:
           Width: 160
          Height: 120
       FrameRate: 15
    BitsPerPixel: 24
     VideoFormat: 'RGB24'

get メソッドは、秒数による長さなど、ビデオに関する情報を提供します。

get(trafficVid)
obj = 

  VideoReader with properties:

   General Properties:
            Name: 'traffic.mj2'
            Path: '/mathworks/devel/bat/Bdoc23b/build/matlab/toolbox/images/imdata'
        Duration: 8
     CurrentTime: 0
       NumFrames: 120

   Video Properties:
           Width: 160
          Height: 120
       FrameRate: 15
    BitsPerPixel: 24
     VideoFormat: 'RGB24'

手順 2: IMPLAY を使用したビデオの探索

implay を使用してビデオを検索します。

implay('traffic.mj2');

手順 3: アルゴリズムの開発

ビデオ データで作業をする際、ビデオからの代表フレームを選択し、そのフレームにアルゴリズムを開発すると便利です。このアルゴリズムは、ビデオのすべてのフレームの処理に適用できます。

この車のタグ付けアプリケーションでは、明るい色と暗い色の車を含むフレームを検査します。交通量ビデオのフレームのようにイメージが多数の構造をもつ場合、対象オブジェクトを検出しようとする前にイメージをできるだけ単純化すると便利です。車のタグ付けアプリケーションの 1 つの方法としては、明るい色の車でないイメージのすべてのオブジェクト (暗い色の車、車線、芝生など) の表示を抑えることです。通常、いろいろな技術を組み合わせて、これらの余分なオブジェクトを削除します。

ビデオ フレームから暗い色の車を削除する 1 つの方法は、関数 imextendedmax を使用することです。この関数は、指定されたしきい値以上の強度値をもつ領域を識別するバイナリ イメージを返します。これは局所的な最大値と呼ばれます。このしきい値以下のピクセル値をもつイメージ内の他のすべてのオブジェクトは、背景になります。暗い色の車を削除するには、イメージ内のこれらのオブジェクトの平均ピクセル値を決定します。(関数 im2gray を使用して、元のビデオを RGB からグレースケールに変換します。)implay のピクセル領域ツールを使用して、ピクセル値を表示できます。関数 imextendedmax を呼び出す際、平均ピクセル値 (またはそれよりわずかに大きい値) をしきい値として指定します。この例では、値を 50 に設定します。

darkCarValue = 50;
darkCar = im2gray(read(trafficVid,71));
noDarkCar = imextendedmax(darkCar, darkCarValue);
imshow(darkCar)
figure, imshow(noDarkCar)

処理されたイメージでは、暗い色の車のオブジェクトのほとんどが削除されたにもかかわらず、車線区分線など他の余分のオブジェクトは残っていることに注意してください。局所的な最大値処理では、ピクセル値はしきい値以上なので、車線区分線は削除されません。これらのオブジェクトを削除するには、モルフォロジー関数 imopen を使用できます。この関数はモルフォロジー処理を使用して、バイナリ イメージから小さなオブジェクトを削除し、大きなオブジェクトを保存します。モルフォロジー処理を使用する際、操作で使用する構造化要素のサイズおよび形状を決定しなければなりません。車線区分線は長くて薄いオブジェクトなので、車線区分線の幅に対応する半径をもつ円板状の構造化要素を使用します。関数 implay のピクセル領域ツールを使用して、これらのオブジェクトの幅を推定します。この例では、値を 2 に設定します。

sedisk = strel('disk',2);
noSmallStructures = imopen(noDarkCar, sedisk);
imshow(noSmallStructures)

アルゴリズムを完了するには、関数 regionprops を使用して、noSmallStructures (明るい色の車のみ) 内でオブジェクトの中央を検出します。この情報を使用して、タグを元のビデオの明るい色の車に合わせます。

手順 4: ビデオへのアルゴリズムの適用

車のタグ付けアプリケーションでは、ループでビデオが一度に 1 フレームずつ処理されます (通常のビデオは多数のフレームを含んでいるため、一度にすべてのフレームを読み取って処理するためには大量のメモリを必要とするからです)。

小さいビデオ (この例でのように) は一度に処理できます。この機能を提供する多数の関数があります。詳細については、イメージ シーケンスの処理を参照してください。

より高速な処理には、処理されるビデオの格納に使用されるメモリを事前配分します。

nframes = trafficVid.NumberOfFrames;
I = read(trafficVid, 1);
taggedCars = zeros([size(I,1) size(I,2) 3 nframes], class(I));

for k = 1 : nframes
    singleFrame = read(trafficVid, k);

    % Convert to grayscale to do morphological processing.
    I = rgb2gray(singleFrame);

    % Remove dark cars.
    noDarkCars = imextendedmax(I, darkCarValue);

    % Remove lane markings and other non-disk shaped structures.
    noSmallStructures = imopen(noDarkCars, sedisk);

    % Remove small structures.
    noSmallStructures = bwareaopen(noSmallStructures, 150);

    % Get the area and centroid of each remaining object in the frame. The
    % object with the largest area is the light-colored car.  Create a copy
    % of the original frame and tag the car by changing the centroid pixel
    % value to red.
    taggedCars(:,:,:,k) = singleFrame;

    stats = regionprops(noSmallStructures, {'Centroid','Area'});
    if ~isempty([stats.Area])
        areaArray = [stats.Area];
        [junk,idx] = max(areaArray);
        c = stats(idx).Centroid;
        c = floor(fliplr(c));
        width = 2;
        row = c(1)-width:c(1)+width;
        col = c(2)-width:c(2)+width;
        taggedCars(row,col,1,k) = 255;
        taggedCars(row,col,2,k) = 0;
        taggedCars(row,col,3,k) = 0;
    end
end

手順 5: 結果の可視化

元のビデオのフレーム レートを取得し、そのフレーム レートを使用して implaytaggedCars を表示します。

frameRate = trafficVid.FrameRate;
implay(taggedCars,frameRate);

参考

| | | | | |

関連するトピック