opencv学习笔记(三十四)自定义角点检测

1.步骤

(1)定义好Harris角点检测与Shi-Tomas角点检测需要的变量,存放响应值的矩阵以及滑块响应函数

(2)源图像灰度处理

(3)Harris使用cornerEigenValsAndVecs函数,获取特征值;Shi-Tomas使用cornerMinEigenVal函数获取特征值

(4)公式计算响应值:Harris为: lamda1*lamda2 - k*(lamda1 + lamda2)^2

(5)计算阈值公式:threshold=最小响应值+q*(最大响应值-最小响应值)    (q为0-1之间的小数,可以通过滑块动态控制)

(6)响应值与阈值进行比较,比阈值大的判定为角点,用circle作出来

2.相关API

(1)cv::cornerEigenValsAndVecs(InputArray src,OutputArray dst,int blocksize,int ksize,int borderType=BORDER_DEFAULT)

src:源图像

dst:输出矩阵,存放(λ1, λ2, x1, y1, x2, y2),2个特征值与特征向量,所以必须比输入图像宽 6 倍

blocksize:计算导数微分不同的窗口大小

ksize:移动窗口大小

borderType:边界处理方式

(2)cv::cornerMinEigenVal(InputArray src,OutputArray dst,int blocksize,int ksize,int borderType=BORDER_DEFAULT)

src:源图像

dst:存放最小特征值

blocksize:计算导数微分不同的窗口大小

ksize:移动窗口大小

borderType:边界处理方式

3.代码实现

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

Mat src, dst, graySrc;
//定义窗口
const char* harris_win = "Custom Harris Corners Detector";
const char* shitomasi_win = "Custom shitomasi_win Corners Detector";
//Harris角点检测所需
Mat harris_dst,harrisRspImg; //分别存放特征值和角点响应值
double harris_min_rsp; //分别存放最大最小角点响应值,用于计算合理阈值判断角点
double harris_max_rsp;
void CustomHarris_Demo(int, void*); //call函数
//Shitomasi角点检测所需
Mat shiTomasiRsp;
double shitomasi_max_rsp;
double shitomasi_min_rsp;
void CustomShiTomasi_Demo(int, void*);
//滑块变量
int quality_value = 30;
int quality_max = 120;
int main()
{
	src = imread("D:/VS project/Image/qp.jpg");
	if (src.empty())
	{
		cout << "无法找到图像" << endl;
		return -1;
	}
	namedWindow("inputName", CV_WINDOW_AUTOSIZE);
	imshow("inputName", src);
	cvtColor(src, graySrc, COLOR_BGR2GRAY);
	//自定义Harris角点检测
	int blockSize = 3;
	int ksize = 3;
	double k = 0.04;
	harris_dst = Mat::zeros(src.size(), CV_32FC(6)); //必须比输入图像宽 6 倍,存放(λ1, λ2, x1, y1, x2, y2),2个特征值与特征向量
	harrisRspImg = Mat::zeros(src.size(), CV_32FC1);
	cornerEigenValsAndVecs(graySrc, harris_dst, blockSize, ksize, 4);//检测矩阵对应的特征值
	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];
			harrisRspImg.at<float>(row, col) = lamda1*lamda2 - k*pow((lamda1 + lamda2), 2);
		}
	}
	minMaxLoc(harrisRspImg, &harris_min_rsp, &harris_max_rsp, 0, 0, Mat());//取出响应值最大最小值
	namedWindow(harris_win, CV_WINDOW_AUTOSIZE);
	createTrackbar("Harris Quatity_level Value:", harris_win, &quality_value, quality_max, CustomHarris_Demo);
	CustomHarris_Demo(0, 0);
	//shiTomas自定义角点检测
	shiTomasiRsp = Mat::zeros(src.size(), CV_32FC1);
	cornerMinEigenVal(graySrc, shiTomasiRsp, blockSize, ksize, 4);
	minMaxLoc(shiTomasiRsp, &shitomasi_min_rsp, &shitomasi_max_rsp, 0, 0, Mat());
	namedWindow(shitomasi_win, CV_WINDOW_AUTOSIZE);
	createTrackbar("ShiTomas Quatity_level Value:", shitomasi_win, &quality_value, quality_max, CustomShiTomasi_Demo);
	CustomShiTomasi_Demo(0, 0);
	waitKey(0);
}
void CustomHarris_Demo(int, void *)
{
	if (quality_value < 10)
	{
		quality_value = 10;
	}
	Mat resultImg = src.clone(); //输出图像克隆下原图
	float harris_threshold= harris_min_rsp + (((double)quality_value) / quality_max)*(harris_max_rsp - harris_min_rsp);//算出阈值
	for (int row = 0; row < src.rows; row++) {
		for (int col = 0; col < src.cols; col++)
		{
			float harris_value = harrisRspImg.at<float>(row, col);
			if (harris_value>harris_threshold) {
				circle(resultImg, Point(col, row), 2, Scalar(0, 0, 255), 2, 8, 0);
			}
		}
	}
	imshow(harris_win, resultImg);
 }

void CustomShiTomasi_Demo(int, void*) {
	if (quality_value < 10)
	{
		quality_value = 10;
	}
	Mat resultImg = src.clone(); //输出图像克隆下原图
	float shiTomas_threshold= shitomasi_min_rsp + (((double)quality_value) / quality_max)*(shitomasi_max_rsp - shitomasi_min_rsp);
	for (int row = 0; row < src.rows; row++) {
		for (int col = 0; col < src.cols; col++) {
			float shiTomas_value = shiTomasiRsp.at<float>(row, col);
			if (shiTomas_value > shiTomas_threshold) {
				circle(resultImg, Point(col, row), 2, Scalar(0, 0, 255), 2, 8, 0);
			}
		}
	}
	imshow(shitomasi_win, resultImg);
}

发布了53 篇原创文章 · 获赞 9 · 访问量 3265

猜你喜欢

转载自blog.csdn.net/weixin_41039168/article/details/99633512