opencv 特征点检测(一)角点检测, harris角点,shi-Tomasi角点,亚像素角点提取

本章内容:


1. harris角点检测
2. shi-Tomasi角点检测

3. 亚像素角点提取

 

1.Harris 角点检测

opencv 特征点检测(一)角点检测, harris角点,shi-Tomasi角点,亚像素角点提取

输出结果:

opencv 特征点检测(一)角点检测, harris角点,shi-Tomasi角点,亚像素角点提取

边缘检测后角点检测

opencv 特征点检测(一)角点检测, harris角点,shi-Tomasi角点,亚像素角点提取

输出结果

opencv 特征点检测(一)角点检测, harris角点,shi-Tomasi角点,亚像素角点提取

2. STH-Tomas角点检测

opencv 特征点检测(一)角点检测, harris角点,shi-Tomasi角点,亚像素角点提取

输出结果

opencv 特征点检测(一)角点检测, harris角点,shi-Tomasi角点,亚像素角点提取

3.亚像素角点

opencv 特征点检测(一)角点检测, harris角点,shi-Tomasi角点,亚像素角点提取

输出结果

opencv 特征点检测(一)角点检测, harris角点,shi-Tomasi角点,亚像素角点提取

源码

#include <ostream>
#include <opencv.hpp>
#include <math.h>

int main(int argc, char *argv[])
{
    /*
     本章内容:
        1. harris角点检测
        2. shi-Tomasi角点检测
        3. 亚像素角点提取

    */
    cv::String fileName = "/home/wang/dev/Image/board.png";
//    cv::String fileName = "/home/wang/dev/Image/c10.tif";
    cv::Mat src = cv::imread(fileName);
//    cv::Mat src1 = cv::imread(fileName1);
    cv::Mat src1;
    cv::Mat src2;
    src1 = src.clone();
    src2 = src.clone();
    if(src.data == NULL){
        printf("图像读入失败\n");
        return -1;
    }
    cv::imshow("src",src);

 

    /*
     * api接口:CV_EXPORTS_W void cornerHarris( InputArray src, OutputArray dst, int blockSize,
                                int ksize, double k,
                                int borderType = BORDER_DEFAULT );
       参数分析
     * @param dst 计算得分输出,CV_32FC1类型,与src相同大小
        @param blockSize Neighborhood size (see the details on #cornerEigenValsAndVecs ).
        @param ksize  Sobel核
        @param k  一般取0.04~0.06;
    */
    cv::Mat gray;
    cv::cvtColor(src,gray,cv::COLOR_BGR2GRAY);
    cv::Mat dstHarris;
    cv::cornerHarris(gray,dstHarris,3,5,0.04);
    cv::normalize(dstHarris,dstHarris,0, 1, cv::NORM_MINMAX);
    cv::imshow("Harris Score",dstHarris);

    // 标记角点
    double threVal = 0.5;
    for(int i=0;i <dstHarris.rows;i++){
        for(int j=0; j<dstHarris.cols; j++){
            if(dstHarris.at<float>(i,j) > threVal){
                cv::circle(src,cv::Point(j,i),2,cv::Scalar(0,0,255),4);
            }
        }
    }
    cv::imshow("gray", gray);
    cv::imshow("src marker", src);

    // 提取变换后角点检测
    cv::Mat dstCanny;
    cv::Canny(gray,dstCanny,50,150);
    cv::Mat CaHarris;
    cv::cornerHarris(dstCanny,CaHarris,3,3,0.04);
    cv::imshow("dstCanny",dstCanny);
    cv::normalize(CaHarris,CaHarris,0, 1, cv::NORM_MINMAX);
    cv::Mat normScaleDst;

    double minVal,maxVal;
    cv::minMaxIdx(normScaleDst,&minVal,&maxVal);
    for(int i=0;i <CaHarris.rows;i++){
        for(int j=0; j<CaHarris.cols; j++){
            if(CaHarris.at<float>(i,j) > maxVal*0.7){
                cv::circle(src1,cv::Point(j,i),2,cv::Scalar(0,0,255),4);
            }
        }
    }
    std::cout << "maxval:" << maxVal << std::endl;
    cv::imshow("src1",src1);

    // Thi-Tomas角点检测
    /*
    api接口: CV_EXPORTS_W void goodFeaturesToTrack( InputArray image, OutputArray corners,
                                         int maxCorners, double qualityLevel, double minDistance,
                                         InputArray mask = noArray(), int blockSize = 3,
                                         bool useHarrisDetector = false, double k = 0.04 );
        参数分析
            @param corners : vector<Point2f>
            @param maxCorners 最大角点数目
            @param qualityLevel 角点强度阈值系数,建议为最大值的0.01倍。
            @param minDistance  角点之间的最小距离
    */
    std::vector<cv::Point2f> corners;
    cv::goodFeaturesToTrack(gray,corners,100,0.01,10);
    for(int i=0; i < corners.size();i++){
        cv::circle(src2,corners[i],1,cv::Scalar(0,0,255),4);
    }
    cv::imshow("src2 Thi-Tomas",src2);

    /*3.亚像素角点
     * apie接口: CV_EXPORTS_W void cornerSubPix( InputArray image, InputOutputArray corners,
                                Size winSize, Size zeroZone,
                                TermCriteria criteria );
        参数分析:
        corners: 输入输出类型,需要提供初始角点
        winSize: 亚像素拟合大小
        zeroZone: 避免出现奇异问题,(-1,-1)
        TermCriteria criteria: 迭代终止条件,支持迭代次数或者迭代精度

    */
    // 构造方式: TermCriteria(int type, int maxCount, double epsilon);
    cv::TermCriteria tc(cv::TermCriteria::EPS + cv::TermCriteria::MAX_ITER, 50,0.01);
    cv::cornerSubPix(gray,corners,cv::Size(5,5),cv::Size(-1,-1),tc);
    std::cout << "亚像素角点"<< corners << std::endl;

    cv::waitKey(0);
    return 1;
}