주요 콘텐츠

이 번역 페이지는 최신 내용을 담고 있지 않습니다. 최신 내용을 영문으로 보려면 여기를 클릭하십시오.

영상 특징점을 사용하여 복잡한 장면에서 객체 찾기

이 예제에서는 객체의 참조 영상이 주어졌을 때 복잡한 장면에서 특정 객체를 검출하는 방법을 보여줍니다.

개요

이 예제에서는 참조 영상과 대상 영상 간의 대응점을 찾아 특정 객체를 검출하는 알고리즘을 보여줍니다. 이 알고리즘은 스케일 변화나 평면 내 회전에도 불구하고 객체를 검출할 수 있습니다. 또한, 소량의 평면 외 회전과 가림 현상에 대해서도 견고합니다.

이 객체 검출 방법은 반복되지 않는 텍스처 패턴을 가진 객체에 가장 효과적이며, 이를 통해 고유한 특징 매칭이 가능합니다. 이 기법은 균일한 색을 가진 객체나 반복되는 패턴이 있는 객체에는 효과적이지 않을 수 있습니다. 이 알고리즘은 모든 코끼리를 검출하는 것이 아니라 특정 객체, 예를 들어 참조 영상에 있는 코끼리를 검출하도록 설계되었습니다.

1단계: 영상 읽어 들이기

관심 객체가 포함된 참조 영상을 읽어 들입니다.

boxImage = imread('stapleRemover.jpg');
figure;
imshow(boxImage);
title('Image of a Box');

복잡한 장면이 포함된 대상 영상을 읽어 들입니다.

sceneImage = imread('clutteredDesk.jpg');
figure;
imshow(sceneImage);
title('Image of a Cluttered Scene');

2단계: 특징점 검출

두 영상 모두에서 특징점을 검출합니다.

boxPoints = detectSURFFeatures(boxImage);
scenePoints = detectSURFFeatures(sceneImage);

참조 영상에서 발견된 가장 강한 특징점을 시각화합니다.

figure;
imshow(boxImage);
title('100 Strongest Point Features from Box Image');
hold on;
plot(selectStrongest(boxPoints, 100));

대상 영상에서 발견된 가장 강한 특징점을 시각화합니다.

figure;
imshow(sceneImage);
title('300 Strongest Point Features from Scene Image');
hold on;
plot(selectStrongest(scenePoints, 300));

3단계: 특징 설명자 추출

두 영상의 관심점에서 특징 설명자를 추출합니다.

[boxFeatures, boxPoints] = extractFeatures(boxImage, boxPoints);
[sceneFeatures, scenePoints] = extractFeatures(sceneImage, scenePoints);

4단계: 매칭되는 추정점 찾기

설명자를 사용하여 특징을 매칭시킵니다.

boxPairs = matchFeatures(boxFeatures, sceneFeatures);

매칭되는 추정 특징을 표시합니다.

matchedBoxPoints = boxPoints(boxPairs(:, 1), :);
matchedScenePoints = scenePoints(boxPairs(:, 2), :);
figure;
showMatchedFeatures(boxImage, sceneImage, matchedBoxPoints, ...
    matchedScenePoints, 'montage');
title('Putatively Matched Points (Including Outliers)');

5단계: 매칭되는 추정점을 사용하여 장면에서 객체 찾기

estgeotform2d는 매칭되는 점 간의 변환을 계산하며, 동시에 이상값을 제거합니다. 이러한 변환을 통해 장면에서 객체를 찾아낼 수 있습니다.

[tform, inlierIdx] = estgeotform2d(matchedBoxPoints, matchedScenePoints, 'affine');
inlierBoxPoints   = matchedBoxPoints(inlierIdx, :);
inlierScenePoints = matchedScenePoints(inlierIdx, :);

이상값이 제거된 매칭 점 쌍을 표시합니다.

figure;
showMatchedFeatures(boxImage, sceneImage, inlierBoxPoints, ...
    inlierScenePoints, 'montage');
title('Matched Points (Inliers Only)');

참조 영상의 경계 다각형을 가져옵니다.

boxPolygon = [1, 1;...                           % top-left
        size(boxImage, 2), 1;...                 % top-right
        size(boxImage, 2), size(boxImage, 1);... % bottom-right
        1, size(boxImage, 1);...                 % bottom-left
        1, 1];                   % top-left again to close the polygon

다각형을 대상 영상의 좌표계로 변환합니다. 변환된 다각형은 장면에서 객체의 위치를 나타냅니다.

newBoxPolygon = transformPointsForward(tform, boxPolygon);

검출된 객체를 표시합니다.

figure;
imshow(sceneImage);
hold on;
line(newBoxPolygon(:, 1), newBoxPolygon(:, 2), Color='y');
title('Detected Box');

6단계: 다른 객체 검출

앞에서와 같은 단계를 사용하여 두 번째 객체를 검출합니다.

두 번째 관심 객체가 포함된 영상을 읽어 들입니다.

elephantImage = imread('elephant.jpg');
figure;
imshow(elephantImage);
title('Image of an Elephant');

특징점을 검출하고 시각화합니다.

elephantPoints = detectSURFFeatures(elephantImage);
figure;
imshow(elephantImage);
hold on;
plot(selectStrongest(elephantPoints, 100));
title('100 Strongest Point Features from Elephant Image');

특징 설명자를 추출합니다.

[elephantFeatures, elephantPoints] = extractFeatures(elephantImage, elephantPoints);

특징을 매칭합니다.

elephantPairs = matchFeatures(elephantFeatures, sceneFeatures, MaxRatio=0.9);

매칭되는 추정 특징을 표시합니다.

matchedElephantPoints = elephantPoints(elephantPairs(:, 1), :);
matchedScenePoints = scenePoints(elephantPairs(:, 2), :);
figure;
showMatchedFeatures(elephantImage, sceneImage, matchedElephantPoints, ...
    matchedScenePoints, 'montage');
title('Putatively Matched Points (Including Outliers)');

기하 변환을 추정하고 이상값을 제거합니다.

[tform, inlierElephantPoints, inlierScenePoints] = ...
    estimateGeometricTransform(matchedElephantPoints, matchedScenePoints, 'affine');
figure;
showMatchedFeatures(elephantImage, sceneImage, inlierElephantPoints, ...
    inlierScenePoints, 'montage');
title('Matched Points (Inliers Only)');

두 객체를 모두 표시합니다.

elephantPolygon = [1, 1;...                                 % top-left
        size(elephantImage, 2), 1;...                       % top-right
        size(elephantImage, 2), size(elephantImage, 1);...  % bottom-right
        1, size(elephantImage, 1);...                       % bottom-left
        1,1];                         % top-left again to close the polygon

newElephantPolygon = transformPointsForward(tform, elephantPolygon);

figure;
imshow(sceneImage);
hold on;
line(newBoxPolygon(:, 1), newBoxPolygon(:, 2), Color='y');
line(newElephantPolygon(:, 1), newElephantPolygon(:, 2), Color='g');
title('Detected Elephant and Box');