Main Content

KLT 알고리즘을 사용한 얼굴 검출 및 추적

이 예제에서는 특징점을 사용하여 얼굴을 자동으로 검출하고 추적하는 방법을 보여줍니다. 이 예제의 방식은 사람이 머리를 기울이거나 카메라를 향해 오거나 멀어지는 경우에도 얼굴을 계속 추적합니다.

소개

객체 검출과 추적은 행동 인식, 자동차 안전, 감시 등을 비롯하여 많은 컴퓨터 비전 응용 분야에서 중요한 작업입니다. 이 예제에서는 추적 문제를 3개의 부분으로 나누어 간단한 얼굴 추적 시스템을 개발합니다.

  1. 얼굴 검출

  2. 추적할 얼굴 특징 식별

  3. 얼굴 추적

얼굴 검출하기

먼저 얼굴을 검출해야 합니다. vision.CascadeObjectDetector 객체를 사용하여 비디오 프레임에서 얼굴의 위치를 검출합니다. 캐스케이드 객체 검출기는 Viola-Jones 검출 알고리즘과 훈련된 분류 모델을 사용하여 검출합니다. 기본적으로 이 검출기는 얼굴을 검출하도록 구성되었지만 다른 유형의 객체를 검출하는 데 사용할 수도 있습니다.

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

% Read a video frame and run the face detector.
videoReader = VideoReader("tilted_face.avi");
videoFrame      = readFrame(videoReader);
bbox            = step(faceDetector, videoFrame);

% Draw the returned bounding box around the detected face.
videoFrame = insertShape(videoFrame, "rectangle", bbox);
figure; imshow(videoFrame); title("Detected face");

Figure contains an axes object. The axes object with title Detected face contains an object of type image.

% Convert the first box into a list of 4 points
% This is needed to be able to visualize the rotation of the object.
bboxPoints = bbox2points(bbox(1, :));

이 예제에서는 시간 경과에 따라 얼굴을 추적하기 위해 KLT(Kanade-Lucas-Tomasi) 알고리즘을 사용합니다. 캐스케이드 객체 검출기는 모든 프레임에서 사용할 수 있지만 많은 계산량을 필요로 합니다. 피사체가 머리를 돌리거나 기울이면 얼굴을 검출하지 못할 수도 있습니다. 이러한 한계는 검출에 사용되는 훈련된 분류 모델의 유형으로 인한 것입니다. 이 예제에서는 얼굴을 한 번만 검출하며, 그런 다음 KLT 알고리즘이 비디오 프레임 전체에서 얼굴을 추적합니다.

추적할 얼굴 특징 식별하기

KLT 알고리즘은 비디오 프레임 전체에서 특징점 세트를 추적합니다. 이 예제에서는 얼굴을 검출한 후 다음 단계에서 안정적으로 추적할 수 있는 특징점을 식별합니다. 이 예제에서는 Shi와 Tomasi가 제안한 "추적하기 좋은 특징"(good features to track) 표준을 사용합니다.

얼굴 영역에서 특징점을 검출합니다.

points = detectMinEigenFeatures(im2gray(videoFrame), "ROI", bbox);

% Display the detected points.
figure, imshow(videoFrame), hold on, title("Detected features");
plot(points);

Figure contains an axes object. The axes object with title Detected features contains 2 objects of type image, line. One or more of the lines displays its values using only markers

추적기를 초기화하여 점 추적하기

특징점이 식별되면 이제 vision.PointTracker System object를 사용하여 이를 추적할 수 있습니다. 점 추적기는 이전 프레임의 각 점에 대해 현재 프레임에서 대응점을 찾으려고 시도합니다. 그런 다음 estimateGeometricTransform2D 함수를 사용하여 이전 점과 새 점 간의 평행 이동, 회전, 스케일을 추정합니다. 이 변환은 얼굴을 둘러싸는 경계 상자에 적용됩니다.

점 추적기를 만들고 양방향 오차 제약 조건을 활성화하여 잡음이 있고 지저분할 때 더욱 견고해 지도록 합니다.

pointTracker = vision.PointTracker("MaxBidirectionalError", 2);

% Initialize the tracker with the initial point locations and the initial
% video frame.
points = points.Location;
initialize(pointTracker, points, videoFrame);

비디오 플레이어를 초기화하여 결과 표시하기

비디오 프레임을 표시하기 위한 video player 객체를 만듭니다.

videoPlayer  = vision.VideoPlayer("Position",...
    [100 100 [size(videoFrame, 2), size(videoFrame, 1)]+30]);

얼굴 추적하기

프레임 간에 점을 추적하고 estimateGeometricTransform2D 함수를 사용하여 얼굴의 움직임을 추정합니다.

이전 프레임의 점과 현재 프레임의 점 사이의 기하 변환을 계산하는 데 사용할 점의 복사본을 만듭니다.

oldPoints = points;

while hasFrame(videoReader)
    % get the next frame
    videoFrame = readFrame(videoReader);

    % Track the points. Note that some points may be lost.
    [points, isFound] = step(pointTracker, videoFrame);
    visiblePoints = points(isFound, :);
    oldInliers = oldPoints(isFound, :);
    
    if size(visiblePoints, 1) >= 2 % need at least 2 points
        
        % Estimate the geometric transformation between the old points
        % and the new points and eliminate outliers
        [xform, inlierIdx] = estimateGeometricTransform2D(...
            oldInliers, visiblePoints, "similarity", "MaxDistance", 4);
        oldInliers    = oldInliers(inlierIdx, :);
        visiblePoints = visiblePoints(inlierIdx, :);
        
        % Apply the transformation to the bounding box points
        bboxPoints = transformPointsForward(xform, bboxPoints);
                
        % Insert a bounding box around the object being tracked
        bboxPolygon = reshape(bboxPoints', 1, []);
        videoFrame = insertShape(videoFrame, "polygon", bboxPolygon, ...
            "LineWidth", 2);
                
        % Display tracked points
        videoFrame = insertMarker(videoFrame, visiblePoints, "+", ...
            "MarkerColor", "white");       
        
        % Reset the points
        oldPoints = visiblePoints;
        setPoints(pointTracker, oldPoints);        
    end
    
    % Display the annotated video frame using the video player object
    step(videoPlayer, videoFrame);
end

% Clean up
release(videoPlayer);

Figure Video Player contains an axes object and other objects of type uiflowcontainer, uimenu, uitoolbar. The axes object contains an object of type image.

release(pointTracker);

요약

이 예제에서는 하나의 얼굴을 자동으로 검출하고 추적하는 간단한 얼굴 추적 시스템을 만들었습니다. 입력 비디오를 변경해 본 후 여전히 얼굴을 검출하고 추적할 수 있는지 확인하십시오. 검출 단계의 초기 프레임에서 사람이 카메라를 향해 있는지 확인하십시오.

참고 문헌

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