检测图像中的角点
参考博客
文献1
文献2
代码程序
#include <iostream>
#include <vector>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
class HarrisDetector{
private:
cv::Mat cornerStrength;
cv::Mat cornerTh;
cv::Mat localMax;
int neighborhood;
int aperture;
double k;
double maxStrength;
double threshold;
int nonMaxSize;
cv::Mat kernel;
public:
HarrisDetector():neighborhood(3),aperture(3),
k(0.01), maxStrength(0.0),
threshold(0.01), nonMaxSize(3){
}
void setLocalMaxWindowsize(int nonMaxSize){
this->nonMaxSize = nonMaxSize;
};
void detect(const cv::Mat& image){
cv::cornerHarris(image, cornerStrength,
neighborhood,
aperture,
k);
cv::minMaxLoc(cornerStrength,0,&maxStrength);
cv::Mat dilated;
cv::dilate(cornerStrength,dilated, cv::Mat());
cv::compare(cornerStrength,dilated,localMax,cv::CMP_EQ);
}
cv::Mat getCornerMap(double qualityLevel){
cv::Mat cornerMap;
threshold = qualityLevel * maxStrength;
cv::threshold(cornerStrength, cornerTh, threshold,255, cv::THRESH_BINARY);
cornerTh.convertTo(cornerMap, CV_8U);
cv::bitwise_and(cornerMap,localMax,cornerMap);
return cornerMap;
}
void getCorners(std::vector<cv::Point> &points,
const cv::Mat& cornerMap){
for (int y = 0; y < cornerMap.rows; y++){
const uchar* rowPty = cornerMap.ptr<uchar>(y);
for (int x = 0; x < cornerMap.cols; x++){
if (rowPty[x]){
points.push_back(cv::Point(x, y));
}
}
}
}
void getCorners(std::vector<cv::Point> &points, double qualityLevel){
cv::Mat cornerMap = getCornerMap(qualityLevel);
getCorners(points, cornerMap);
}
void drawOnImage(cv::Mat &image,
const std::vector<cv::Point> &points,
cv::Scalar color = cv::Scalar(255, 255, 255),
int radius = 3, int thickness = 1){
std::vector<cv::Point>::const_iterator it = points.begin();
while(it != points.end()){
cv::circle(image, *it, radius, color, thickness);
++it;
}
}
};
int main(int argc, char** argv) {
if(argc != 2)
{
std::cerr << "don't get the image" << std::endl;
return -1;
}
cv::Mat image = cv::imread(argv[1],cv::IMREAD_GRAYSCALE);
if(image.empty())
{
std::cout << "don't get the data of image" << std::endl;
return -1;
}
cv::imshow("Original", image);
HarrisDetector harris;
harris.detect(image);
std::vector<cv::Point> pts;
harris.getCorners(pts, 0.02);
harris.drawOnImage(image, pts);
cv::imshow("Corners", image);
cv::waitKey(0);
return 0;
}