可参考:http://www.cnblogs.com/ronny/p/4009425.html
http://www.cnblogs.com/ztfei/archive/2012/05/07/2487123.html
http://blog.csdn.net/crzy_sparrow/article/details/7391511
矩阵M(x)的特征值能表示在水平和竖直方向的变化程度,但Harris给出的角点差别方法并不需要计算具体的特征值,而是计算一个
角点响应值R来判断。
alpha的值对角点检测的影响:增大α的值,将减小角点响应值R,降低角点检测的灵性,减少被检测角点的数量;减小α值,将增大角点响应值R,增加角点检测的灵敏性,增加被检测角点的数量。
关于尺度不变性:
下面是代码,我加了部分注释


#include "opencv2/core/core.hpp" #include "opencv2/features2d/features2d.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/calib3d/calib3d.hpp" #include "opencv2/nonfree/nonfree.hpp" #include<opencv2/highgui/highgui.hpp> #include<opencv2/imgproc/imgproc.hpp> #include <iostream> using namespace cv; using namespace std;/*void drawCornerOnImage(Mat& image, const Mat&binary) {Mat_<uchar>::const_iterator it = binary.begin<uchar>();Mat_<uchar>::const_iterator itd = binary.end<uchar>();for (int i = 0; it != itd; it++, i++){//Point内时什么意思?if (*it)circle(image, Point(i%image.cols, i / image.cols), 3, Scalar(0, 255, 0), 1);} } */ /******************下面是Harris角点检测的C++实现*******************************/ /* void detectHarrisCorners(const Mat& imgSrc,Mat& imgDst,double alpha ) {Mat gray;if (imgSrc.channels() == 3)cvtColor(imgSrc, gray, CV_BGR2GRAY);elsegray = imgSrc.clone();gray.convertTo(gray, CV_64F);//第二个参数depthMat xKernel = (Mat_<double>(1, 3) << -1, 0, 1);//模板一行三列,后面为相应的值Mat yKernel = xKernel.t();Mat Ix, Iy;//Convolves an image with the kernel.filter2D(gray, Ix, CV_64F, xKernel);filter2D(gray, Iy, CV_64F, yKernel);Mat Ix2, Iy2, Ixy;//计算图像两个梯度方向的乘积Ix2 = Ix.mul(Ix);Iy2 = Iy.mul(Iy);Ixy = Ix.mul(Iy);Mat gaussKernel = getGaussianKernel(7, 1);filter2D(Ix2, Ix2, CV_64F, gaussKernel);filter2D(Iy2, Iy2, CV_64F, gaussKernel);filter2D(Ixy, Ixy, CV_64F, gaussKernel);Mat cornerStrength(gray.size(), gray.type());for (int i = 0; i < gray.rows; i++){for (int j = 0; j < gray.cols; j++){double det_m = Ix2.at<double>(i, j)*Iy2.at<double>(i, j)-Ixy.at<double>(i,j)*Ixy.at<double>(i,j);double trace_m = Ix2.at<double>(i, j) + Iy2.at<double>(i, j);cornerStrength.at<double>(i,j) = det_m - trace_m;}}//thresholddouble maxStrength;minMaxLoc(cornerStrength, NULL, &maxStrength, NULL, NULL);Mat dilated, localMax;//默认3*3核膨胀,膨胀之后,除了局部最大值点和原来相同,其它非局部最大值点被 //3*3邻域内的最大值点取代 dilate(cornerStrength, dilated, Mat());imshow("dilated", dilated);imshow("cornerStrength", cornerStrength);//与原图相比,只剩下和原图值相同的点,这些点都是局部最大值点,保存到localMax compare(cornerStrength, dilated, localMax, CMP_EQ);//两图中相同的地方进行比较,相等的地方设为255imshow("localMax", localMax);Mat cornerMap;double qualityLevel = 0.01;double thresh = qualityLevel * maxStrength;cornerMap = cornerStrength > thresh;bitwise_and(cornerMap, localMax, cornerMap);//将两图进行与操作imgDst = cornerMap.clone();}*/ int main() {/******harris角点检测的C++实现********//*Mat img = imread("1.jpg");imshow("原图", img);Mat gray,dst;cvtColor(img, gray, CV_BGR2GRAY);detectHarrisCorners(img, dst, 0.01);imshow("目标", dst);drawCornerOnImage(img, dst);imshow("处理后", img);*/////*************************下面是用opencv自带的角点检测函数*************************/ /*Mat img = imread("1.jpg");imshow("原图", img);Mat gray;cvtColor(img, gray, CV_BGR2GRAY);Mat cornerStrenth;cornerHarris(gray, cornerStrenth, 3, 3, 0.1);//imshow("cornerstrenth", cornerStrenth);threshold(cornerStrenth, cornerStrenth, 0.001, 255, THRESH_BINARY);//imshow("cornerstrenth", cornerStrenth);double maxStrength, minStrength;minMaxLoc(cornerStrenth, &minStrength, &maxStrength);Mat dilated;Mat locaMax;// // 膨胀图像,找出图像中全部的局部最大值点dilate(cornerStrenth, dilated, Mat());//imshow("dilated", dilated);// compare是一个逻辑比较函数,返回两幅图像中对应点相同的二值图像compare(cornerStrenth, dilated, locaMax, CMP_EQ);//imshow("locaMax", locaMax);Mat cornerMap;double qualityLevel = 0.01;double th = qualityLevel*maxStrength; // 阈值计算threshold(cornerStrenth, cornerMap, th, 255, THRESH_BINARY);//imshow("cornerMap", cornerMap);// 转为8-bit图cornerMap.convertTo(cornerMap, CV_8U);//imshow("cornerMap1", cornerMap);// 逐点的位运算// 和局部最大值图与,剩下角点局部最大值图,即:完成非最大值抑制bitwise_and(cornerMap, locaMax, cornerMap);//imshow("cornerMap2", cornerMap);drawCornerOnImage(img, cornerMap);namedWindow("result");imshow("result", img);//imshow("角点", cornerStrenth);waitKey(0);return 0;*/waitKey(0);return 0; }