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