OpenCV2.4.4中调用SIFT特征检测器进行图像匹配
2015-01-16 22:51
537 查看
OpenCV中一些相关结构说明:
特征点类:
查看文本打印?
class KeyPoint
{
Point2f pt; //坐标
float size; //<strong>特征</strong>点邻域直径
float angle; //<strong>特征</strong>点的方向,值为[0,360),负值表示不使用
float response; //
int octave; //<strong>特征</strong>点所在的<strong>图像</strong>金字塔的组
int class_id; //用于聚类的id
}
存放匹配结果的结构:
查看文本打印?
struct DMatch
{
//三个构造函数
DMatch(): queryIdx(-1), trainIdx(-1),imgIdx(-1),distance(std::numeric_limits<float>::max()) {}
DMatch(int _queryIdx, int _trainIdx, float _distance ) :
queryIdx( _queryIdx),trainIdx( _trainIdx), imgIdx(-1),distance( _distance) {}
DMatch(int _queryIdx, int _trainIdx, int _imgIdx, float _distance ) :
queryIdx(_queryIdx), trainIdx( _trainIdx), imgIdx( _imgIdx),distance( _distance) {}
intqueryIdx; //此<strong>匹配</strong>对应的查询<strong>图像</strong>的<strong>特征</strong>描述子索引
inttrainIdx; //此<strong>匹配</strong>对应的训练(模板)<strong>图像</strong>的<strong>特征</strong>描述子索引
intimgIdx; //训练<strong>图像</strong>的索引(若有多个)
float distance; //两个<strong>特征</strong>向量之间的欧氏距离,越小表明<strong>匹配</strong>度越高。
booloperator < (const DMatch &m) const;
};
说明:以两个特征点描述子(特征向量)之间的欧氏距离作为特征点匹配的相似度准则,假设特征点对p和q的
特征描述子分别为Desp和Desq,则其欧氏距离定义为:
所以每个匹配分别对应训练图像(train)和查询图像(query)中的一个特征描述子(特征向量)。
查看文本打印?
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/nonfree/nonfree.hpp"
#include "opencv2/nonfree/features2d.hpp"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace cv;
using namespace std;
int main()
{
initModule_nonfree();//初始化模块,使用SIFT或SURF时用到
Ptr<FeatureDetector> detector = FeatureDetector::create( "SIFT" );//创建SIFT<strong>特征</strong><strong>检测器</strong>
Ptr<DescriptorExtractor> descriptor_extractor = DescriptorExtractor::create( "SIFT" );//创建<strong>特征</strong>向量生成器
Ptr<DescriptorMatcher> descriptor_matcher = DescriptorMatcher::create( "BruteForce" );//创建<strong>特征</strong><strong>匹配</strong>器
if( detector.empty() || descriptor_extractor.empty() )
cout<<"fail to create detector!";
//读入<strong>图像</strong>
Mat img1 = imread("desk.jpg");
Mat img2 = imread("desk_glue.jpg");
//<strong>特征</strong>点检测
double t = getTickCount();//当前滴答数
vector<KeyPoint> keypoints1,keypoints2;
detector->detect( img1, keypoints1 );//检测img1中的SIFT<strong>特征</strong>点,存储到keypoints1中
detector->detect( img2, keypoints2 );
cout<<"<strong>图像</strong>1<strong>特征</strong>点个数:"<<keypoints1.size()<<endl;
cout<<"<strong>图像</strong>2<strong>特征</strong>点个数:"<<keypoints2.size()<<endl;
//根据<strong>特征</strong>点计算<strong>特征</strong>描述子矩阵,即<strong>特征</strong>向量矩阵
Mat descriptors1,descriptors2;
descriptor_extractor->compute( img1, keypoints1, descriptors1 );
descriptor_extractor->compute( img2, keypoints2, descriptors2 );
t = ((double)getTickCount() - t)/getTickFrequency();
cout<<"SIFT算法用时:"<<t<<"秒"<<endl;
cout<<"<strong>图像</strong>1<strong>特征</strong>描述矩阵大小:"<<descriptors1.size()
<<",<strong>特征</strong>向量个数:"<<descriptors1.rows<<",维数:"<<descriptors1.cols<<endl;
cout<<"<strong>图像</strong>2<strong>特征</strong>描述矩阵大小:"<<descriptors2.size()
<<",<strong>特征</strong>向量个数:"<<descriptors2.rows<<",维数:"<<descriptors2.cols<<endl;
//画出<strong>特征</strong>点
Mat img_keypoints1,img_keypoints2;
drawKeypoints(img1,keypoints1,img_keypoints1,Scalar::all(-1),0);
drawKeypoints(img2,keypoints2,img_keypoints2,Scalar::all(-1),0);
//imshow("Src1",img_keypoints1);
//imshow("Src2",img_keypoints2);
//<strong>特征</strong><strong>匹配</strong>
vector<DMatch> matches;//<strong>匹配</strong>结果
descriptor_matcher->match( descriptors1, descriptors2, matches );//<strong>匹配</strong>两个<strong>图像</strong>的<strong>特征</strong>矩阵
cout<<"Match个数:"<<matches.size()<<endl;
//计算<strong>匹配</strong>结果中距离的最大和最小值
//距离是指两个<strong>特征</strong>向量间的欧式距离,表明两个<strong>特征</strong>的差异,值越小表明两个<strong>特征</strong>点越接近
double max_dist = 0;
double min_dist = 100;
for(int i=0; i<matches.size(); i++)
{
double dist = matches[i].distance;
if(dist < min_dist) min_dist = dist;
if(dist > max_dist) max_dist = dist;
}
cout<<"最大距离:"<<max_dist<<endl;
cout<<"最小距离:"<<min_dist<<endl;
//筛选出较好的<strong>匹配</strong>点
vector<DMatch> goodMatches;
for(int i=0; i<matches.size(); i++)
{
if(matches[i].distance < 0.31 * max_dist)
{
goodMatches.push_back(matches[i]);
}
}
cout<<"goodMatch个数:"<<goodMatches.size()<<endl;
//画出<strong>匹配</strong>结果
Mat img_matches;
//红色连接的是<strong>匹配</strong>的<strong>特征</strong>点对,绿色是未<strong>匹配</strong>的<strong>特征</strong>点
drawMatches(img1,keypoints1,img2,keypoints2,goodMatches,img_matches,
Scalar::all(-1)/*CV_RGB(255,0,0)*/,CV_RGB(0,255,0),Mat(),2);
imshow("MatchSIFT",img_matches);
waitKey(0);
return 0;
}
特征点类:
查看文本打印?
class KeyPoint
{
Point2f pt; //坐标
float size; //<strong>特征</strong>点邻域直径
float angle; //<strong>特征</strong>点的方向,值为[0,360),负值表示不使用
float response; //
int octave; //<strong>特征</strong>点所在的<strong>图像</strong>金字塔的组
int class_id; //用于聚类的id
}
存放匹配结果的结构:
查看文本打印?
struct DMatch
{
//三个构造函数
DMatch(): queryIdx(-1), trainIdx(-1),imgIdx(-1),distance(std::numeric_limits<float>::max()) {}
DMatch(int _queryIdx, int _trainIdx, float _distance ) :
queryIdx( _queryIdx),trainIdx( _trainIdx), imgIdx(-1),distance( _distance) {}
DMatch(int _queryIdx, int _trainIdx, int _imgIdx, float _distance ) :
queryIdx(_queryIdx), trainIdx( _trainIdx), imgIdx( _imgIdx),distance( _distance) {}
intqueryIdx; //此<strong>匹配</strong>对应的查询<strong>图像</strong>的<strong>特征</strong>描述子索引
inttrainIdx; //此<strong>匹配</strong>对应的训练(模板)<strong>图像</strong>的<strong>特征</strong>描述子索引
intimgIdx; //训练<strong>图像</strong>的索引(若有多个)
float distance; //两个<strong>特征</strong>向量之间的欧氏距离,越小表明<strong>匹配</strong>度越高。
booloperator < (const DMatch &m) const;
};
说明:以两个特征点描述子(特征向量)之间的欧氏距离作为特征点匹配的相似度准则,假设特征点对p和q的
特征描述子分别为Desp和Desq,则其欧氏距离定义为:
所以每个匹配分别对应训练图像(train)和查询图像(query)中的一个特征描述子(特征向量)。
查看文本打印?
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/nonfree/nonfree.hpp"
#include "opencv2/nonfree/features2d.hpp"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace cv;
using namespace std;
int main()
{
initModule_nonfree();//初始化模块,使用SIFT或SURF时用到
Ptr<FeatureDetector> detector = FeatureDetector::create( "SIFT" );//创建SIFT<strong>特征</strong><strong>检测器</strong>
Ptr<DescriptorExtractor> descriptor_extractor = DescriptorExtractor::create( "SIFT" );//创建<strong>特征</strong>向量生成器
Ptr<DescriptorMatcher> descriptor_matcher = DescriptorMatcher::create( "BruteForce" );//创建<strong>特征</strong><strong>匹配</strong>器
if( detector.empty() || descriptor_extractor.empty() )
cout<<"fail to create detector!";
//读入<strong>图像</strong>
Mat img1 = imread("desk.jpg");
Mat img2 = imread("desk_glue.jpg");
//<strong>特征</strong>点检测
double t = getTickCount();//当前滴答数
vector<KeyPoint> keypoints1,keypoints2;
detector->detect( img1, keypoints1 );//检测img1中的SIFT<strong>特征</strong>点,存储到keypoints1中
detector->detect( img2, keypoints2 );
cout<<"<strong>图像</strong>1<strong>特征</strong>点个数:"<<keypoints1.size()<<endl;
cout<<"<strong>图像</strong>2<strong>特征</strong>点个数:"<<keypoints2.size()<<endl;
//根据<strong>特征</strong>点计算<strong>特征</strong>描述子矩阵,即<strong>特征</strong>向量矩阵
Mat descriptors1,descriptors2;
descriptor_extractor->compute( img1, keypoints1, descriptors1 );
descriptor_extractor->compute( img2, keypoints2, descriptors2 );
t = ((double)getTickCount() - t)/getTickFrequency();
cout<<"SIFT算法用时:"<<t<<"秒"<<endl;
cout<<"<strong>图像</strong>1<strong>特征</strong>描述矩阵大小:"<<descriptors1.size()
<<",<strong>特征</strong>向量个数:"<<descriptors1.rows<<",维数:"<<descriptors1.cols<<endl;
cout<<"<strong>图像</strong>2<strong>特征</strong>描述矩阵大小:"<<descriptors2.size()
<<",<strong>特征</strong>向量个数:"<<descriptors2.rows<<",维数:"<<descriptors2.cols<<endl;
//画出<strong>特征</strong>点
Mat img_keypoints1,img_keypoints2;
drawKeypoints(img1,keypoints1,img_keypoints1,Scalar::all(-1),0);
drawKeypoints(img2,keypoints2,img_keypoints2,Scalar::all(-1),0);
//imshow("Src1",img_keypoints1);
//imshow("Src2",img_keypoints2);
//<strong>特征</strong><strong>匹配</strong>
vector<DMatch> matches;//<strong>匹配</strong>结果
descriptor_matcher->match( descriptors1, descriptors2, matches );//<strong>匹配</strong>两个<strong>图像</strong>的<strong>特征</strong>矩阵
cout<<"Match个数:"<<matches.size()<<endl;
//计算<strong>匹配</strong>结果中距离的最大和最小值
//距离是指两个<strong>特征</strong>向量间的欧式距离,表明两个<strong>特征</strong>的差异,值越小表明两个<strong>特征</strong>点越接近
double max_dist = 0;
double min_dist = 100;
for(int i=0; i<matches.size(); i++)
{
double dist = matches[i].distance;
if(dist < min_dist) min_dist = dist;
if(dist > max_dist) max_dist = dist;
}
cout<<"最大距离:"<<max_dist<<endl;
cout<<"最小距离:"<<min_dist<<endl;
//筛选出较好的<strong>匹配</strong>点
vector<DMatch> goodMatches;
for(int i=0; i<matches.size(); i++)
{
if(matches[i].distance < 0.31 * max_dist)
{
goodMatches.push_back(matches[i]);
}
}
cout<<"goodMatch个数:"<<goodMatches.size()<<endl;
//画出<strong>匹配</strong>结果
Mat img_matches;
//红色连接的是<strong>匹配</strong>的<strong>特征</strong>点对,绿色是未<strong>匹配</strong>的<strong>特征</strong>点
drawMatches(img1,keypoints1,img2,keypoints2,goodMatches,img_matches,
Scalar::all(-1)/*CV_RGB(255,0,0)*/,CV_RGB(0,255,0),Mat(),2);
imshow("MatchSIFT",img_matches);
waitKey(0);
return 0;
}
相关文章推荐
- OpenCV2.4.4中调用SIFT特征检测器进行图像匹配
- OpenCV2.4.4中调用SIFT特征检测器进行图像匹配
- OpenCV2.4.4中调用SIFT特征检测器进行图像匹配
- OpenCV2.4.4中调用SIFT特征检测器进行图像匹配
- OpenCV2.4.4中调用SIFT特征检测器进行图像匹配
- OpenCV2.4.4中调用SIFT特征检测器进行图像匹配
- 【OpenCV】SIFT特征检测器进行图像匹配
- Opencv实现图像无缝拼接,Sift查找特征点,Flann进行匹配
- 在android 上,使用Opencv3.0实现图像无缝拼接,Fast查找特征点,BruteForce进行匹配
- Symbian c++调用opencv库进行图像处理
- Feature Matching by using opencv(Python)-使用opencv进行图像特征匹配
- 利用OpenCV进行图像匹配
- Opencv实现图像无缝拼接,Sift查找特征点,Flann进行匹配
- 调用opencv中BP神经网络来对图像进行分类
- 使用Opencv进行图像特征点检查与匹配
- opencv输出文字 opencv简单的图像模板匹配代码
- opencv对图像像素进行操作
- opencv下调用K均值函数cvKMeans2聚类图像例程
- 利用特征点(Brief,ORB,SIFT)进行图像匹配,模板匹配
- OpenCV学习笔记2:使用opencv进行图像比较