http://blog.csdn.net/kingeasternsun/article/details/8279114
头文件
在VS2010+OpenCV2.3.1
- #include "StdAfx.h"
- #include "opencv2/core/core.hpp"
- #include "opencv2/calib3d/calib3d.hpp"
- #include "opencv2/features2d/features2d.hpp"
- #include "opencv2/imgproc/imgproc.hpp"
- #include "opencv2/highgui/highgui.hpp"
- //#include <opencv2/legacy/legacy.hpp>
- #include <vector>
- #include <iostream>
- #include <fstream>
- #include <math.h>
- using namespace cv;
- using namespace std;
- void getMatchLR(string imgpath);
- void getMatchDT(string imgpath);
- //void getSURFFeature(string imgpath);
- void getORBFeature(string imgpath);
- void MatchTemplate(string imgname);
- void MatchTemplateORB(string imgname);
- void MatchTemplateSIFT(string imgname);
- void testMatch();
- static string imgdir = "E:\\input_resize\\";
- static string Matchsavedir = "E:\\macth_result\\";
- static string TemplateDir = "E:\\template_resize\\";
- //static string ORBsavedir = "ORB_result\\";
- IplImage mat_src_lpl;
- IplImage OutImage_lpl;
- IplImage TemplateIpl;
- IplImage* dst_left;
- IplImage* dst_right;
- IplImage *src;
- IplImage *TemplateIplPtr;
- Mat mat_src;
- Mat OutImage;
- Mat TemplateMat;
在UBUNTU12.04UTL+opencv2.4.
- #include "opencv2/core/core.hpp"
- #include "opencv2/calib3d/calib3d.hpp"
- #include "opencv2/features2d/features2d.hpp"
- #include "opencv2/imgproc/imgproc.hpp"
- #include "opencv2/highgui/highgui.hpp"
- #include <opencv2/legacy/legacy.hpp>
- #include <vector>
- #include <iostream>
- #include <fstream>
- #include <math.h>
主函数
- int main()
- {
- string imgname = "07_in.jpg";
- //testMatch();
- MatchTemplateSIFT(imgname);
- //getMatchLR(imgname);
- return 0;
- }
SIFT
利用SIFT特征进行模板匹配,template1为一个物体的小图,然后在一张含有多个同样物体的大图上进行匹配。
在大图上滑窗处理,得到每一个滑窗的特征,进行匹配,计算距离均值,作为一个灰度值,最后生成一个大图。
特征子,描述符,匹配方法分别为:
- new SiftFeatureDetector
- new SiftDescriptorExtractor;
- BruteForceMatcher<L2(float)>
详细代码
- void MatchTemplateSIFT(string imgname)
- {
- vector<KeyPoint> LeftKey;
- vector<KeyPoint> RightKey;
- Mat LeftDescriptor;
- Mat RightDescriptor;
- vector<DMatch> Matches;
- //vector<double> meanDisances;
- IplImage* dst;
- ofstream fout("E:\\picin\\rBRIEF_Test\\templateCompareResult.txt");
- int xstep = 2;
- int ystep = 2;
- string TemplateName = "template1.jpg";
- string TemplateImgPath = TemplateDir + TemplateName;
- string imgpath = imgdir + imgname;
- string resultPath = Matchsavedir+imgname;
- TemplateMat = imread(TemplateImgPath,CV_LOAD_IMAGE_GRAYSCALE);
- if(!TemplateMat.data){
- cout<<"no template exist";
- return ;
- }
- int TemplateWidth = TemplateMat.cols;
- int TemplateHeight = TemplateMat.rows;
- std::cout<<"TemplateWidth "<<TemplateWidth<<endl;
- std::cout<<"TemplateHeight "<<TemplateHeight<<endl;
- FeatureDetector *pDetector = new SiftFeatureDetector; pDetector->detect(TemplateMat, LeftKey);
- DescriptorExtractor *pExtractor = new SiftDescriptorExtractor;
- pExtractor->compute(TemplateMat, LeftKey, LeftDescriptor);
- DescriptorMatcher *pMatcher = new BruteForceMatcher<L2<float>>;
- mat_src = imread(imgpath, CV_LOAD_IMAGE_GRAYSCALE );
- if(!mat_src.data) {
- cout<<"no src img";
- return ;
- } mat_src_lpl = IplImage(mat_src);
- src = &mat_src_lpl;
- long ImgWidth = src->width;
- long ImgHeight = src->height;
- std::cout<<"ImgWidth "<<ImgWidth<<endl;
- std::cout<<"ImgHeight "<<ImgHeight<<endl;
- int x;
- int y;
- //Mat R = Mat(ImgHeight - TemplateHeight, ImgWidth - TemplateWidth, CV_8UC1,255);
- //namedWindow("result", CV_WINDOW_NORMAL );
- //imshow("result",mat_src);
- //uchar *p;
- //while(start_x < ImgWidth - TemplateWidth){
- for(long start_y = 0;start_y <ImgHeight - TemplateHeight;start_y = start_y+ystep){
- for(long start_x = 0;start_x < ImgWidth - TemplateWidth;start_x = start_x+xstep){
- x = start_x;
- y = start_y;
- cvSetImageROI(src,cvRect(x,y,TemplateWidth,TemplateHeight));
- dst = cvCreateImage(cvSize(TemplateWidth,TemplateHeight),
- IPL_DEPTH_8U,
- src->nChannels);
- cvCopy(src,dst,0);
- cvResetImageROI(src);
- Mat DstImage = Mat(dst, false); // Do not copy
- pDetector->detect(DstImage, RightKey);
- pExtractor->compute(DstImage, RightKey, RightDescriptor);
- pMatcher->match(LeftDescriptor, RightDescriptor, Matches);
- //double sum = 0;
- double sum = 0;
- //int i = 0;
- for(vector<DMatch>::iterator dite = Matches.begin();dite <Matches.end(); dite++ )
- {
- sum += dite->distance;
- }
- int matchSize = Matches.size()*10;
- if(matchSize>1){
- fout<<exp(-sum/matchSize)<<" ";
- }else{
- fout<<exp(-100.0)<<" ";
- }
- }
- }
- //
- std::cout<<"finish";
- fout.close();
- //destroyWindow("result" );
- //imwrite(resultPath,R);
- delete pDetector;
- delete pExtractor;
- delete pMatcher;
- }
SURF
SURF特征同SIFT特征。
ORB
描述子和描述符,匹配代码如下- ORB orb;
- orb(TemplateMat,Mat(),LeftKey,LeftDescriptor);
- DescriptorMatcher *pMatcher = new BruteForceMatcher<HammingLUT>;
详细代码如下
- void MatchTemplateORB(string imgname)
- {
- vector<KeyPoint> LeftKey;
- vector<KeyPoint> RightKey;
- Mat LeftDescriptor;
- Mat RightDescriptor;
- vector<DMatch> Matches;
- //vector<double> meanDisances;
- IplImage* dst;
- ofstream fout("E:\\picin\\rBRIEF_Test\\templateCompareResult.txt");
- int xstep = 2;
- int ystep = 2;
- string TemplateName = "template2.jpg";
- string TemplateImgPath = TemplateDir + TemplateName;
- string imgpath = imgdir + imgname;
- string resultPath = Matchsavedir+imgname;
- TemplateMat = imread(TemplateImgPath,CV_LOAD_IMAGE_GRAYSCALE);
- if(!TemplateMat.data){
- cout<<"no template exist";
- return ;
- }
- int TemplateWidth = TemplateMat.cols;
- int TemplateHeight = TemplateMat.rows;
- std::cout<<"TemplateWidth "<<TemplateWidth<<endl;
- std::cout<<"TemplateHeight "<<TemplateHeight<<endl;
- ORB orb;
- orb(TemplateMat,Mat(),LeftKey,LeftDescriptor);
- DescriptorMatcher *pMatcher = new BruteForceMatcher<HammingLUT>;
- mat_src = imread(imgpath, CV_LOAD_IMAGE_GRAYSCALE );
- if(!mat_src.data) {
- cout<<"no src img";
- return ;
- }
- mat_src_lpl = IplImage(mat_src);
- src = &mat_src_lpl;
- long ImgWidth = src->width;
- long ImgHeight = src->height;
- std::cout<<"ImgWidth "<<ImgWidth<<endl;
- std::cout<<"ImgHeight "<<ImgHeight<<endl;
- int x;
- int y;
- //Mat R = Mat(ImgHeight - TemplateHeight, ImgWidth - TemplateWidth, CV_8UC1,255);
- //namedWindow("result", CV_WINDOW_NORMAL );
- //imshow("result",mat_src);
- //uchar *p;
- //while(start_x < ImgWidth - TemplateWidth){
- for(long start_y = 0;start_y <ImgHeight - TemplateHeight;start_y = start_y+ystep){
- for(long start_x = 0;start_x < ImgWidth - TemplateWidth;start_x = start_x+xstep){
- x = start_x;
- y = start_y;
- //std::cout<<"<"<<x<<","<<y<<">"<<" ";
- cvSetImageROI(src,cvRect(x,y,TemplateWidth,TemplateHeight));
- dst = cvCreateImage(cvSize(TemplateWidth,TemplateHeight),
- IPL_DEPTH_8U,
- src->nChannels);
- cvCopy(src,dst,0);
- cvResetImageROI(src);
- Mat DstImage = Mat(dst, false); // Do not copy
- orb(DstImage,Mat(),RightKey,RightDescriptor);
- //std::cout<<RightDescriptor.size();
- pMatcher->match(LeftDescriptor, RightDescriptor, Matches);
- //double sum = 0;
- double sum = 0;
- //int i = 0;
- for(vector<DMatch>::iterator dite = Matches.begin();dite <Matches.end(); dite++ )
- {
- sum += dite->distance;
- }
- int matchSize = Matches.size()*10;
- //std::cout<<matchSize<<" ";
- if(matchSize>1){
- //int meanDis = sum/matchSize;
- fout<<exp(-sum/matchSize)<<" ";
- //std::cout<<"meanDis"<<meanDis<<" ";
- //R.at<uchar>(x,y) = meanDis;
- }else{
- fout<<exp(-100.0)<<" ";
- //fout<<255<<" ";
- //std::cout<<"meanDis"<<255<<" ";
- }
- }
- //std::cout<<endl;
- fout<<"\n";
- //start_x += step;
- }
- //
- std::cout<<"finish";
- fout.close();
- //destroyWindow("result" );
- //imwrite(resultPath,R);
- //delete pDetector;
- //delete pExtractor;
- delete pMatcher;
- }
对利用特征点对图片左右部分进行匹配
- void getMatchLR(string imgname)
- {
- string imgpath = imgdir + imgname;
- mat_src = imread(imgpath, CV_LOAD_IMAGE_GRAYSCALE );
- if(!mat_src.data) {
- cout<<"no img";
- return ;
- }
- mat_src_lpl = IplImage(mat_src);
- src = &mat_src_lpl;
- //
- cvSetImageROI(src,cvRect(0,0,0.5*src->width,src->height));
- dst_left = cvCreateImage(cvSize(0.5*src->width,src->height),
- IPL_DEPTH_8U,
- src->nChannels);
- cvCopy(src,dst_left,0);
- cvResetImageROI(src);
- cvSetImageROI(src,cvRect(0.5*src->width,0,0.5*src->width,src->height));
- dst_right = cvCreateImage(cvSize(0.5*src->width,src->height),
- IPL_DEPTH_8U,
- src->nChannels);
- cvCopy(src,dst_right,0);
- cvResetImageROI(src);
- // Convert IplImage to cv::Mat
- Mat matLeftImage = Mat(dst_left, false); // Do not copy
- Mat matRightImage = Mat(dst_right, false);
- // Key point and its descriptor
- vector<KeyPoint> LeftKey;
- vector<KeyPoint> RightKey;
- Mat LeftDescriptor;
- Mat RightDescriptor;
- vector<DMatch> Matches;
- /*
- // Detect key points from image
- FeatureDetector *pDetector = new FastFeatureDetector; //
- pDetector->detect(matLeftImage, LeftKey);
- pDetector->detect(matRightImage, RightKey);
- delete pDetector;
- // Extract descriptors
- DescriptorExtractor *pExtractor = new BriefDescriptorExtractor; //
- pExtractor->compute(matLeftImage, LeftKey, LeftDescriptor);
- pExtractor->compute(matRightImage, RightKey, RightDescriptor);
- delete pExtractor;
- */
- ORB orb;
- orb(matLeftImage,Mat(),LeftKey,LeftDescriptor);
- orb(matRightImage,Mat(),RightKey,RightDescriptor);
- // Matching features
- //DescriptorMatcher *pMatcher = new FlannBasedMatcher; //
- DescriptorMatcher *pMatcher = new BruteForceMatcher<HammingLUT>; //
- pMatcher->match(LeftDescriptor, RightDescriptor, Matches);
- delete pMatcher;
- double max_dist = 0; double min_dist = 200;
- //-- Quick calculation of max and min distances between keypoints
- for( int i = 0; i < LeftDescriptor.rows; i++ )
- { double dist = Matches[i].distance;
- if( dist < min_dist ) min_dist = dist;
- if( dist > max_dist ) max_dist = dist;
- }
- //printf("-- Max dist : %f \n", max_dist );
- //printf("-- Min dist : %f \n", min_dist );
- //-- Draw only "good" matches (i.e. whose distance is less than 2*min_dist )
- //-- PS.- radiusMatch can also be used here.
- std::vector< DMatch > good_matches;
- for( int i = 0; i < LeftDescriptor.rows; i++ )
- { if( Matches[i].distance < 0.5*max_dist )
- { good_matches.push_back( Matches[i]); }
- }
- // Show result
- //drawMatches(matLeftImage, LeftKey, matRightImage, RightKey, Matches, OutImage);
- drawMatches( matLeftImage, LeftKey, matRightImage, RightKey,
- good_matches, OutImage, Scalar::all(-1), Scalar::all(-1),
- vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );
- OutImage_lpl = IplImage(OutImage);
- cvNamedWindow( "Match features", 1);
- cvShowImage("Match features", &(OutImage_lpl));
- cvWaitKey( 0 );
- cvDestroyWindow( "Match features" );
- string savepath = Matchsavedir + imgname;
- //-- Show detected (drawn) keypoints
- imwrite(savepath, OutImage );//
- }
以上代码中被注释的部分
- // Detect key points from image
- FeatureDetector *pDetector = new FastFeatureDetector; //
- pDetector->detect(matLeftImage, LeftKey);
- pDetector->detect(matRightImage, RightKey);
- delete pDetector;
- // Extract descriptors
- DescriptorExtractor *pExtractor = new BriefDescriptorExtractor; //
- pExtractor->compute(matLeftImage, LeftKey, LeftDescriptor);
- pExtractor->compute(matRightImage, RightKey, RightDescriptor);
是利用的BRIEF特征,进行左右匹配