openCV特征检测与提取(三)-- 自定义角点检测器

在这里插入图片描述

之前的角点检测器主要都是通过固定方法的API来实现的,而我们也可以用不同角点检测方法的原理和需求去制作角点检测的函数

相关函数的介绍

在这里插入图片描述

1.cornerEigenValsAndVecs()函数

该函数用来求解输入图像矩阵的特征向量和特征值
主要用来模拟Harris角点检测

2.cornMinEigenVal()函数

与第一个函数相似,但是它只计算相关矩阵的最小特征值,主要用来模拟Shi-Tomasi角点检测

3.minMaxLoc()函数

寻找输入矩阵中的最小值和最大值,并可以获得对应点的位置

代码:

	#include<opencv2/opencv.hpp>
#include<math.h>
#include<iostream>

using namespace cv;
using namespace std;


const char* harris_win = "Custion Harris Corners Detector";
const char* shitomasi_win = "Custon Shi-Tomasi Corners Detector";
int qualityLevel = 30;
int max_count = 100;
int sm_qualityLevel = 30;
int sm_max_count = 100;
double harris_min_rsp;
double harris_max_rsp;
Mat harris_dst, harrisRspImg;
Mat shiTomasiRsp;
double shitomasi_min_rsp;
double shitomasi_max_rsp;
void CustomHarris_Demo(int, void*);
void CustomShiTomasi_Demo(int, void*);
Mat src, gray_src;

void Tomasi_Demo(int, void*);
int main(int argc, char** argv) {
	src = imread("C:/Users/18929/Desktop/博客项目/项目图片/18.jpg");
	if (src.empty()) {
		printf("could not load image");
		return -1;
	}
	imshow("input_img", src);

	namedWindow(output_title, CV_WINDOW_AUTOSIZE);

	//首先转换为灰度图像
	cvtColor(src, gray_src, COLOR_BGR2GRAY);

	//计算特征值
	int blockSize = 3;
	int ksize = 3;
	double k = 0.04;
	harris_dst = Mat::zeros(src.size(), CV_32FC(6));//CV_32FC(6)--float数据类型图片
	harrisRspImg = Mat::zeros(src.size(), CV_32FC1);
	//计算图像的特征值和特征向量用于计算--输出为double型数据
	cornerEigenValsAndVecs(gray_src, harris_dst, blockSize, ksiaze, 4);

	//计算响应值
	//harris形式
	for (int row = 0; row < harris_dst.rows; row++)
	{
		for (int col = 0; col < harris_dst.cols; col++) {
			//0,1分别为两个特征值
			double lambda1 = harris_dst.at<Vec6f>(row, col)[0];
			double lambda2 = harris_dst.at<Vec6f>(row, col)[1];
			//Harris : M = lambda1*lambda2 - k(lambda1+lambda2)^2
			harrisRspImg.at<float>(row, col) = lambda1 * lambda2 - k * pow((lambda1 + lambda2), 2);

		}
	}
	//找出全局最小值和最大值备用
	minMaxLoc(harrisRspImg, &harris_min_rsp, &harris_max_rsp, 0, 0, Mat());
	createTrackbar("Threshold:", harris_win, &qualityLevel, max_count, CustomHarris_Demo);
	CustomHarris_Demo(0,0);

	//shi-Tomasi
	//计算最小特征值
	Mat shiTomasiRsp = Mat::zeros(src.size(), CV_32FC1);
	cornerMinEigenVal(gray_src, shiTomasiRsp, blocksize, ksize, 4);
	minMaxLoc(shiTomasiRsp, &shitomasi_min_rsp, &shitomasi_max_rsp, 0, 0, Mat());
	namedWindow(shitomasi_win, CV_WINDOW_AUTOSIZE);
	createTrackbar("Quality:", shitomasi_win, &sm_qualityLevel, sm_max_count, CustomShiTomasi_Demo);
	CustomShiTomasi_Demo(0, 0);

	waitKey(0);
	return 0;
}

void CustomHarris_Demo(int, char*) {
	if (qualityLevel<10)
	{
		qualityLevel = 10;
	}
	Mat resultImg = src.clone();
	//定义最小阈值
	float t = harris_min_rsp + (((double)qualityLevel) / max_count) * (harris_max_rsp - harris_min_rsp);
	for (int row = 0; row < src.rows; row++)
	{
		for (int col = 0; col < src.cols; col++)
		{
			float v = harrosRspImg.at(row, col);
			//比阈值大的点作为角点并画出来
			if (v>t)
			{
				circle(resultImg, Point(col, row), 2, Scalar(0, 0, 255), 2, 8, 0);
			}
		}

	}
	imshow(harris_win, resultImg);
}

void CustomShiTomasi_Demo(int, char*) {
	if (sm_qualityLevel < 20) {
		sm_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 = shiTomasiRsp.at<float>(row, col);
			if (v > t) {
				circle(resultImg, Point(col, row), 2, Scalar(0, 0, 255), 2, 8, 0);
			}
		}

	}
	imshow(shitomasi_win, resultImg);

}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值