Harris角点检测完以后如何进行配准

[html]  view plain  copy
  1.   
本人菜鸟一枚,刚刚接触opencv进行三维重建,在进行角点检测匹配的时候,遇到了harris角点匹配的问题,在教材中只提到harris角点的检测,却没有详细的关于harris角点匹配问题,完成角点检测以后,接下来就蒙圈了,不知道如何下手了,关于surf、sift两种检测匹配算法,在opencv3中都封装了相关的函数,包括计算特征点、描述子,而在harris的角点检测部分中没有描述子一说,这时候怎么办???

无奈返回到opencv的头文件中去寻找关于匹配部分的函数。返回查找KeyPoint类下的函数,发现一个非常有意思的函数。如下:

[html]  view plain  copy
  1. CV_WRAP static void convert(const std::vector<Point2f>& points2f,  
  2.                              CV_OUT std::vector<KeyPoint>& keypoints,  
  3.                              float size=1, float response=1, int octave=0, int class_id=-1);  
该函数告诉我们可以将harris检测到的Point2f类型的特征点转化为KeyPoint类型,其中关于尺度等等都做了初始化,于是乎可以将KeyPoint类型特征点作为sift的特征点,然后利用sift中的检测描述子函数来完成描述子的检测,最后可以和各种函数匹配函数组合来完成两张图中的harris角点匹配。

不多说了,直接上代码!

1.主函数

main.cpp文件

[html]  view plain  copy
  1. //--------------------------------------【程序说明】-------------------------------------------  
  2. //      程序说明:参考了《OpenCV3编程入门》OpenCV3版书本配套示例程序88  
  3. //      程序描述:亚像素级角点检测匹配  
  4. //      开发测试所用操作系统: Windows 7 64bit  
  5. //      开发测试所用IDE版本:Visual Studio 2010  
  6. //      开发测试所用OpenCV版本: 3.0 betarExtra  
  7. //      2014年11月 Created by @yiweixianyi  
  8. //      2014年12月 Revised by @yiweixianyi  
  9. //------------------------------------------------------------------------------------------------  
  10.   
  11.   
  12.   
  13. //---------------------------------【头文件、命名空间包含部分】----------------------------  
  14. //      描述:包含程序所使用的头文件和命名空间  
  15. //------------------------------------------------------------------------------------------------  
  16. #include "opencv2/highgui/highgui.hpp"  
  17. #include "opencv2/imgproc/imgproc.hpp"  
  18. #include <iostream>  
  19. #include "harris.h"  
  20. #include "harrismatch.h"  
  21. using namespace cv;  
  22. using namespace std;  
  23.   
  24.   
  25. //-----------------------------------【宏定义部分】--------------------------------------------   
  26. //  描述:定义一些辅助宏   
  27. //----------------------------------------------------------------------------------------------  
  28. #define WINDOW_NAME "【亚像素级角点检测】"        //为窗口标题定义的宏   
  29.   
  30. //-----------------------------------【ShowHelpText( )函数】----------------------------------  
  31. //          描述:输出一些帮助信息  
  32. //----------------------------------------------------------------------------------------------  
  33. static void ShowHelpText( )  
  34. {  
  35.     //输出欢迎信息和OpenCV版本  
  36.     printf("\n\n  ----------------------------------------------------------------------------\n");  
  37.     //输出一些帮助信息  
  38.     printf("\n\t欢迎来到【亚像素级角点检测】示例程序\n\n");   
  39.     printf("\n\t请调整滑动条观察图像效果\n\n");  
  40.   
  41. }  
  42.   
  43.   
  44. //--------------------------------------【main( )函数】-----------------------------------------  
  45. //          描述:控制台应用程序的入口函数,我们的程序从这里开始执行  
  46. //-----------------------------------------------------------------------------------------------  
  47. int main(  )  
  48. {  
  49.     int keypointnum=300;  
  50.     int matchnum=50;  
  51.     Mat g_srcImage1, g_srcImage2;  
  52.     vector<KeyPoint> keypoints1,keypoints2;   
  53.     //【0】改变console字体颜色  
  54.     system("color 2F");   
  55.   
  56.     //【0】显示帮助文字  
  57.     ShowHelpText();  
  58.   
  59.     //【1】载入源图像并将其转换为灰度图  
  60.     g_srcImage1 = imread("1.jpg", 1 );  
  61.     g_srcImage2 = imread("1.jpg", 1 );   
  62.     //cvtColor( g_srcImage, g_grayImage, COLOR_BGR2GRAY );  
  63.   
  64.     //【2】创建窗口和滑动条,并进行显示和回调函数初始化  
  65.     //namedWindow( WINDOW_NAME, WINDOW_AUTOSIZE );  
  66.     //createTrackbar( "最大角点数", WINDOW_NAME, &g_maxCornerNumber, g_maxTrackbarNumber, on_GoodFeaturesToTrack );  
  67.     on_GoodFeaturesToTrack( g_srcImage1, keypoints1,keypointnum );  
  68.     on_GoodFeaturesToTrack( g_srcImage2, keypoints2,keypointnum );  
  69.   
  70.     //imshow( WINDOW_NAME, g_srcImage );  
  71.     harrismatch(g_srcImage1, g_srcImage2, keypoints1,keypoints2,matchnum);  
  72.   
  73.     waitKey(0);  
  74.     return(0);  
  75. }  
2.harris角点检测

harris.h文件

[html]  view plain  copy
  1. #include "opencv2/highgui/highgui.hpp"  
  2. #include "opencv2/imgproc/imgproc.hpp"  
  3. #include <iostream>  
  4. using namespace cv;  
  5. using namespace std;  
  6.   
  7. #define WINDOW_NAME "【亚像素级角点检测】"        //为窗口标题定义的宏   
  8.   
  9. void on_GoodFeaturesToTrack(Mat g_srcImage, vector<KeyPoint>& keypoints,int g_maxCornerNumber );  


harris.cpp文件

[html]  view plain  copy
  1. #include "opencv2/highgui/highgui.hpp"  
  2. #include "opencv2/imgproc/imgproc.hpp"  
  3. #include <iostream>  
  4. #include "harris.h"  
  5. using namespace cv;  
  6. using namespace std;  
  7.   
  8. void on_GoodFeaturesToTrack(Mat g_srcImage, vector<KeyPoint>& keypoints,int g_maxCornerNumber )  
  9. {  
  10.     Mat g_grayImage;  
  11.     RNG g_rng(12345);//初始化随机数生成器  
  12.     cvtColor( g_srcImage, g_grayImage, COLOR_BGR2GRAY );  
  13.     //【1】对变量小于等于1时的处理  
  14.     if( g_maxCornerNumber <= 1 ) { g_maxCornerNumber = 1; }  
  15.   
  16.     //【2】Shi-Tomasi算法(goodFeaturesToTrack函数)的参数准备  
  17.     vector<Point2f> corners;  
  18.     double qualityLevel = 0.01;//角点检测可接受的最小特征值  
  19.     double minDistance = 10;//角点之间的最小距离  
  20.     int blockSize = 3;//计算导数自相关矩阵时指定的邻域范围  
  21.     double k = 0.04;//权重系数  
  22.     Mat copy = g_srcImage.clone();  //复制源图像到一个临时变量中,作为感兴趣区域  
  23.   
  24.     //【3】进行Shi-Tomasi角点检测  
  25.     goodFeaturesToTrack( g_grayImage,//输入图像  
  26.         corners,//检测到的角点的输出向量  
  27.         g_maxCornerNumber,//角点的最大数量  
  28.         qualityLevel,//角点检测可接受的最小特征值  
  29.         minDistance,//角点之间的最小距离  
  30.         Mat(),//感兴趣区域  
  31.         blockSize,//计算导数自相关矩阵时指定的邻域范围  
  32.         false,//不使用Harris角点检测  
  33.         k );//权重系数  
  34.   
  35.     //【4】输出文字信息  
  36.     cout<<"\n\t>-------------此次检测到的角点数量为:"<<corners.size()<<endl;  
  37.   
  38.     //【5】绘制检测到的角点  
  39.     //int r = 4;  
  40.     //for( unsigned int i = 0; i < corners.size(); i++ )  
  41.     //{   
  42.     //  //以随机的颜色绘制出角点  
  43.     //  circle( copy, corners[i], r, Scalar(g_rng.uniform(0,255), g_rng.uniform(0,255),  
  44.     //      g_rng.uniform(0,255)), -1, 8, 0 );   
  45.     //}  
  46.   
  47.     //【6】显示(更新)窗口  
  48.     //imshow( WINDOW_NAME, copy );  
  49.   
  50.     //【7】亚像素角点检测的参数设置  
  51.     Size winSize = Size( 5, 5 );  
  52.     Size zeroZone = Size( -1, -1 );  
  53.     //此句代码的OpenCV2版为:  
  54.     //TermCriteria criteria = TermCriteria( CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 40, 0.001 );  
  55.     //此句代码的OpenCV3版为:  
  56.     TermCriteria criteria = TermCriteria( TermCriteria::EPS + TermCriteria::MAX_ITER, 40, 0.001 );  
  57.   
  58.     //【8】计算出亚像素角点位置  
  59.     cornerSubPix( g_grayImage, corners, winSize, zeroZone, criteria );  
  60.   
  61.     //【9】输出角点信息  
  62. //  for( int i = 0; i < corners.size(); i++ )  
  63. //  { cout<<" \t>>精确角点坐标["<<i<<"]  ("<<corners[i].x<<","<<corners[i].y<<")"<<endl; }  
  64.   
  65.     KeyPoint::convert(corners,keypoints);  
  66. }  

3.角点匹配

harrismatch.h文件

[html]  view plain  copy
  1. #include "opencv2/highgui/highgui.hpp"  
  2. #include "opencv2/imgproc/imgproc.hpp"  
  3. #include <iostream>  
  4. #include <opencv2/opencv.hpp>  
  5. #include <vector>  
  6. using namespace cv;  
  7. using namespace std;  
  8.   
  9.   
  10. void harrismatch(Mat img1, Mat img2, vector<KeyPoint> keyImg1,vector<KeyPoint> keyImg2,int matchnum);  


harrismatch.cpp文件

[html]  view plain  copy
  1. #include "opencv2/highgui/highgui.hpp"  
  2. #include "opencv2/imgproc/imgproc.hpp"  
  3. #include "opencv2/xfeatures2d/nonfree.hpp"  
  4. #include <opencv2/xfeatures2d.hpp>  
  5. #include <iostream>  
  6. #include "harrismatch.h"  
  7. using namespace cv;  
  8. using namespace std;  
  9.   
  10.   
  11. void harrismatch(Mat img1, Mat img2, vector<KeyPoint> keyImg1,vector<KeyPoint> keyImg2,int matchnum)  
  12. {  
  13.     Ptr<Feature2D> bxfeatures2d::SIFT::create();  
  14.   
  15.     Ptr<DescriptorMatcher> descriptorMatcher;  
  16.   
  17.     // Match between img1 and img2  
  18.     vector<DMatch> matches;  
  19.   
  20.     // Descriptor for img1 and img2  
  21.     Mat descImg1, descImg2;  
  22.   
  23.     // and compute their descriptors with method  compute  
  24.     b->compute(img1, keyImg1, descImg1);  
  25.     b->compute(img1, keyImg2, descImg2);  
  26.     // Match method loop  
  27.     descriptorMatcher = DescriptorMatcher::create("BruteForce-L1");  
  28.   
  29.     descriptorMatcher->match(descImg1, descImg2, matches, Mat());  
  30.     // Keep best matches only to have a nice drawing.  
  31.     // We sort distance between descriptor matches  
  32.     Mat index;  
  33.     int nbMatch=int(matches.size());  
  34.     Mat tab(nbMatch, 1, CV_32F);  
  35.     for (int i = 0; i<nbMatch; i++)  
  36.     {  
  37.         tab.at<float>(i, 0) = matches[i].distance;  
  38.     }  
  39.     sortIdx(tab, index, SORT_EVERY_COLUMN + SORT_ASCENDING);  
  40.     vector<DMatch> bestMatches;  
  41.     for (int i = 0; i<matchnum; i++)  
  42.     {  
  43.         bestMatches.push_back(matches[index.at<int>(i, 0)]);  
  44.     }  
  45.     Mat result;  
  46.     drawMatches(img1, keyImg1, img2, keyImg2, bestMatches, result);  
  47.     namedWindow("harris_sift_match", WINDOW_AUTOSIZE);  
  48.     imshow("harris_sift_match", result);  
  49.     waitKey();  
  50.   
  51. }  
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值