算法原理:
http://blog.csdn.net/lcc_633/article/details/52691311
算法详细步骤:
第一步:计算图像X方向与Y方向的一阶高斯偏导数Ix与Iy
第二步:根据第一步结果得到Ix^2 , Iy^2与Ix*Iy值
第三步:高斯模糊第二步三个值得到Sxx, Syy, Sxy
第四部:定义每个像素的Harris矩阵,计算出矩阵的两个特质值
第五步:计算出每个像素的R值
第六步:使用3X3或者5X5的窗口,实现非最大值压制
第七步:根据角度检测结果计算,最提取到的关键点以绿色标记,显示在原图上。
#include<opencv2\opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;
class harris {
private:
Mat cornerStrength;
Mat cornerTh;
Mat localMax;
Mat kernel;
int neighbourhood;
int aperture;
double k;
double maxStrength;
double Threshold;
int nonMaxSize;
public:
harris():neighbourhood(3),aperture(3),k(0.01),maxStrength(0),Threshold(0.1),nonMaxSize(0){}
void detect(const Mat& img) {
cornerHarris(img, cornerStrength, neighbourhood, aperture, k);
double minStrength = 0;
minMaxLoc(cornerStrength, &minStrength, &maxStrength);
Mat temp;
dilate(cornerStrength, temp, Mat());
compare(temp, cornerStrength, localMax, CMP_EQ);
}
void getCorners(vector<Point> &point, double value) {
Mat tempMap;
Threshold = value * maxStrength;
threshold(cornerStrength, cornerTh, Threshold, 255, THRESH_BINARY);
cornerTh.convertTo(tempMap, CV_8U);
bitwise_and(tempMap, localMax, tempMap);
for (int i = 0; i < tempMap.rows; i++) {
const uchar* p = tempMap.ptr<uchar>(i);
for (int j = 0; j < tempMap.cols; j++) {
if (p[j]) {
point.push_back(Point(j, i));
}
}
}
}
void drawOnImg(Mat &img, const vector<Point> &point, Scalar color = Scalar(255,155,155),int radis = 3, int thickness = 2) {
vector<Point>::const_iterator it = point.begin();
for (;it != point.end(); ++it) {
circle(img, *it, radis, color, thickness);
}
}
};
void main() {
Mat img = imread("E://图片//1.jpg");
if (img.empty()) {
return;
}
Mat gray;
cvtColor(img, gray, CV_BGR2GRAY);
harris goal;
vector<Point> pointDetect;
goal.detect(gray);
goal.getCorners(pointDetect, 0.01);
goal.drawOnImg(img, pointDetect);
imshow("result", img);
waitKey(0);
}
运行结果: