1、资料harris角点检测原理步骤说明资料harris角点检测原理步骤说明一、Harris角点检测基本理论1.1 简略表达: 角点:最直观的印象就是在水平、竖直两个方向上变化均较大的点,即Ix、Iy都较大 边缘:仅在水平、或者仅在竖直方向有较大的变化量,即Ix和Iy只有其一较大 平坦地区:在水平、竖直方向的变化量均较小,即Ix、Iy都较小 角点响应 R=det(M)-k*(trace(M)2) (附录资料给出k=0.040.06,opencv指出是0.05-0.5,浮动较大) det(M)=1*2 trace(M)=1+2 R取决于M的特征值,对于角点|R|很大,平坦的区域|R|很小,边缘的R为
2、负值。1.2 详细描述:见附录里的ppt 1.3 算法步骤 其中,局部极大值可用先膨胀后与原图比较的方法求得,具体见二中源码。二、opencv代码实现 harris类 cpp view plaincopyprint? 1. #ifndef HARRIS_H 2. #define HARRIS_H 3. #include opencv2/opencv.hpp 4. 5. class harris 6. 7. private: 8. cv:Mat cornerStrength; /opencv harris函数检测结果,也就是每个像素的角点响应函数值 9. cv:Mat cornerTh; /co
3、rnerStrength阈值化的结果 10. cv:Mat localMax; /局部最大值结果 11. int neighbourhood; /邻域窗口大小 12. int aperture;/sobel边缘检测窗口大小(sobel获取各像素点x,y方向的灰度导数) 13. double k; 14. double maxStrength;/角点响应函数最大值 15. double threshold;/阈值除去响应小的值 16. int nonMaxSize;/这里采用默认的3,就是最大值抑制的邻域窗口大小 17. cv:Mat kernel;/最大值抑制的核,这里也就是膨胀用到的核 18
4、. public: 19. harris():neighbourhood(3),aperture(3),k(0.01),maxStrength(0.0),threshold(0.01),nonMaxSize(3) 20. 21. ; 22. 23. void setLocalMaxWindowsize(int nonMaxSize) 24. this-nonMaxSize = nonMaxSize; 25. ; 26. 27. /计算角点响应函数以及非最大值抑制 28. void detect(const cv:Mat &image) 29. /opencv自带的角点响应函数计算函数 30.
5、cv:cornerHarris (image,cornerStrength,neighbourhood,aperture,k); 31. double minStrength; 32. /计算最大最小响应值 33. cv:minMaxLoc (cornerStrength,&minStrength,&maxStrength); 34. 35. cv:Mat dilated; 36. /默认3*3核膨胀,膨胀之后,除了局部最大值点和原来相同,其它非局部最大值点被 37. /3*3邻域内的最大值点取代 38. cv:dilate (cornerStrength,dilated,cv:Mat();
6、39. /与原图相比,只剩下和原图值相同的点,这些点都是局部最大值点,保存到localMax 40. cv:compare(cornerStrength,dilated,localMax,cv:CMP_EQ); 41. 42. 43. /获取角点图 44. cv:Mat getCornerMap(double qualityLevel) 45. cv:Mat cornerMap; 46. / 根据角点响应最大值计算阈值 47. threshold= qualityLevel*maxStrength; 48. cv:threshold(cornerStrength,cornerTh, 49. t
7、hreshold,255,cv:THRESH_BINARY); 50. / 转为8-bit图 51. cornerTh.convertTo(cornerMap,CV_8U); 52. / 和局部最大值图与,剩下角点局部最大值图,即:完成非最大值抑制 53. cv:bitwise_and(cornerMap,localMax,cornerMap); 54. return cornerMap; 55. 56. 57. void getCorners(std:vector &points, 58. double qualityLevel) 59. /获取角点图 60. cv:Mat cornerMa
8、p= getCornerMap(qualityLevel); 61. / 获取角点 62. getCorners(points, cornerMap); 63. 64. 65. / 遍历全图,获得角点 66. void getCorners(std:vector &points, 67. const cv:Mat& cornerMap) 68. 69. for( int y = 0; y cornerMap.rows; y+ ) 70. const uchar* rowPtr = cornerMap.ptr(y); 71. for( int x = 0; x cornerMap.cols; x
9、+ ) 72. / 非零点就是角点 73. if (rowPtrx) 74. points.push_back(cv:Point(x,y); 75. 76. 77. 78. 79. 80. /用圈圈标记角点 81. void drawOnImage(cv:Mat &image, 82. const std:vector &points, 83. cv:Scalar color= cv:Scalar(255,255,255), 84. int radius=3, int thickness=2) 85. std:vector:const_iterator it=points.begin(); 8
10、6. while (it!=points.end() 87. / 角点处画圈 88. cv:circle(image,*it,radius,color,thickness); 89. +it; 90. 91. 92. 93. ; 94. 95. #endif / HARRIS_H 相关测试代码: cpp view plaincopyprint? 1. cv:Mat image, image1 = cv:imread (test.jpg); 2. /灰度变换 3. cv:cvtColor (image1,image,CV_BGR2GRAY); 4. 5. 6. / 经典的harris角点方法 7
11、. harris Harris; 8. / 计算角点 9. Harris.detect(image); 10. /获得角点 11. std:vector pts; 12. Harris.getCorners(pts,0.01); 13. / 标记角点 14. Harris.drawOnImage(image,pts); 15. 16. cv:namedWindow (harris); 17. cv:imshow (harris,image); 18. cv:waitKey (0); 19. return 0; 相关测试结果: 三、改进的Harris角点检测 从经典的Harris角点检测方法不难
12、看出,该算法的稳定性和k有关,而k是个经验值,不好把握,浮动也有可能较大。鉴于此,改进的Harris方法()直接计算出两个特征值,通过比较两个特征值直接分类,这样就不用计算Harris响应函数了。另一方面,我们不再用非极大值抑制了,而选取容忍距离:容忍距离内只有一个特征点。 该算法首先选取一个具有最大 最小特征值的点(即:max(min(e1,e2),e1,e2是harris矩阵的特征值)作为角点,然后依次按照最大最小特征值顺序寻找余下的角点,当然和前一角点距离在容忍距离内的新角点呗忽略。 opencv测试该算法代码如下: cpp view plaincopyprint? 1. cv:Mat
13、image, image1 = cv:imread (test.jpg); 2. /灰度变换 3. cv:cvtColor (image1,image,CV_BGR2GRAY); 4. / 改进的harris角点检测方法 5. std:vector corners; 6. cv:goodFeaturesToTrack(image,corners, 7. 200, 8. /角点最大数目 9. 0.01, 10. / 质量等级,这里是0.01*max(min(e1,e2),e1,e2是harris矩阵的特征值 11. 10); 12. / 两个角点之间的距离容忍度 13. harris().dra
14、wOnImage(image,corners);/标记角点 测试结果如下: 四、FAST角点检测 算法原理比较简单,但实时性很强。 该算法的角点定义为:若某像素点圆形邻域圆周上有3/4的点和该像素点不同(编程时不超过某阈值th),则认为该点就是候选角点。opencv更极端,选用半径为3的圆周上(上下左右)四个点,若超过三个点和该像素点不同,则该点为候选角点。和Harris算法类似,该算法需要非极大值抑制。 opencv代码: cpp view plaincopyprint? 1. cv:Mat image, image1 = cv:imread (test.jpg); 2. cv:cvtColor (image1,image,CV_BGR2GRAY); 3. /快速角点检测 4. std:vector keypoints; 5. cv:FastFeatureDetector fast(40,true); 6. fast .detect (image,keypoints); 7. cv:drawKeypoints (image,keypoints,image,cv:Scalar:all(255),cv:DrawMatchesFlags:DRAW_OVER_OUTIMG); 测试结果如下: 五
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1