1. 程式人生 > 實用技巧 >自定義角點檢測器

自定義角點檢測器

自定義角點檢測器是基於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);
}