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

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

Обзор

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

Этот метод обнаружения объектов работает лучше всего на объекты, которые показывают неповторяющиеся шаблоны структуры, которые дают начало соответствиям уникальной функции. Этот метод вряд ли будет работать хорошо на однородно-цветные-объекты, или на объекты, содержащие повторяющиеся шаблоны. Обратите внимание на то, что этот алгоритм спроектирован для обнаружения конкретного объекта, например, слона в ссылочном изображении, а не любого слона. Для обнаружения объектов конкретной категории, таких как люди или поверхности, смотрите 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');