Как использовать SIFT в OpenCV 3.0 с С++?

У меня есть OpenCV 3.0, и я скомпилировал и установил его с модулем opencv_contrib, так что это не проблема. К сожалению, примеры из предыдущих версий не работают с текущей, поэтому, хотя этот вопрос имеет уже задано более одного раза Я хотел бы более актуальный пример, с которым я действительно могу работать. Даже официальные примеры не работают в этой версии (обнаружение функций работает, но не другие примеры функций), и они все равно используют SURF.

Итак, как мне использовать OpenCV SIFT на C++? Я хочу захватить ключевые точки на двух изображениях и сопоставить их, подобно в этом примере, но даже просто получить баллы и дескрипторы будет достаточно. Помощь!


person leinaD_natipaC    schedule 17.12.2014    source источник


Ответы (2)


  1. получить репозиторий opencv_contrib
  2. не торопитесь с файлом readme, добавьте его в настройки main opencv cmake
  3. перезапустите cmake/make/install в основном репозитории opencv

тогда:

   #include "opencv2/xfeatures2d.hpp"

  // 
  // now, you can no more create an instance on the 'stack', like in the tutorial
  // (yea, noticed for a fix/pr).
  // you will have to use cv::Ptr all the way down:
  //
  cv::Ptr<Feature2D> f2d = xfeatures2d::SIFT::create();
  //cv::Ptr<Feature2D> f2d = xfeatures2d::SURF::create();
  //cv::Ptr<Feature2D> f2d = ORB::create();
  // you get the picture, i hope..

  //-- Step 1: Detect the keypoints:
  std::vector<KeyPoint> keypoints_1, keypoints_2;    
  f2d->detect( img_1, keypoints_1 );
  f2d->detect( img_2, keypoints_2 );

  //-- Step 2: Calculate descriptors (feature vectors)    
  Mat descriptors_1, descriptors_2;    
  f2d->compute( img_1, keypoints_1, descriptors_1 );
  f2d->compute( img_2, keypoints_2, descriptors_2 );

  //-- Step 3: Matching descriptor vectors using BFMatcher :
  BFMatcher matcher;
  std::vector< DMatch > matches;
  matcher.match( descriptors_1, descriptors_2, matches );

также не забудьте связать opencv_xfeatures2d!

person berak    schedule 17.12.2014
comment
В документации обнаружение и вычисление отображаются только как функции Python. Документация неполная? Где лучше документирован класс SIFT? И SIFT::operator() непригоден для использования, или я просто делаю что-то ужасно неправильно? Редактировать: функция create(...) нигде не просматривается в онлайн-документации... Думаю, я либо ищу не в том месте, либо мне просто придется обойтись без докс. - person leinaD_natipaC; 17.12.2014
comment
operator() все еще существует, но использование его из указателя сделало бы его чем-то вроде f2d-›operator(...). тогда лучше использовать: f2d->detectAndCompute(...). (и да, документы нуждаются в срочном порядке...) - person berak; 17.12.2014
comment
Редакция помогает. После небольшого исследования я хотел бы добавить, что вы также можете использовать detectAndCompute(img, mask, keypoints, descriptors) и что вы можете использовать noArray(), если вам не нужна маска. - person leinaD_natipaC; 18.12.2014
comment
Также для дальнейшего использования вы можете использовать drawMatches( ), чтобы увидеть совпадения. - person leinaD_natipaC; 18.12.2014
comment
@berak Как связать opencv_xfeature2d? - person Yirga; 21.03.2017

Есть полезные ответы, но я добавлю свою версию (для OpenCV 3.X) на тот случай, если приведенные выше неясны (проверено и опробовано):

  1. Клонировать opencv из https://github.com/opencv/opencv в домашний каталог
  2. Клонировать opencv_contrib из https://github.com/opencv/opencv_contrib в домашний каталог
  3. Внутри opencv создайте папку с именем build
  4. Используйте эту команду CMake для активации несвободных модулей: cmake -DOPENCV_EXTRA_MODULES_PATH=/home/YOURUSERNAME/opencv_contrib/modules -DOPENCV_ENABLE_NONFREE:BOOL=ON .. (Обратите внимание, что мы показали, где находятся модули contrib, а также активировали несвободные модули)
  5. Сделайте make и make install потом

Вышеуказанные шаги должны работать для OpenCV 3.X.

После этого вы можете запустить приведенный ниже код, используя g++ с соответствующими флагами:

g++ -std=c++11 main.cpp `pkg-config --libs --cflags opencv` -lutil -lboost_iostreams -lboost_system -lboost_filesystem -lopencv_xfeatures2d -o surftestexecutable

Важно не забыть связать библиотеку xfeatures2D с -lopencv_xfeatures2d, как показано в команде. И файл main.cpp:

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "opencv2/xfeatures2d.hpp"
#include "opencv2/xfeatures2d/nonfree.hpp"

using namespace cv;
using namespace std;

int main(int argc, const char* argv[])
{

    const cv::Mat input = cv::imread("surf_test_input_image.png", 0); //Load as grayscale

    Ptr< cv::xfeatures2d::SURF> surf =  xfeatures2d::SURF::create();
    std::vector<cv::KeyPoint> keypoints;
    surf->detect(input, keypoints);

    // Add results to image and save.
    cv::Mat output;
    cv::drawKeypoints(input, keypoints, output);
    cv::imwrite("surf_result.jpg", output);


    return 0;
}

Это должно создать и сохранить изображение с ключевыми точками серфинга.

person Okan Barut    schedule 23.12.2019