简易三维重建(二) SIFT提取特征向量
一,SIFT 函数接口
OpenCV中的SIFT函数主要有两个接口。
构造函数:
- SIFT::SIFT(int nfeatures=0, int nOctaveLayers=3, double contrastThreshold=0.04, double edgeThreshold=
- 10, double sigma=1.6)
nOctaveLayers:金字塔中每组的层数(算法中会自己计算这个值,后面会介绍)。
contrastThreshold:过滤掉较差的特征点的对阈值。contrastThreshold越大,返回的特征点越少。
edgeThreshold:过滤掉边缘效应的阈值。edgeThreshold越大,特征点越多(被多滤掉的越少)。
sigma:金字塔第0层图像高斯滤波系数,也就是σ。
重载操作符:
- void SIFT::operator()(InputArray img, InputArray mask, vector<KeyPoint>& keypoints, OutputArray
- descriptors, bool useProvidedKeypoints=false)
img:8bit灰度图像
mask:图像检测区域(可选)
keypoints:特征向量矩阵
descipotors:特征点描述的输出向量(如果不需要输出,需要传cv::noArray())。
useProvidedKeypoints:是否进行特征点检测。ture,则检测特征点;false,只计算图像特征描述。
注:老版opencv可以直接用SIFT构造函数,新版用creat方法。
用SIFT进行特征点提取和匹配
参考:
#include"stdafx.h"
#include <iostream>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/core/core.hpp"
#include "highgui.h"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/xfeatures2d/nonfree.hpp"
#include <opencv2/opencv.hpp> //头文件
#include <opencv2/xfeatures2d.hpp>
#include <opencv2/opencv.hpp> //头文件
#include <opencv2/xfeatures2d.hpp>
using namespace cv; //包含cv命名空间
using namespace std;
int main() {
//
// 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..
Mat img_1 = imread("1.jpg");
Mat img_2 = imread("2.jpg");
/*测试是否能读取图片*/
/*imshow("1", img_1);
imshow("2", img_2);
waitKey(0);*/
//f2d->detectAndCompute(image, noArray(), key_points, descriptor);
//-- 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);
//绘制匹配出的关键点
Mat img_matches;
drawMatches(img_1, keypoints_1, img_2, keypoints_2, matches, img_matches);
namedWindow("【match图】", 0);
imshow("【match图】", img_matches);
//等待任意按键按下
waitKey(0);
}
#include <iostream>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/core/core.hpp"
#include "highgui.h"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/xfeatures2d/nonfree.hpp"
#include <opencv2/opencv.hpp> //头文件
#include <opencv2/xfeatures2d.hpp>
#include <opencv2/opencv.hpp> //头文件
#include <opencv2/xfeatures2d.hpp>
using namespace cv; //包含cv命名空间
using namespace std;
int main() {
//
// 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..
Mat img_1 = imread("1.jpg");
Mat img_2 = imread("2.jpg");
/*测试是否能读取图片*/
/*imshow("1", img_1);
imshow("2", img_2);
waitKey(0);*/
//f2d->detectAndCompute(image, noArray(), key_points, descriptor);
//-- 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);
//绘制匹配出的关键点
Mat img_matches;
drawMatches(img_1, keypoints_1, img_2, keypoints_2, matches, img_matches);
namedWindow("【match图】", 0);
imshow("【match图】", img_matches);
//等待任意按键按下
waitKey(0);
}
报错:OpenCV Error: Assertion failed (_queryDescriptors.type() == trainDescType) in cv::BFMatcher::knnMatchImpl, file C:\build\master_winpack-build-win64-vc14\opencv\modules\features2d\src\matchers.cpp, line 744
解决:检测后发现是图片路径有问题,修改后正确运行如下。