Обнаружение объектов в загроможденной сцене с использованием соответствия функций точек

Этот пример показов, как обнаружить конкретный объект в загроможденной сцене, учитывая ссылку изображение объекта.

Обзор

Этот пример представляет алгоритм для обнаружения определенного объекта на основе соответствия точек нахождения между ссылкой и целевым изображением. Он может обнаруживать объекты, несмотря на изменение шкалы или вращение в плоскости. Он также является устойчивым к небольшому количеству вращения вне плоскости и окклюзии.

Этот метод обнаружения объектов лучше всего работает для объектов, которые показывают неповторяющиеся шаблоны текстуры, которые вызывают уникальные соответствия функций. Этот метод вряд ли будет хорошо работать для однородно окрашенных объектов или для объектов, содержащих повторяющиеся шаблоны. Обратите внимание, что этот алгоритм предназначен для обнаружения определенного объекта, для примера, слона в ссылку изображении, а не любого слона. Для обнаружения объектов определенной категории, таких как люди или лица, смотрите vision.PeopleDetector и vision.CascadeObjectDetector.

Шаг 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 Feature Points from Box Image');
hold on;
plot(selectStrongest(boxPoints, 100));

Визуализируйте точки сильнейший признака, найденные в целевом изображении.

figure;
imshow(sceneImage);
title('300 Strongest Feature Points 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. Определение местоположения объекта в сцене с помощью предполагаемых соответствий

estimateGeometricTransform2D вычисляет преобразование, связывающее совпадающие точки, с устранением выбросов. Это преобразование позволяет нам локализовать объект в сцене.

[tform, inlierIdx] = ...
    estimateGeometricTransform2D(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');

Шаг 7: Обнаружение другого объекта

Обнаружите второй объект с помощью тех же шагов, что и ранее.

Считайте изображение, содержащее второй интересующий объект.

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 Feature Points 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');