图像处理之Shi-Tomasi角点检测

174 阅读4分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 5 天

1 Shi-Tomasi 角点检测概述

除了利用Harris进行角点检测之外,我们通常还可以利用Shi—Tomasi方法进行角点检测。Shi—Tomasi算法是Harris算法的改进,此算法最原始的定义是将矩阵M的行列式值与M的迹相减,再将差值同预先给定的阈值进行比较。后来Shi和Tomasi提出改进了方法,若两个特征值中较小的一个大于最小阈值,则会得到强角点。

由于Shi-Tomasi算子是1994年在文章《Good Features to Track》中被提出的, OpenCV 实现此算法的函数名便定义为 goodFeaturesToTrack。下面我们来看看此 函数的用法。

2 确定图像强角点:goodFeaturesToTrack()函数

goodFeaturesToTrack()函数结合了 Shi-Tomasi 算子,用于确定图像的强角点。

C++:

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)

  • 第一个参数,InputArray 类型的image,输入图像,须为8位或浮点型32位单通道图像。
  • 第二个参数,OutputArray类型的corners,检测到的角点的输出向量。
  • 第三个参数,int类型的maxCorners,角点的最大数量。
  • 第四个参数,double类型的qualityLevel,角点检测可接受的最小特征值。其实实际用于过滤角点的最小特征值是 qualityLevel 与图像中最大特征值的乘积。所以qualityLevel 通常不会超过1(常用的值为0.10或者0.01)。而检测完所有的角点后,还要进一步剔除掉一些距离较近的角点。
  • 第五个参数,double类型的minDistance,角点之间的最小距离,此参数用于保证返回的角点之间的距离不小于minDistance个像素。
  • 第六个参数,InputArray 类型的mask,可选参数,表示感兴趣区域,有默认值noArray()。若此参数非空(需为CV_8UC1类型,且和第一个参数image有相同的尺寸),便用于指定角点检测区域。
  • 第七个参数,int类型的blockSize,有默认值3,是计算导数自相关矩阵时指定的邻域范围。
  • 第八个参数,bool 类型的useHarrisDetector,默认值 false,指示是否使用 Harris角点检测。
  • 第九个参数,double类型的k,有默认值0.04,为用于设置Hessian自相关矩阵行列式的相对权重的权重系数。

另外值得一提的是,goodFeaturesToTrack 函数可用来初始化一个基于点的对象跟踪操作。

3 综合示例:Shi-Tomasi角点检测

源码:

//---------------------------------【头文件、命名空间包含部分】----------------------------
//		描述:包含程序所使用的头文件和命名空间
//---------------------------------------------------------------------------------------
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
using namespace cv;
using namespace std;

//-----------------------------------【宏定义部分】-------------------------------------------- 
//  描述:定义一些辅助宏 
//-------------------------------------------------------------------------------------------
#define WINDOW_NAME "【Shi-Tomasi角点检测】"        //为窗口标题定义的宏 



//-----------------------------------【全局变量声明部分】--------------------------------------
//          描述:全局变量声明
//-------------------------------------------------------------------------------------------
Mat g_srcImage, g_grayImage;
int g_maxCornerNumber = 33;
int g_maxTrackbarNumber = 500;
RNG g_rng(12345);//初始化随机数生成器


//-----------------------------【on_GoodFeaturesToTrack( )函数】----------------------------
//          描述:响应滑动条移动消息的回调函数
//-----------------------------------------------------------------------------------------
void on_GoodFeaturesToTrack( int, void* )
{
	//【1】对变量小于等于1时的处理
	if( g_maxCornerNumber <= 1 ) { g_maxCornerNumber = 1; }

	//【2】Shi-Tomasi算法(goodFeaturesToTrack函数)的参数准备
	vector<Point2f> corners;
	double qualityLevel = 0.01;//角点检测可接受的最小特征值
	double minDistance = 10;//角点之间的最小距离
	int blockSize = 3;//计算导数自相关矩阵时指定的邻域范围
	double k = 0.04;//权重系数
	Mat copy = g_srcImage.clone();	//复制源图像到一个临时变量中,作为感兴趣区域

	//【3】进行Shi-Tomasi角点检测
	goodFeaturesToTrack( g_grayImage,//输入图像
		corners,//检测到的角点的输出向量
		g_maxCornerNumber,//角点的最大数量
		qualityLevel,//角点检测可接受的最小特征值
		minDistance,//角点之间的最小距离
		Mat(),//感兴趣区域
		blockSize,//计算导数自相关矩阵时指定的邻域范围
		false,//不使用Harris角点检测
		k );//权重系数


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

	//【5】绘制检测到的角点
	int r = 4;
	for( int i = 0; i < corners.size(); i++ )
	{ 
		//以随机的颜色绘制出角点
		circle( copy, corners[i], r, Scalar(g_rng.uniform(0,255), g_rng.uniform(0,255),
			g_rng.uniform(0,255)), -1, 8, 0 ); 
	}

	//【6】显示(更新)窗口
	imshow( WINDOW_NAME, copy );
}

//--------------------------------------【main( )函数】-----------------------------------------
//          描述:控制台应用程序的入口函数,我们的程序从这里开始执行
//---------------------------------------------------------------------------------------------
int main(  )
{
	//【0】改变console字体颜色
	system("color 2F"); 

	//【0】显示帮助文字
	ShowHelpText();

	//【1】载入源图像并将其转换为灰度图
	g_srcImage = imread("1.jpg", 1 );
	cvtColor( g_srcImage, g_grayImage, CV_BGR2GRAY );

	//【2】创建窗口和滑动条,并进行显示和回调函数初始化
	namedWindow( WINDOW_NAME, CV_WINDOW_AUTOSIZE );
	createTrackbar( "最大角点数", WINDOW_NAME, &g_maxCornerNumber, g_maxTrackbarNumber, on_GoodFeaturesToTrack );
	imshow( WINDOW_NAME, g_srcImage );
	on_GoodFeaturesToTrack( 0, 0 );

	waitKey(0);
	return(0);
}

运行此程序,得到如下图所示的角点检测图,并且调节滑动条,可改变能检测到的最大角点数量。在程序代码中,我们设定可检测到的最大角点数量为500。

原图

1.jpg

效果图-计算角点数量

5.PNG

效果图-最大角点数为33

3.PNG

效果图-最大角点数为138

4.PNG


开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 5 天