OpenCV图像特征提取学习二,Shi-Tomasi 角点检测算法

一.Shi-Tomasi 角点检测算法

Harris角点检测基本数学公式如下: 

                            E\left ( u,v \right ) = \sum_{x,y}^{}w\left ( x,y \right )\left [ I\left ( x+u,y+v \right )-I\left ( x,y \right ) \right ]^{2}

泰勒公式进行展开后,近似为:

                            E \approx \left [ u,v \right ]\sum w\left ( u,v \right )\left [ \binom{I_{x}^{2},I_{x}I_{y}}{I_{x}I_{y},I_{y}^{2}} \right ]\binom{u}{v}

对于局部微小的移动量\left [ u,v \right ],可以近似得到下面的表达:

                             E \approx \left [ u,v \right ]M\begin{bmatrix} u\\ v\end{bmatrix}

其中M为2*2的矩阵,可由图像的导数求得:

                             M = \sum_{x,y}^{}w\left ( u,v \right )\begin{bmatrix} I_{x}^{2}&I_{x}I_{y}\\ I_{x}I_{y}&I_{y}^{2}\end{bmatrix}

矩阵M,将其对角化之后 ,特征值λ1, λ2 分别代表了X 和Y 方向的灰度变化率.

                             M = \sum_{x,y}^{}w\left ( u,v \right )\begin{bmatrix} I_{x}^{2}&I_{x}I_{y}\\ I_{x}I_{y}&I_{y}^{2}\end{bmatrix} = \begin{bmatrix} \lambda _{1}&0\\ 0&\lambda _{2}\end{bmatrix}

E\left ( u,v \right )的椭圆形式如下:

                              

Harris角点检测算法的角点响应函数为:

                                 R = \lambda _{1}\lambda _{2}-K\left ( \lambda _{1}+\lambda _{2} \right )^{2}

Harris角点检测算法就是对角点响应函数R进行阈值处理:R > threshold,即提取R的局部极大值。shi-Tomasi 算法是基于Harris 算法进行的改进,Harris算法最基础的数学定义是将矩阵 M 的行列式值与矩阵 M 的迹相减,再将差值与预先给定的阈值进行比较。若两个特征值中较小的一个大于最小阈值,则会得到强角点,这就是Shi-Tomasi角点检测算法。

Shi-Tomasi角点检测算法的角点响应函数为:

                                 R =min \left ( \lambda _{1},\lambda _{2} \right )

Shi-tomasi角点检测 和Harris 算法一样,如果该分数大于设定的阈值,我们就认为它是一个角点。可以看出来只有当 λ1 和 λ 2 都大于最小值时,才被认为是角点,即下图中的紫色区域。

--------------------------------------------------------------------------------------------------------------------------------

二.Shi-Tomasi角点检测API函数接口

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 );

参数说明:

第一个参数image:输入图像,8位或浮点32比特,单通道图像;
第二个参数corners:输出参数,检测到的角点;表示返回角点的数目,如果检测出来角点数目大于最大数目则返回响应值最强前规定数目;
第三个参数corner_count:输出参数,检测到的角点数目;
第四个参数quality_level:最大最小特征值的乘法因子。定义可接受图像角点的最小质量因子;
第五个参数min_distance:限制因子。得到的角点的最小距离;使用 Euclidian 距离;
第六个参数mask:ROI感兴趣区域。函数在ROI中计算角点;如果 mask 为 NULL,则选择整个图像;
第七个参数block_size: 是计算导数的自相关矩阵时指定点的领域,采用小窗口计算的结果比单点 (也就是block_size为1)计算的结果要好;
第八个参数useHarrisDetector:当use_harris的值为非0,则函数使用Harris的角点定义;若为 0,则使用Shi-Tomasi的定义;
第九个参数K:用于设置Hessian自相关矩阵即对Hessian行列式的相对权重的权重系数;

---------------------------------------------------------------------------------------------------------------------------------

代码实现

#include"stdafx.h"
#include <opencv2/opencv.hpp>
#include <iostream>

#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>

using namespace cv;
using namespace std;

#define WIN_NAME "Shi-Tomasi角点检测"

Mat srcImage, grayImage;
int maxCornerNumber = 33;
int maxTrackbarNumber = 500;
RNG rng(12345);

void on_GoodFeatureToTrack(int, void *)
{
	if (maxCornerNumber <= 1)
	{
		maxCornerNumber = 1;
	}
	//Shi-Tomasi参数准备
	vector<Point2f> corners;
	double qualityLevel = 0.01; //角点检测可以接受的最小特征值
	double minDistance = 10; //角点间的最小像素距离设置
	int blockSize = 3;  //计算导数自相关矩阵时指定的领域范围
	double k = 0.04;   //权重系数

	Mat copy = srcImage.clone(); //复制原图到一个临时变量中,作为感兴趣区域
								 //Shi-Tomasi Test
	goodFeaturesToTrack(grayImage, corners, maxCornerNumber, qualityLevel, minDistance, Mat(), blockSize, false, k);

	//输出文字信息
	cout << ">此次检测到的角点数量为: " << corners.size() << endl;

	//绘制检测到的角点
	for (unsigned int i = 0; i < corners.size(); i++)
	{
		circle(copy, corners[i], 5, Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)), -1, 8, 0);
	}

	imshow(WIN_NAME, copy);
}

int main(int argc, char** argv)
{
	srcImage = imread("F:/photo/lj.jpg");
	cvtColor(srcImage, grayImage, COLOR_BGR2GRAY);

	namedWindow(WIN_NAME, WINDOW_AUTOSIZE);

	createTrackbar("最大角点数:", WIN_NAME, &maxCornerNumber, maxTrackbarNumber, on_GoodFeatureToTrack);

	//imshow(WIN_NAME, srcImage);


	on_GoodFeatureToTrack(0, 0);


	waitKey(0);
	return 0;
}

-------------------------------------------------------------------------------------------------------------------------------- 

图像处理效果

猜你喜欢

转载自blog.csdn.net/weixin_44651073/article/details/126475441