Main Content

교통 상황을 촬영한 비디오에서 차량 검출하기

이 예제에서는 Image Processing Toolbox™를 사용하여 비디오 또는 영상 시퀀스를 시각화하고 분석하는 방법을 보여줍니다. 이 예제에서는 VideoReader(MATLAB®) 함수와 implay 함수, 기타 Image Processing Toolbox 함수를 사용하여, 교통 상황을 촬영한 비디오에서 밝은 색 차량을 검출합니다. 참고로, VideoReader는 특정 플랫폼의 기능이므로 일부 플랫폼에서는 제공된 Motion JPEG2000 비디오를 읽어 들이지 못할 수 있습니다.

1단계: VideoReader를 사용하여 비디오에 액세스하기

VideoReader 함수는 멀티미디어 파일에서 비디오 데이터를 읽어 들일 수 있는 멀티미디어 리더 객체를 생성합니다. 사용 중인 플랫폼에서 지원되는 형식에 대한 자세한 내용은 VideoReader 항목을 참조하십시오.

VideoReader를 사용하여 비디오에 액세스하고 비디오에 대한 기본 정보를 얻습니다.

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

  VideoReader with properties:

   General Properties:
            Name: 'traffic.mj2'
            Path: '/mathworks/devel/bat/filer/batfs1904-0/Bdoc24a.2511836/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/filer/batfs1904-0/Bdoc24a.2511836/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단계: 알고리즘 개발하기

비디오 데이터를 사용하는 경우, 비디오에서 대표적인 프레임을 하나 선택하고 그 프레임에 기초하여 알고리즘을 개발하는 것이 유용할 수 있습니다. 그러면 이 알고리즘을 비디오의 모든 프레임을 처리하는 데 적용할 수 있습니다.

이 차량 태그 지정 애플리케이션에 사용하기 위해, 밝은 색 차량과 어두운 색 차량이 모두 포함된 프레임을 조사합니다. 영상이 교통 상황 비디오 프레임과 같이 여러 구조를 갖는 경우, 관심 객체를 검출하기 전에 영상을 최대한 단순화하는 것이 좋습니다. 차량 태그 지정 애플리케이션에 대해 이 작업을 수행하는 한 가지 방법은 영상에서 밝은 색 차량이 아닌 객체(어두운 색 차량, 차선, 잔디)를 모두 표시하지 않는 것입니다. 대개, 이러한 관련 없는 객체를 제거하기 위해 여러 가지 기법을 조합하여 사용합니다.

비디오 프레임에서 어두운 색 차량을 제거하는 한 가지 방법은 imextendedmax 함수를 사용하는 것입니다. 이 함수는 지정된 임계값(국부 최댓값이라고 함)보다 높은 명암 값을 갖는 영역을 알아볼 수 있는 이진 영상을 반환합니다. 영상에서 이 임계값보다 낮은 픽셀 값을 갖는 다른 모든 객체는 배경이 됩니다. 어두운 색 차량을 제거하기 위해 이러한 영상 객체에 대한 평균 픽셀 값을 구합니다. (참고로, 원래 비디오를 RGB에서 회색조로 변환하려면 im2gray를 사용하십시오.) 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단계: 알고리즘을 비디오에 적용하기

차량 태그 지정 애플리케이션은 루프에서 비디오 프레임을 한 번에 하나씩 처리합니다. 일반적인 비디오에는 상당히 많은 프레임이 포함되어 있기 때문에 모든 프레임을 한 번에 읽고 처리하려면 많은 메모리가 사용됩니다.

이 예제에 사용된 비디오 같이 크기가 작은 비디오는 한 번에 처리할 수 있으며 이 기능을 제공하는 함수도 많이 있습니다. 자세한 내용은 Process Image Sequences 항목을 참조하십시오.

처리 속도를 높이기 위해, 처리할 비디오를 저장하는 데 사용할 메모리를 사전할당합니다.

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단계: 결과 시각화하기

원래 비디오의 프레임 속도를 가져온 후 implay에서 이 프레임 속도를 사용하여 taggedCars를 확인합니다.

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

참고 항목

| | | | | |

관련 항목