Harris角点

可参考:http://www.cnblogs.com/ronny/p/4009425.html

           http://www.cnblogs.com/ztfei/archive/2012/05/07/2487123.html

          http://blog.csdn.net/crzy_sparrow/article/details/7391511

          矩阵M(x)的特征值能表示在水平和竖直方向的变化程度,但Harris给出的角点差别方法并不需要计算具体的特征值,而是计算一个

角点响应值R来判断。

         alpha的值对角点检测的影响:增大α的值,将减小角点响应值R,降低角点检测的灵性,减少被检测角点的数量;减小α值,将增大角点响应值R,增加角点检测的灵敏性,增加被检测角点的数量。

         关于尺度不变性:

      

        下面是代码,我加了部分注释

#include "opencv2/core/core.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/nonfree/nonfree.hpp"
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;




/*void drawCornerOnImage(Mat& image, const Mat&binary)
{
    Mat_<uchar>::const_iterator it = binary.begin<uchar>();
    Mat_<uchar>::const_iterator itd = binary.end<uchar>();
    for (int i = 0; it != itd; it++, i++)
    {
        //Point内时什么意思?
        if (*it)
            circle(image, Point(i%image.cols, i / image.cols), 3, Scalar(0, 255, 0), 1);
        
    }
}
*/
/******************下面是Harris角点检测的C++实现*******************************/
/*
void detectHarrisCorners(const Mat& imgSrc,Mat& imgDst,double alpha )
{
    Mat gray;
    if (imgSrc.channels() == 3)
        cvtColor(imgSrc, gray, CV_BGR2GRAY);
    else
        gray = imgSrc.clone();
    gray.convertTo(gray, CV_64F);//第二个参数depth
    Mat xKernel = (Mat_<double>(1, 3) << -1, 0, 1);//模板一行三列,后面为相应的值
    Mat yKernel = xKernel.t();

    Mat Ix, Iy;
    //Convolves an image with the kernel.
    filter2D(gray, Ix, CV_64F, xKernel);
    filter2D(gray, Iy, CV_64F, yKernel);

    Mat Ix2, Iy2, Ixy;//计算图像两个梯度方向的乘积
    Ix2 = Ix.mul(Ix);
    Iy2 = Iy.mul(Iy);
    Ixy = Ix.mul(Iy);

    Mat gaussKernel = getGaussianKernel(7, 1);
    filter2D(Ix2, Ix2, CV_64F, gaussKernel);
    filter2D(Iy2, Iy2, CV_64F, gaussKernel);
    filter2D(Ixy, Ixy, CV_64F, gaussKernel);

    Mat cornerStrength(gray.size(), gray.type());

    for (int i = 0; i < gray.rows; i++)
    {
        for (int j = 0; j < gray.cols; j++)
        {
            double det_m = Ix2.at<double>(i, j)*Iy2.at<double>(i, j)-
                Ixy.at<double>(i,j)*Ixy.at<double>(i,j);
            double trace_m = Ix2.at<double>(i, j) + Iy2.at<double>(i, j);

            cornerStrength.at<double>(i,j) = det_m - trace_m;
        }
    }

    //threshold
    double maxStrength;
    minMaxLoc(cornerStrength, NULL, &maxStrength, NULL, NULL);
    Mat dilated, localMax;
    //默认3*3核膨胀,膨胀之后,除了局部最大值点和原来相同,其它非局部最大值点被  
    //3*3邻域内的最大值点取代  
    dilate(cornerStrength, dilated, Mat());
    imshow("dilated", dilated);
    imshow("cornerStrength", cornerStrength);
    //与原图相比,只剩下和原图值相同的点,这些点都是局部最大值点,保存到localMax  
    compare(cornerStrength, dilated, localMax, CMP_EQ);//两图中相同的地方进行比较,相等的地方设为255
    imshow("localMax", localMax);
    Mat cornerMap;
    double qualityLevel = 0.01;
    double thresh = qualityLevel * maxStrength;
    cornerMap = cornerStrength > thresh;
    bitwise_and(cornerMap, localMax, cornerMap);//将两图进行与操作

    imgDst = cornerMap.clone();

}

*/
int main()
{
    

    /******harris角点检测的C++实现********/

    /*
    Mat img = imread("1.jpg");
    imshow("原图", img);
    Mat gray,dst;
    cvtColor(img, gray, CV_BGR2GRAY);
    detectHarrisCorners(img, dst, 0.01);
    imshow("目标", dst);
    drawCornerOnImage(img, dst);
    imshow("处理后", img);*/
    ////*************************下面是用opencv自带的角点检测函数*************************/////////
    /*
    Mat img = imread("1.jpg");
    imshow("原图", img);
    Mat gray;
    cvtColor(img, gray, CV_BGR2GRAY);

    Mat cornerStrenth;
    cornerHarris(gray, cornerStrenth, 3, 3, 0.1);
    //imshow("cornerstrenth", cornerStrenth);
    threshold(cornerStrenth, cornerStrenth, 0.001, 255, THRESH_BINARY);
    //imshow("cornerstrenth", cornerStrenth);
    double maxStrength, minStrength;
    minMaxLoc(cornerStrenth, &minStrength, &maxStrength);

    Mat dilated;
    Mat locaMax;

    // // 膨胀图像,找出图像中全部的局部最大值点
    dilate(cornerStrenth, dilated, Mat());
    //imshow("dilated", dilated);
    // compare是一个逻辑比较函数,返回两幅图像中对应点相同的二值图像
    compare(cornerStrenth, dilated, locaMax, CMP_EQ);
    //imshow("locaMax", locaMax);
    Mat cornerMap;
    double qualityLevel = 0.01;
    double th = qualityLevel*maxStrength; // 阈值计算
    threshold(cornerStrenth, cornerMap, th, 255, THRESH_BINARY);
    //imshow("cornerMap", cornerMap);
    // 转为8-bit图
    cornerMap.convertTo(cornerMap, CV_8U);
    //imshow("cornerMap1", cornerMap);
    // 逐点的位运算
    // 和局部最大值图与,剩下角点局部最大值图,即:完成非最大值抑制
    bitwise_and(cornerMap, locaMax, cornerMap);
    //imshow("cornerMap2", cornerMap);
    drawCornerOnImage(img, cornerMap);
    namedWindow("result");
    imshow("result", img);
    //imshow("角点", cornerStrenth);
    waitKey(0);
    return 0;
    */
    waitKey(0);
    return 0;
}
View Code

       

原文地址:https://www.cnblogs.com/573177885qq/p/4731808.html