自定义角点检测器

自定义角点检测器是基于Harris和Shi-Tomasi角点检测的

首先通过计算矩阵M来得出λ1λ2两个特征值,然后根据他们得到角点响应值

然后自己设置阈值实现实现计算出阈值得到有效响应值的角点位置

 

API

cv::cornerEigenValsAndVecs

(

InputArray src,

OutputArray dst,

int blocksize,

int ksize,

int borderType=BORDER_DEFAULT

)

 

cv::cornerMinEigenVal

(

InputArray src,

OutputArray dst,

int blocksize,

int ksize=3,

int borderType=BORDER_DEFAULT

)

 

自定义CustomHarris角点检测Demo

#include"pch.h"
#include<iostream>
#include<opencv2/opencv.hpp>
#include<math.h>
using namespace std;
using namespace cv;


const char* output_title = "Custom Harris CornerDetection Reslut";
double harris_mins_rsp;
double harris_max_rsp;
int qualityLevel = 30;
int max_count = 100;
Mat src, gray_src;
Mat harris_dst, harriRspImg;
void CustomHarris_Demo(int,void*);

int main(int argc, char** argv)
{
    src = imread("1.jpg");
    imshow("input img", src);
    int blocksize = 3;
    int ksize = 3;
    double k = 0.04;
    harriRspImg = Mat::zeros(src.size(), CV_32FC1);
    harris_dst = Mat::zeros(src.size(), CV_32FC(6));
    namedWindow(output_title, CV_WINDOW_AUTOSIZE);
    cvtColor(src, gray_src, COLOR_BGR2GRAY);

    //caculate eigen value计算特征值
    cornerEigenValsAndVecs(gray_src, harris_dst, blocksize, ksize, BORDER_DEFAULT);

    //计算响应
    for(int row=0;row<harris_dst.rows;++row)
        for (int col = 0; col < harris_dst.cols; ++col)
        {
            double lamda1=harris_dst.at<Vec6f>(row, col)[0];
            double lamda2 = harris_dst.at<Vec6f>(row, col)[1];
            harriRspImg.at<float>(row, col) = lamda1 * lamda2 - k * pow((lamda1 + lamda2), 2);//pow求平方


        }
    minMaxLoc(harriRspImg, &harris_mins_rsp, &harris_max_rsp, 0, 0,Mat());
    createTrackbar("Quality value:", output_title, &qualityLevel, max_count, CustomHarris_Demo);
    CustomHarris_Demo(0, 0);
    waitKey();
    return 0;
}

void CustomHarris_Demo(int, void*)
{
    if (qualityLevel < 10)
        qualityLevel = 10;
    Mat resultImg = src.clone();
    float t = harris_mins_rsp + (double(qualityLevel)) / max_count * (harris_max_rsp - harris_mins_rsp);
    for(int row=0;row<src.rows;++row)
        for (int col = 0; col < src.cols; ++col)
        {
            float v = harriRspImg.at<float>(row, col);
            if (v > t)
                circle(resultImg, Point(col, row), 2, Scalar(0, 0, 255), 2, 8, 0);
        }
    imshow(output_title, resultImg);
}

 

 

自定义CustomShi-Tomasi角点检测Demo

#include"pch.h"
#include<iostream>
#include<opencv2/opencv.hpp>
#include<math.h>
using namespace std;
using namespace cv;


const char* output_title = "Custom Shi-Tomasi CornerDetection Reslut";
double harris_mins_rsp;
double harris_max_rsp;
int qualityLevel = 30;
int max_count = 100;
Mat src, gray_src;
Mat harris_dst, harriRspImg;
//Shi-Tomasi
Mat ShiTomasiRspImg;
double ShiTomasi_max_rsp;
double ShiTomasi_min_rsp;
int SM_QualityLevel = 30;

void CustomShiTomasi_Demo(int,void*);

int main(int argc, char** argv)
{
    src = imread("1.jpg");
    imshow("input img", src);
    int blocksize = 3;
    int ksize = 3;
    double k = 0.04;
    harriRspImg = Mat::zeros(src.size(), CV_32FC1);
    harris_dst = Mat::zeros(src.size(), CV_32FC(6));
    namedWindow(output_title, CV_WINDOW_AUTOSIZE);
    cvtColor(src, gray_src, COLOR_BGR2GRAY);

    //caculate eigen value计算特征值
    cornerEigenValsAndVecs(gray_src, harris_dst, blocksize, ksize, BORDER_DEFAULT);

    //计算响应
    for(int row=0;row<harris_dst.rows;++row)
        for (int col = 0; col < harris_dst.cols; ++col)
        {
            double lamda1 = harris_dst.at<Vec6f>(row, col)[0];
            double lamda2 = harris_dst.at<Vec6f>(row, col)[1];
            harriRspImg.at<float>(row, col) = lamda1 * lamda2 - k * pow((lamda1 + lamda2), 2);//pow求平方


        }
    minMaxLoc(harriRspImg, &harris_mins_rsp, &harris_max_rsp, 0, 0,Mat());
    //createTrackbar("Quality value:", output_title, &qualityLevel, max_count, CustomHarris_Demo);
    //CustomHarris_Demo(0, 0);

    //计算最小特征值
    ShiTomasiRspImg = Mat::zeros(src.size(), CV_32FC1);
    cornerMinEigenVal(gray_src, ShiTomasiRspImg, blocksize, ksize, 4);
    minMaxLoc(ShiTomasiRspImg, &ShiTomasi_min_rsp, &ShiTomasi_max_rsp, 0, 0, Mat());
    createTrackbar("Min Value:", output_title, &SM_QualityLevel, max_count, CustomShiTomasi_Demo);
    CustomShiTomasi_Demo(0, 0);

    waitKey();
    return 0;
}

void CustomShiTomasi_Demo(int, void*)
{
    if (qualityLevel < 20)
        qualityLevel = 20;
    Mat resultImg = src.clone();
    float t = ShiTomasi_min_rsp + ((double(SM_QualityLevel)) / max_count) * (ShiTomasi_max_rsp - ShiTomasi_min_rsp);
    
    for(int row=0;row<src.rows;++row)
        for (int col = 0; col < src.cols; ++col)
        {
            float v = ShiTomasiRspImg.at<float>(row, col);
            if (v > t)
                circle(resultImg, Point(col, row), 2, Scalar(0, 0, 255), 2, 8, 0);
        }
    imshow(output_title, resultImg);
}

 

posted @ 2020-08-18 22:13  Wangtn  阅读(283)  评论(0编辑  收藏  举报