opencv代碼實現(xiàn)
harris類
#ifndef HARRIS_H
#define HARRIS_H
#include “opencv2/opencv.hpp”
class harris
{
private:
cv::Mat cornerStrength; //opencv harris函數(shù)檢測結(jié)果,也就是每個像素的角點響應(yīng)函數(shù)值
cv::Mat cornerTh; //cornerStrength閾值化的結(jié)果
cv::Mat localMax; //局部最大值結(jié)果
int neighbourhood; //鄰域窗口大小
int aperture;//sobel邊緣檢測窗口大?。╯obel獲取各像素點x,y方向的灰度導(dǎo)數(shù))
double k;
double maxStrength;//角點響應(yīng)函數(shù)最大值
double threshold;//閾值除去響應(yīng)小的值
int nonMaxSize;//這里采用默認的3,就是最大值抑制的鄰域窗口大小
cv::Mat kernel;//最大值抑制的核,這里也就是膨脹用到的核
public:
harris():neighbourhood(3),aperture(3),k(0.01),maxStrength(0.0),threshold(0.01),nonMaxSize(3){
};
void setLocalMaxWindowsize(int nonMaxSize){
this-》nonMaxSize = nonMaxSize;
};
//計算角點響應(yīng)函數(shù)以及非最大值抑制
void detect(const cv::Mat &image){
//opencv自帶的角點響應(yīng)函數(shù)計算函數(shù)
cv::cornerHarris (image,cornerStrength,neighbourhood,aperture,k);
double minStrength;
//計算最大最小響應(yīng)值
cv::minMaxLoc (cornerStrength,&minStrength,&maxStrength);
cv::Mat dilated;
//默認3*3核膨脹,膨脹之后,除了局部最大值點和原來相同,其它非局部最大值點被
//3*3鄰域內(nèi)的最大值點取代
cv::dilate (cornerStrength,dilated,cv::Mat());
//與原圖相比,只剩下和原圖值相同的點,這些點都是局部最大值點,保存到localMax
cv::compare(cornerStrength,dilated,localMax,cv::CMP_EQ);
}
//獲取角點圖
cv::Mat getCornerMap(double qualityLevel) {
cv::Mat cornerMap;
// 根據(jù)角點響應(yīng)最大值計算閾值
threshold= qualityLevel*maxStrength;
cv::threshold(cornerStrength,cornerTh,
threshold,255,cv::THRESH_BINARY);
// 轉(zhuǎn)為8-bit圖
cornerTh.convertTo(cornerMap,CV_8U);
// 和局部最大值圖與,剩下角點局部最大值圖,即:完成非最大值抑制
cv::bitwise_and(cornerMap,localMax,cornerMap);
return cornerMap;
}
void getCorners(std::vector《cv::Point》 &points,
double qualityLevel) {
//獲取角點圖
cv::Mat cornerMap= getCornerMap(qualityLevel);
// 獲取角點
getCorners(points, cornerMap);
}
// 遍歷全圖,獲得角點
void getCorners(std::vector《cv::Point》 &points,
const cv::Mat& cornerMap) {
for( int y = 0; y 《 cornerMap.rows; y++ ) {
const uchar* rowPtr = cornerMap.ptr《uchar》(y);
for( int x = 0; x 《 cornerMap.cols; x++ ) {
// 非零點就是角點
if (rowPtr[x]) {
points.push_back(cv::Point(x,y));
}
}
}
}
//用圈圈標記角點
void drawOnImage(cv::Mat &image,
const std::vector《cv::Point》 &points,
cv::Scalar color= cv::Scalar(255,255,255),
int radius=3, int thickness=2) {
std::vector《cv::Point》::const_iterator it=points.begin();
while (it!=points.end()) {
// 角點處畫圈
cv::circle(image,*it,radius,color,thickness);
++it;
}
}
};
#endif // HARRIS_H
相關(guān)測試代碼:
cv::Mat image, image1 = cv::imread (“test.jpg”);
//灰度變換
cv::cvtColor (image1,image,CV_BGR2GRAY);
// 經(jīng)典的harris角點方法
harris Harris;
// 計算角點
Harris.detect(image);
//獲得角點
std::vector《cv::Point》 pts;
Harris.getCorners(pts,0.01);
// 標記角點
Harris.drawOnImage(image,pts);
cv::namedWindow (“harris”);
cv::imshow (“harris”,image);
cv::waitKey (0);
return 0;
相關(guān)測試結(jié)果:
評論
查看更多