Est-ce que quelqu'un connaît le lien d'exemple d'implémentation de SIFT avec OpenCV 2.2. Cordialement,
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
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
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.
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;
}
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;
}
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])