harris

//#include <iostream>
//#include <opencv.hpp>
//#include <string>
//#include "harris.h"

#ifndef HARRIS_H //先测试 预处理器变量HARRIS_H 是否被宏定义过 
#define HARRIS_H // #define HARRIS_H
                 // 程序段 1 //如果HARRIS_H没有被宏定义过,定义HARRIS_H,并编译程序段 1
                 // #endif
                 // 程序段 2 //如果x已经定义过了则编译程序段2的语句,“忽视”程序段 1。
#include "opencv2/opencv.hpp"  
  
class harris //在C++ 语言中class是定义类的关键字,C++中也可以使用struct定义类。
	//两者区别是,用class定义的类,如果数据成员或成员函数没有说明则默认为private(私有)的,而用struct定义的,默认为public(公共)的。 
{  
private:  
    cv::Mat cornerStrength;  //opencv harris函数检测结果,也就是每个像素的角点响应函数值  
    cv::Mat cornerTh; //cornerStrength阈值化的结果  
    cv::Mat localMax; //局部最大值结果  
    int neighbourhood; //邻域窗口大小  
    int aperture;//sobel边缘检测窗口大小(sobel获取各像素点x,y方向的灰度导数)  
    double k;  
    double maxStrength;//角点响应函数最大值  
    double threshold;//阈值除去响应小的值  
    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;  
    };  
  
    //计算角点响应函数以及非最大值抑制  
    void detect(const cv::Mat &image){  //const限定变量&image为不可修改的常量,且默认为文件的局部变量
            //opencv自带的角点响应函数计算函数  
            cv::cornerHarris (image,cornerStrength,neighbourhood,aperture,k);  
            double minStrength;  
            //计算最大最小响应值  
            cv::minMaxLoc (cornerStrength,&minStrength,&maxStrength);  
  
            cv::Mat dilated;  
            //默认3*3核膨胀,膨胀之后,除了局部最大值点和原来相同,其它非局部最大值点被  
            //3*3邻域内的最大值点取代  
            cv::dilate (cornerStrength,dilated,cv::Mat());  
            //与原图相比,只剩下和原图值相同的点,这些点都是局部最大值点,保存到localMax  
            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);  
            // 转为8-bit图  
            cornerTh.convertTo(cornerMap,CV_8U);  
            // 和局部最大值图与,剩下角点局部最大值图,即:完成非最大值抑制  
            cv::bitwise_and(cornerMap,localMax,cornerMap);  
            return cornerMap;  
    }  
  
    void getCorners(std::vector<cv::Point> &points, //表示空类型,它跟int,float是同地位的,一般用在没有返回值的函数中,比如你写void main (),主函数完了不用写return 语句,但是如果是int main ()或者是main (),你不写return 语句它就会有warning 
            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);  //const定义为常量
                    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 

测试文件

int main()
{
   cv::Mat  image, image1 = cv::imread ("D:/13.jpg");  
   //灰度变换  
   cv::cvtColor (image1,image,CV_BGR2GRAY);  
  
  
   // 经典的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;  

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值