web-dev-qa-db-fra.com

Implémentation de Sift avec OpenCV 2.2

Est-ce que quelqu'un connaît le lien d'exemple d'implémentation de SIFT avec OpenCV 2.2. Cordialement,

32
Shahgee

Voici un exemple minimal:

#include <opencv/cv.h>
#include <opencv/highgui.h>

int main(int argc, const char* argv[])
{
    const cv::Mat input = cv::imread("input.jpg", 0); //Load as grayscale

    cv::SiftFeatureDetector detector;
    std::vector<cv::KeyPoint> keypoints;
    detector.detect(input, keypoints);

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

    return 0;
}

Testé sur OpenCV 2.3

33
Unapiedra

Vous pouvez obtenir le détecteur SIFT et l'extracteur basé sur SIFT de plusieurs manières. Comme d'autres ont déjà suggéré des méthodes plus directes, je proposerai une approche plus "d'ingénierie logicielle" qui peut vous rendre le code plus flexible aux changements (c'est-à-dire plus facile à changer vers d'autres détecteurs et extracteurs).

Premièrement, si vous cherchez à obtenir le détecteur à l'aide de paramètres intégrés, la meilleure façon est d'utiliser les méthodes d'usine d'OpenCV pour le créer. Voici comment:

#include <opencv2/core/core.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/highgui/highgui.hpp>

#include <vector>

using namespace std;
using namespace cv;

int main(int argc, char *argv[])
{        
  Mat image = imread("TestImage.jpg");

  // Create smart pointer for SIFT feature detector.
  Ptr<FeatureDetector> featureDetector = FeatureDetector::create("SIFT");
  vector<KeyPoint> keypoints;

  // Detect the keypoints
  featureDetector->detect(image, keypoints); // NOTE: featureDetector is a pointer hence the '->'.

  //Similarly, we create a smart pointer to the SIFT extractor.
  Ptr<DescriptorExtractor> featureExtractor = DescriptorExtractor::create("SIFT");

  // Compute the 128 dimension SIFT descriptor at each keypoint.
  // Each row in "descriptors" correspond to the SIFT descriptor for each keypoint
  Mat descriptors;
  featureExtractor->compute(image, keypoints, descriptors);

  // If you would like to draw the detected keypoint just to check
  Mat outputImage;
  Scalar keypointColor = Scalar(255, 0, 0);     // Blue keypoints.
  drawKeypoints(image, keypoints, outputImage, keypointColor, DrawMatchesFlags::DEFAULT);

  namedWindow("Output");
  imshow("Output", outputImage);

  char c = ' ';
  while ((c = waitKey(0)) != 'q');  // Keep window there until user presses 'q' to quit.

  return 0;

}

La raison d'utiliser les méthodes d'usine est flexible, car vous pouvez désormais passer à un autre détecteur de points clés ou à un extracteur de fonctionnalités, par ex. SURF simplement en changeant l'argument passé aux méthodes d'usine "create" comme ceci:

Ptr<FeatureDetector> featureDetector = FeatureDetector::create("SURF");
Ptr<DescriptorExtractor> featureExtractor = DescriptorExtractor::create("SURF");

Pour d'autres arguments possibles à passer pour créer d'autres détecteurs ou extracteurs, voir: http://opencv.itseez.com/modules/features2d/doc/common_interfaces_of_feature_detectors.html#featuredetector-create

http://opencv.itseez.com/modules/features2d/doc/common_interfaces_of_descriptor_extractors.html?highlight=descriptorextractor#descriptorextractor-create

Maintenant, en utilisant les méthodes d'usine, vous gagnez la commodité de ne pas avoir à deviner certains paramètres appropriés à passer à chacun des détecteurs ou extracteurs. Cela peut être pratique pour les nouveaux utilisateurs. Cependant, si vous souhaitez créer votre propre détecteur SIFT personnalisé, vous pouvez encapsuler l'objet SiftDetector créé avec des paramètres personnalisés et l'encapsuler dans un pointeur intelligent et vous y référer en utilisant la variable de pointeur intelligent featureDetector comme ci-dessus.

30
lightalchemist

Un exemple simple utilisant le détecteur de fonctionnalités non libres SIFT dans opencv 2.4

#include <opencv2/opencv.hpp>
#include <opencv2/nonfree/nonfree.hpp>
using namespace cv;

int main(int argc, char** argv)
{

    if(argc < 2)
        return -1;

    Mat img = imread(argv[1]);

    SIFT sift;
    vector<KeyPoint> key_points;

    Mat descriptors;
    sift(img, Mat(), key_points, descriptors);

    Mat output_img;
    drawKeypoints(img, key_points, output_img);

    namedWindow("Image");
    imshow("Image", output_img);
    waitKey(0);
    destroyWindow("Image");

    return 0;
}
6
AMCoded

OpenCV fournit TAMISER et SURFER ( ici aussi ) et d'autres descripteurs de fonctionnalités prêts à l'emploi.
Notez que l'algorithme SIFT est breveté, il peut donc être incompatible avec l'utilisation/la licence OpenCV standard.

5
Adi Shavit

Un autre exemple simple utilisant le détecteur de fonctionnalités non libres SIFT dans opencv 2.4 Assurez-vous d'ajouter la dépendance opencv_nonfree240.lib

#include "cv.h"
#include "highgui.h"
#include <opencv2/nonfree/nonfree.hpp>

int main(int argc, char** argv)
{
   cv::Mat img = cv::imread("image.jpg");

   cv::SIFT sift(10);   //number of keypoints

   cv::vector<cv::KeyPoint> key_points;

   cv::Mat descriptors, mascara;
   cv::Mat output_img;

   sift(img,mascara,key_points,descriptors);
   drawKeypoints(img, key_points, output_img);

   cv::namedWindow("Image");
   cv::imshow("Image", output_img);
   cv::waitKey(0);

   return 0;
}
3
Tervenet

au cas où quelqu'un se demanderait comment faire avec 2 images:

import numpy as np
import cv2

print ('Initiate SIFT detector')
sift = cv2.xfeatures2d.SIFT_create()
print ('find the keypoints and descriptors with SIFT')
gcp1, des1 = sift.detectAndCompute(src_img,None)
gcp2, des2 = sift.detectAndCompute(trg_img,None)

# create BFMatcher object
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)


matches = bf.match(des1,des2)
# Sort them in the order of their distance.
matches = sorted(matches, key = lambda x:x.distance)

#print only the first 100 matches
img3 = drawMatches(src_img, gcp1, trg_img, gcp2, matches[:100])
0
Aymen Alsaadi