1. 程式人生 > >利用特徵點(Brief,ORB,SIFT)進行影象匹配,模板匹配

利用特徵點(Brief,ORB,SIFT)進行影象匹配,模板匹配

http://blog.csdn.net/kingeasternsun/article/details/8279114

標頭檔案

在VS2010+OpenCV2.3.1 
  1. #include "StdAfx.h"
  2. #include "opencv2/core/core.hpp"
  3. #include "opencv2/calib3d/calib3d.hpp"
  4. #include "opencv2/features2d/features2d.hpp"
  5. #include "opencv2/imgproc/imgproc.hpp"
  6. #include "opencv2/highgui/highgui.hpp"
  7. //#include <opencv2/legacy/legacy.hpp>
  8. #include <vector>
  9. #include <iostream>
  10. #include <fstream>
  11. #include <math.h>
  12. usingnamespace cv;  
  13. usingnamespace std;  
  14. void getMatchLR(string imgpath);  
  15. void getMatchDT(string imgpath);  
  16. //void getSURFFeature(string imgpath);
  17. void getORBFeature(string imgpath);  
  18. void MatchTemplate(string imgname);  
  19. void MatchTemplateORB(string imgname);  
  20. void MatchTemplateSIFT(string imgname);  
  21. void testMatch();  
  22. static string imgdir = "E:\\input_resize\\";  
  23. static string Matchsavedir = "E:\\macth_result\\";  
  24. static string TemplateDir = "E:\\template_resize\\";  
  25. //static string ORBsavedir = "ORB_result\\";
  26. IplImage mat_src_lpl;  
  27. IplImage OutImage_lpl;  
  28. IplImage TemplateIpl;  
  29. IplImage* dst_left;  
  30. IplImage* dst_right;  
  31. IplImage *src;  
  32. IplImage *TemplateIplPtr;  
  33. Mat mat_src;  
  34. Mat OutImage;  
  35. Mat TemplateMat;  
在UBUNTU12.04UTL+opencv2.4.
  1. #include "opencv2/core/core.hpp"
  2. #include "opencv2/calib3d/calib3d.hpp"
  3. #include "opencv2/features2d/features2d.hpp"
  4. #include "opencv2/imgproc/imgproc.hpp"
  5. #include "opencv2/highgui/highgui.hpp"
  6. #include <opencv2/legacy/legacy.hpp>
  7. #include <vector>
  8. #include <iostream>
  9. #include <fstream>
  10. #include <math.h>

主函式

  1. int main()  
  2. {  
  3.     string imgname = "07_in.jpg";  
  4.     //testMatch();
  5.     MatchTemplateSIFT(imgname);  
  6.     //getMatchLR(imgname);
  7.     return 0;  
  8. }  

SIFT

利用SIFT特徵進行模板匹配,template1為一個物體的小圖,然後在一張含有多個同樣物體的大圖上進行匹配。

在大圖上滑窗處理,得到每一個滑窗的特徵,進行匹配,計算距離均值,作為一個灰度值,最後生成一個大圖。

特徵子,描述符,匹配方法分別為:

  1. new SiftFeatureDetector  
  2. new SiftDescriptorExtractor;  
  3. BruteForceMatcher<L2(float)>  

詳細程式碼

  1. void MatchTemplateSIFT(string imgname)  
  2. {  
  3.     vector<KeyPoint> LeftKey;  
  4.     vector<KeyPoint> RightKey;  
  5.     Mat LeftDescriptor;  
  6.     Mat RightDescriptor;  
  7.     vector<DMatch> Matches;  
  8.     //vector<double> meanDisances;
  9.     IplImage* dst;  
  10.     ofstream fout("E:\\picin\\rBRIEF_Test\\templateCompareResult.txt");  
  11.     int xstep = 2;  
  12.     int ystep = 2;  
  13.     string TemplateName = "template1.jpg";  
  14.     string TemplateImgPath = TemplateDir + TemplateName;  
  15.     string imgpath = imgdir + imgname;  
  16.     string resultPath = Matchsavedir+imgname;  
  17.     TemplateMat = imread(TemplateImgPath,CV_LOAD_IMAGE_GRAYSCALE);  
  18.     if(!TemplateMat.data){  
  19.         cout<<"no template exist";  
  20.         return ;  
  21.     }  
  22.     int TemplateWidth = TemplateMat.cols;  
  23.     int TemplateHeight = TemplateMat.rows;  
  24.     std::cout<<"TemplateWidth "<<TemplateWidth<<endl;  
  25.     std::cout<<"TemplateHeight "<<TemplateHeight<<endl;  
  26.     FeatureDetector *pDetector = new SiftFeatureDetector;   pDetector->detect(TemplateMat, LeftKey);  
  27.     DescriptorExtractor *pExtractor = new SiftDescriptorExtractor;   
  28.     pExtractor->compute(TemplateMat, LeftKey, LeftDescriptor);  
  29.     DescriptorMatcher *pMatcher = new BruteForceMatcher<L2<float>>;  
  30.     mat_src = imread(imgpath, CV_LOAD_IMAGE_GRAYSCALE );  
  31.     if(!mat_src.data) {  
  32.         cout<<"no src img";  
  33.         return ;  
  34.       } mat_src_lpl = IplImage(mat_src);  
  35.     src  = &mat_src_lpl;  
  36.     long ImgWidth = src->width;  
  37.     long ImgHeight = src->height;  
  38.     std::cout<<"ImgWidth "<<ImgWidth<<endl;  
  39.     std::cout<<"ImgHeight "<<ImgHeight<<endl;  
  40.     int x;  
  41.     int y;  
  42.     //Mat R = Mat(ImgHeight - TemplateHeight, ImgWidth - TemplateWidth, CV_8UC1,255);
  43.     //namedWindow("result", CV_WINDOW_NORMAL );
  44.     //imshow("result",mat_src);
  45.     //uchar *p;
  46.     //while(start_x < ImgWidth - TemplateWidth){
  47.     for(long start_y = 0;start_y <ImgHeight - TemplateHeight;start_y = start_y+ystep){  
  48.         for(long start_x = 0;start_x < ImgWidth - TemplateWidth;start_x = start_x+xstep){  
  49.             x = start_x;  
  50.             y = start_y;  
  51.             cvSetImageROI(src,cvRect(x,y,TemplateWidth,TemplateHeight));  
  52.             dst = cvCreateImage(cvSize(TemplateWidth,TemplateHeight),  
  53.                     IPL_DEPTH_8U,  
  54.                     src->nChannels);  
  55.             cvCopy(src,dst,0);  
  56.             cvResetImageROI(src);  
  57.             Mat DstImage = Mat(dst, false); // Do not copy
  58.             pDetector->detect(DstImage, RightKey);  
  59.             pExtractor->compute(DstImage, RightKey, RightDescriptor);  
  60.             pMatcher->match(LeftDescriptor, RightDescriptor, Matches);  
  61.             //double sum = 0;
  62.             double sum = 0;  
  63.             //int i = 0;
  64.             for(vector<DMatch>::iterator dite = Matches.begin();dite <Matches.end(); dite++ )  
  65.               {  
  66.                   sum += dite->distance;  
  67.               }  
  68.             int matchSize = Matches.size()*10;  
  69.             if(matchSize>1){  
  70.                 fout<<exp(-sum/matchSize)<<" ";  
  71.             }else{  
  72.                 fout<<exp(-100.0)<<" ";  
  73.             }  
  74.         }  
  75.     }  
  76.     //
  77.     std::cout<<"finish";  
  78.     fout.close();  
  79.     //destroyWindow("result" );
  80.     //imwrite(resultPath,R);
  81.     delete pDetector;  
  82.     delete pExtractor;  
  83.     delete pMatcher;  
  84. }  

SURF

SURF特徵同SIFT特徵。

ORB

描述子和描述符,匹配程式碼如下
  1. ORB orb;  
  2. orb(TemplateMat,Mat(),LeftKey,LeftDescriptor);  
  3. DescriptorMatcher *pMatcher = new BruteForceMatcher<HammingLUT>;  

詳細程式碼如下

  1. void MatchTemplateORB(string imgname)  
  2. {  
  3.     vector<KeyPoint> LeftKey;  
  4.     vector<KeyPoint> RightKey;  
  5.     Mat LeftDescriptor;  
  6.     Mat RightDescriptor;  
  7.     vector<DMatch> Matches;  
  8.     //vector<double> meanDisances;
  9.     IplImage* dst;  
  10.     ofstream fout("E:\\picin\\rBRIEF_Test\\templateCompareResult.txt");  
  11.     int xstep = 2;  
  12.     int ystep = 2;  
  13.     string TemplateName = "template2.jpg";  
  14.     string TemplateImgPath = TemplateDir + TemplateName;  
  15.     string imgpath = imgdir + imgname;  
  16.     string resultPath = Matchsavedir+imgname;  
  17.         TemplateMat = imread(TemplateImgPath,CV_LOAD_IMAGE_GRAYSCALE);  
  18.     if(!TemplateMat.data){  
  19.         cout<<"no template exist";  
  20.         return ;  
  21.     }  
  22.     int TemplateWidth = TemplateMat.cols;  
  23.     int TemplateHeight = TemplateMat.rows;  
  24.     std::cout<<"TemplateWidth "<<TemplateWidth<<endl;  
  25.     std::cout<<"TemplateHeight "<<TemplateHeight<<endl;  
  26.     ORB orb;  
  27.     orb(TemplateMat,Mat(),LeftKey,LeftDescriptor);  
  28.     DescriptorMatcher *pMatcher = new BruteForceMatcher<HammingLUT>;  
  29.     mat_src = imread(imgpath, CV_LOAD_IMAGE_GRAYSCALE );  
  30.     if(!mat_src.data) {  
  31.         cout<<"no src img";  
  32.         return ;  
  33.       }  
  34.     mat_src_lpl = IplImage(mat_src);  
  35.     src  = &mat_src_lpl;  
  36.     long ImgWidth = src->width;  
  37.     long ImgHeight = src->height;  
  38.     std::cout<<"ImgWidth "<<ImgWidth<<endl;  
  39.     std::cout<<"ImgHeight "<<ImgHeight<<endl;  
  40.     int x;  
  41.     int y;  
  42.     //Mat R = Mat(ImgHeight - TemplateHeight, ImgWidth - TemplateWidth, CV_8UC1,255);
  43.     //namedWindow("result", CV_WINDOW_NORMAL );
  44.     //imshow("result",mat_src);
  45.     //uchar *p;
  46.     //while(start_x < ImgWidth - TemplateWidth){
  47.     for(long start_y = 0;start_y <ImgHeight - TemplateHeight;start_y = start_y+ystep){  
  48.         for(long start_x = 0;start_x < ImgWidth - TemplateWidth;start_x = start_x+xstep){  
  49.             x = start_x;  
  50.             y = start_y;  
  51.             //std::cout<<"<"<<x<<","<<y<<">"<<" ";
  52.             cvSetImageROI(src,cvRect(x,y,TemplateWidth,TemplateHeight));  
  53.             dst = cvCreateImage(cvSize(TemplateWidth,TemplateHeight),  
  54.                     IPL_DEPTH_8U,  
  55.                     src->nChannels);  
  56.             cvCopy(src,dst,0);  
  57.             cvResetImageROI(src);  
  58.             Mat DstImage = Mat(dst, false); // Do not copy
  59.             orb(DstImage,Mat(),RightKey,RightDescriptor);  
  60.             //std::cout<<RightDescriptor.size();
  61.             pMatcher->match(LeftDescriptor, RightDescriptor, Matches);  
  62.             //double sum = 0;
  63.             double sum = 0;  
  64.             //int i = 0;
  65.             for(vector<DMatch>::iterator dite = Matches.begin();dite <Matches.end(); dite++ )  
  66.               {  
  67.                   sum += dite->distance;  
  68.               }  
  69.             int matchSize = Matches.size()*10;  
  70.             //std::cout<<matchSize<<" ";
  71.             if(matchSize>1){  
  72.                 //int meanDis = sum/matchSize;
  73.                 fout<<exp(-sum/matchSize)<<" ";  
  74.                 //std::cout<<"meanDis"<<meanDis<<" ";
  75.                 //R.at<uchar>(x,y) = meanDis;
  76.             }else{  
  77.                 fout<<exp(-100.0)<<" ";  
  78.                 //fout<<255<<" ";
  79.                 //std::cout<<"meanDis"<<255<<" ";
  80.             }  
  81.         }  
  82.         //std::cout<<endl;
  83.         fout<<"\n";  
  84.         //start_x += step;
  85.     }  
  86.     //
  87.     std::cout<<"finish";  
  88.     fout.close();  
  89.     //destroyWindow("result" );
  90.     //imwrite(resultPath,R);
  91.     //delete pDetector;
  92.     //delete pExtractor;
  93.     delete pMatcher;  
  94. }  

對利用特徵點對圖片左右部分進行匹配

  1. void getMatchLR(string imgname)  
  2. {  
  3.     string imgpath = imgdir + imgname;  
  4.     mat_src = imread(imgpath, CV_LOAD_IMAGE_GRAYSCALE );  
  5.     if(!mat_src.data) {  
  6.         cout<<"no img";  
  7.         return ;  
  8.       }  
  9.     mat_src_lpl = IplImage(mat_src);  
  10.     src  = &mat_src_lpl;  
  11.     //
  12.     cvSetImageROI(src,cvRect(0,0,0.5*src->width,src->height));  
  13.     dst_left = cvCreateImage(cvSize(0.5*src->width,src->height),  
  14.             IPL_DEPTH_8U,  
  15.             src->nChannels);  
  16.     cvCopy(src,dst_left,0);  
  17.     cvResetImageROI(src);  
  18.     cvSetImageROI(src,cvRect(0.5*src->width,0,0.5*src->width,src->height));  
  19.     dst_right = cvCreateImage(cvSize(0.5*src->width,src->height),  
  20.             IPL_DEPTH_8U,  
  21.             src->nChannels);  
  22.     cvCopy(src,dst_right,0);  
  23.     cvResetImageROI(src);  
  24.      // Convert IplImage to cv::Mat
  25.     Mat matLeftImage = Mat(dst_left, false); // Do not copy
  26.     Mat matRightImage = Mat(dst_right, false);  
  27.     // Key point and its descriptor
  28.     vector<KeyPoint> LeftKey;  
  29.     vector<KeyPoint> RightKey;  
  30.     Mat LeftDescriptor;  
  31.     Mat RightDescriptor;  
  32.     vector<DMatch> Matches;  
  33.     /* 
  34.     // Detect key points from image 
  35.     FeatureDetector *pDetector = new FastFeatureDetector; //  
  36.     pDetector->detect(matLeftImage, LeftKey); 
  37.     pDetector->detect(matRightImage, RightKey); 
  38.     delete pDetector; 
  39.     // Extract descriptors 
  40.     DescriptorExtractor *pExtractor = new BriefDescriptorExtractor; //  
  41.     pExtractor->compute(matLeftImage, LeftKey, LeftDescriptor); 
  42.     pExtractor->compute(matRightImage, RightKey, RightDescriptor); 
  43.     delete pExtractor; 
  44.     */
  45.     ORB orb;  
  46.     orb(matLeftImage,Mat(),LeftKey,LeftDescriptor);  
  47.     orb(matRightImage,Mat(),RightKey,RightDescriptor);  
  48.     // Matching features
  49.     //DescriptorMatcher *pMatcher = new FlannBasedMatcher; // 
  50.     DescriptorMatcher *pMatcher = new BruteForceMatcher<HammingLUT>; // 
  51.     pMatcher->match(LeftDescriptor, RightDescriptor, Matches);  
  52.     delete pMatcher;  
  53.     double max_dist = 0; double min_dist = 200;  
  54.       //-- Quick calculation of max and min distances between keypoints
  55.       forint i = 0; i < LeftDescriptor.rows; i++ )  
  56.       { double dist = Matches[i].distance;  
  57.         if( dist < min_dist ) min_dist = dist;  
  58.         if( dist > max_dist ) max_dist = dist;  
  59.       }  
  60.       //printf("-- Max dist : %f \n", max_dist );
  61.       //printf("-- Min dist : %f \n", min_dist );
  62.       //-- Draw only "good" matches (i.e. whose distance is less than 2*min_dist )
  63.       //-- PS.- radiusMatch can also be used here.
  64.       std::vector< DMatch > good_matches;  
  65.       forint i = 0; i < LeftDescriptor.rows; i++ )  
  66.       { if( Matches[i].distance < 0.5*max_dist )  
  67.         { good_matches.push_back( Matches[i]); }  
  68.       }  
  69.     // Show result
  70.     //drawMatches(matLeftImage, LeftKey, matRightImage, RightKey, Matches, OutImage);
  71.     drawMatches( matLeftImage, LeftKey, matRightImage, RightKey,  
  72.                    good_matches, OutImage, Scalar::all(-1), Scalar::all(-1),  
  73.                    vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );  
  74.     OutImage_lpl = IplImage(OutImage);  
  75.     cvNamedWindow( "Match features", 1);  
  76.     cvShowImage("Match features", &(OutImage_lpl));  
  77.     cvWaitKey( 0 );  
  78.     cvDestroyWindow( "Match features" );  
  79.     string savepath = Matchsavedir + imgname;  
  80.       //-- Show detected (drawn) keypoints
  81.     imwrite(savepath, OutImage );//
  82. }  

以上程式碼中被註釋的部分
  1. // Detect key points from image
  2. FeatureDetector *pDetector = new FastFeatureDetector; // 
  3. pDetector->detect(matLeftImage, LeftKey);  
  4. pDetector->detect(matRightImage, RightKey);  
  5. delete pDetector;  
  6. // Extract descriptors
  7. DescriptorExtractor *pExtractor = new BriefDescriptorExtractor; // 
  8. pExtractor->compute(matLeftImage, LeftKey, LeftDescriptor);  
  9. pExtractor->compute(matRightImage, RightKey, RightDescriptor);  

是利用的BRIEF特徵,進行左右匹配