资料harris角点检测原理步骤说明.docx
《资料harris角点检测原理步骤说明.docx》由会员分享,可在线阅读,更多相关《资料harris角点检测原理步骤说明.docx(10页珍藏版)》请在冰豆网上搜索。
![资料harris角点检测原理步骤说明.docx](https://file1.bdocx.com/fileroot1/2022-11/19/c6a2a1c2-f814-4558-b35d-06c214daf42a/c6a2a1c2-f814-4558-b35d-06c214daf42a1.gif)
资料harris角点检测原理步骤说明
[资料]harris角点检测原理步骤说明
一、Harris角点检测基本理论
1.1简略表达:
角点:
最直观的印象就是在水平、竖直两个方向上变化均较大的点,即Ix、Iy都较大边缘:
仅在水平、或者仅在竖直方向有较大的变化量,即Ix和Iy只有其一较大平坦地区:
在水平、竖直方向的变化量均较小,即Ix、Iy都较小
角点响应
R=det(M)-k*(trace(M)^2)(附录资料给出k=0.04~0.06,opencv指出是0.05-0.5,浮动较大)
det(M)=λ1*λ2trace(M)=λ1+λ2
R取决于M的特征值,对于角点|R|很大,平坦的区域|R|很小,边缘的R为负值。
1.2详细描述:
见附录里的ppt
1.3算法步骤
其中,局部极大值可用先膨胀后与原图比较的方法求得,具体见二中源码。
二、opencv代码实现
harris类
[cpp]viewplaincopyprint?
1.#ifndefHARRIS_H
2.#defineHARRIS_H
3.#include"opencv2/opencv.hpp"
4.
5.classharris
6.{
7.private:
8.cv:
:
MatcornerStrength;//opencvharris函数检测结果,也就是每个像素的角点
响应函数值
9.cv:
:
MatcornerTh;//cornerStrength阈值化的结果10.cv:
:
MatlocalMax;//局部最大值结果11.intneighbourhood;//邻域窗口大小12.intaperture;//sobel边缘检测窗口大小(sobel获取各像素点x,y方向的灰度导
数)
13.doublek;
14.doublemaxStrength;//角点响应函数最大值15.doublethreshold;//阈值除去响应小的值16.intnonMaxSize;//这里采用默认的3,就是最大值抑制的邻域窗口大小
17.cv:
:
Matkernel;//最大值抑制的核,这里也就是膨胀用到的核
18.public:
19.harris():
neighbourhood(3),aperture(3),k(0.01),maxStrength(0.0),threshold(0.01)
nonMaxSize(3){
20.
21.};
22.
23.voidsetLocalMaxWindowsize(intnonMaxSize){24.this->nonMaxSize=nonMaxSize;25.};
26.
27.//计算角点响应函数以及非最大值抑制28.voiddetect(constcv:
:
Mat&image){29.//opencv自带的角点响应函数计算函数30.cv:
:
cornerHarris(image,cornerStrength,neighbourhood,aperture,k);
31.doubleminStrength;
32.//计算最大最小响应值
33.cv:
:
minMaxLoc(cornerStrength,&minStrength,&maxStrength);
34.
35.cv:
:
Matdilated;
36.//默认3*3核膨胀,膨胀之后,除了局部最大值点和原来相同,其它非局部
最大值点被
37.//3*3邻域内的最大值点取代38.cv:
:
dilate(cornerStrength,dilated,cv:
:
Mat());39.//与原图相比,只剩下和原图值相同的点,这些点都是局部最大值点,保存
到localMax
40.cv:
:
compare(cornerStrength,dilated,localMax,cv:
:
CMP_EQ);
41.}
42.
43.//获取角点图
44.cv:
:
MatgetCornerMap(doublequalityLevel){45.cv:
:
MatcornerMap;
46.//根据角点响应最大值计算阈值47.threshold=qualityLevel*maxStrength;48.cv:
:
threshold(cornerStrength,cornerTh,49.threshold,255,cv:
:
THRESH_BINARY);50.//转为8-bit图
51.cornerTh.convertTo(cornerMap,CV_8U);
52.//和局部最大值图与,剩下角点局部最大值图,即:
完成非最大值抑制
53.cv:
:
bitwise_and(cornerMap,localMax,cornerMap);54.returncornerMap;
55.}
56.
57.voidgetCorners(std:
:
vector:
Point>&points,58.doublequalityLevel){
59.//获取角点图
60.cv:
:
MatcornerMap=getCornerMap(qualityLevel);61.//获取角点
62.getCorners(points,cornerMap);63.}
64.
65.//遍历全图,获得角点
66.voidgetCorners(std:
:
vector:
Point>&points,67.constcv:
:
Mat&cornerMap){
68.
69.for(inty=0;y(y);
71.for(intx=0;x73.if(rowPtr[x]){
74.points.push_back(cv:
:
Point(x,y));75.}
76.}
77.}
78.}
79.
80.//用圈圈标记角点
81.voiddrawOnImage(cv:
:
Mat&image,82.conststd:
:
vector:
Point>&points,83.cv:
:
Scalarcolor=cv:
:
Scalar(255,255,255),84.intradius=3,intthickness=2){
85.std:
:
vector:
Point>:
:
const_iteratorit=points.begin();
86.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]viewplaincopyprint?
1.cv:
:
Matimage,image1=cv:
:
imread("test.jpg");
2.//灰度变换
3.cv:
:
cvtColor(image1,image,CV_BGR2GRAY);
4.
5.
6.//经典的harris角点方法7.harrisHarris;
8.//计算角点
9.Harris.detect(image);10.//获得角点
11.std:
:
vector:
Point>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.return0;
相关测试结果:
三、改进的Harris角点检测
从经典的Harris角点检测方法不难看出,该算法的稳定性和k有关,而k是个经验值,
不好把握,浮动也有可能较大。
鉴于此,改进的Harris方法()直接计算出两个特征值,
通过比较两个特征值直接分类,这样就不用计算Harris响应函数了。
另一方面,我们不再用非极大值抑制了,而选取容忍距离:
容忍距离内只有一个特征点。
该算法首先选取一个具有最大最小特征值的点(即:
max(min(e1,e2)),e1,e2是harris矩阵的特征值)作为角点,然后依次按照最大最小特征值顺序寻找余下的角点,当然和前一角点距离在容忍距离内的新角点呗忽略。
opencv测试该算法代码如下:
[cpp]viewplaincopyprint?
1.cv:
:
Matimage,image1=cv:
:
imread("test.jpg");
2.//灰度变换
3.cv:
:
cvtColor(image1,image,CV_BGR2GRAY);
4.//改进的harris角点检测方法
5.std:
:
vector:
Point>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().drawOnImage(image,corners);//标记角点
测试结果如下:
四、FAST角点检测
算法原理比较简单,但实时性很强。
该算法的角点定义为:
若某像素点圆形邻域圆周上有3/4的点和该像素点不同(编程时不超过某阈值th),则认为该点就是候选角点。
opencv更极端,选用半径为3的圆周上(上下左右)四个点,若超过三个点和该像素点不同,则该点为候选角点。
和Harris算法类似,该算法需要非极大值抑制。
opencv代码:
[cpp]viewplaincopyprint?
1.cv:
:
Matimage,image1=cv:
:
imread("test.jpg");
2.cv:
:
cvtColor(image1,image,CV_BGR2GRAY);
3.//快速角点检测
4.std:
:
vector:
KeyPoint>keypoints;
5.cv:
:
FastFeatureDetectorfast(40,true);
6.fast.detect(image,keypoints);
7.cv:
:
drawKeypoints(image,keypoints,image,cv:
:
Scalar:
:
all(255),cv:
:
DrawMatchesF
lags:
:
DRAW_OVER_OUTIMG);
测试结果如下:
五