手机网站框架,修改wordpress文章发布页,河南建设厅,亚马逊aws永久免费服务69OpenCV学习(二十四 #xff09;#xff1a;角点检测(Corner Detection):cornerHarris(),goodFeatureToTrack()
参考博客#xff1a; Harris角点检测原理详解 Harris角点检测原理及C实现 OpenCV亚像素角点cornerSubPixel()源代码分析 Taylor公式#xff08;泰勒公式#x…OpenCV学习(二十四 角点检测(Corner Detection):cornerHarris(),goodFeatureToTrack()
参考博客 Harris角点检测原理详解 Harris角点检测原理及C实现 OpenCV亚像素角点cornerSubPixel()源代码分析 Taylor公式泰勒公式通俗本质详解 如何理解最小二乘法
一、概述
1、角点定义 角点没有明确的数学定义,但人们普遍认为角点是二维图像亮度变化剧烈的点或图像边缘曲线上曲率极大值的点。这些点在保留图像图形重要特征的同时,可以有效地减少信息的数据量,使其信息的含量很高,有效地提高了计算的速度,有利于图像的可靠匹配,使得实时处理成为可能。其在三维场景重建、运动估计、目标跟踪、目标识别、图像配准与匹配等计算机视觉领域起着非常重要的作用。
2、角点检测 计算机视觉子系统中用来捕获图像特征的一种方法广泛应用于运动检测图相匹配视频跟踪三维重建和目标识别等领域也称为特征点检测。我不再观测整幅图二十选择某些特殊的点然后对他们进行局部 有的放矢有明确的目的性和针对性地分析。
图像的特征类型包括有 1边缘 2角点感兴趣的关键点 3斑点感兴趣的区域
关于角点的具体描述有 1一阶导数既灰度的梯度的局部最大所对应的像素点 2两条既两条以上边缘的交点 3图像中梯度值和梯度方向的变化速率都很高的点 4角点处得一阶导数最大二阶导数为零它指示了物体边缘变化不连续的方向
在当前的图像处理领域中角点检测算法可以归纳为 1基于灰度图像的角点检测基于灰度图像的角点检测又可分三类见下 2基于二值图像的角点检测 3基于轮廓曲线的角点检测
基于灰度图像的角点检测 1基于梯度 其中基于梯度的方法是通过计算边缘的曲率来判断角点的存在性,角点计算数值的大小不仅与边缘强度有关,而且与边缘方向的变化率有关,该方法对噪声比基于模板的角点检测方法对噪声更为敏感。
2基于模板 其中基于模板的方法主要考虑像素领域点的灰度变化即图像亮度的变化将与邻点亮度对比足够大的点定义为角点。常见的基于模板的角点检测算法有Kitchen-Rosenfeld角点检测算法Harris角点检测算法、KLT角点检测算法及SUSAN角点检测算法。和其他角点检测算法相比SUSAN角点检测算法具有算法简单、位置准确、抗噪声能力强等特点。
3基于模板梯度组合
二、harris角点检测cornerHarris()函数
harris角点检测是一种直接基于灰度图像的角点提取算法稳定性高尤其对L型角点检测精度高。但由于
该函数在图像上运行Harris角探测器。与cornerMinEigenVal()和cornerEigenValsAndVecs()函数类似对于每个像素(x,y)它计算 blockSize×blockSize 邻域上的2×2梯度协方差矩阵M(x,y)。然后计算如下特征 : 图像中的角点可以作为此响应映射的局部最大值。即找出角点。
void cornerHarris(
InputArray src, // 输入图像单通道8位或者浮点型图像
OutputArray dst, // 存放利用角点检测之后的图像
int blockSize*blockSize, // 表示领域的大小
int ksize, // 表示Sobel()算子孔径的大小
double k, // Harris参数
intborderTypeBORDER_DEFAULT // 图像像素的边界模式有默认值BORDER_DEFAULT
)在用cornerHarris函数时要用单通道的图像要配合阈值操作函数一起threshold()对角点检测之后的图像进行显示操作确定图像的强角点goodFeatureToTrack()函数。
三、cornerMinEigenVal(),cornerEigenValsAndVecs()函数
作用计算图像块的特征值和特征向量用于角点检测。
void cornerEigenValsAndVecs(
InputArray src, // 输入单通道8位或浮点图像
OutputArray dst, // 用来存储结果的图像它有src相同的大小和类型为CV_32FC(6)
int blockSize, // 领域尺寸
int ksize, // Sobel()算子的孔径参数
int borderTypeBORDER_DEFAULT // 图像像素的边界模式有默认值BORDER_DEFAULT
)作用计算梯度矩阵的最小特征值用于角点检测。
void cornerMinEigenVal(
InputArray src, // 输入单通道8位或浮点图像
OutputArray dst, // 用来存储最小特征值的图像它有src相同的大小和类型为CV_32FC1
int blockSize, // 领域尺寸
int ksize3, // Sobel()算子的孔径参数
int borderTypeBORDER_DEFAULT // 像素外推方式
)三、确定图像强角点Shi-Tomasi角点检测goodFeaturesToTrack()函数
goodFeatureToTrack()函数结合了Shi-Tomasi算子用于确定图像的强角点
void goodFeaturesToTrack(
InputArray image, // 输入图像需要8位的或者浮点型32位单通道图像
OutputArray corners, // 检测到角点的输出向量
int maxCorners, // 角点的最大数量
double qualityLevel, // 角点检测可接受的最小特征值其实实际用于过滤角点的最小特征值// 是 qualityLevel 与图像中最大特征值得乘积。// 通常不超过1常用0.10和0.01。检测完所有角点后// 还要剔除一些距离较近的角点
double minDistance, // 角点之间的最小距离单位为像素
InputArray masknoMask(), // 用于指定感兴趣区域的角点检测默认是noArray
int blockSize3, // 是计算导数自相关矩阵时指定的邻域范围
bool useHarrisDetectorfalse, // 指示是否使用Harris角点检测
double k0.04 // 为了用于设置Hessian 自相关矩阵行列式 的相对权重的权重系数
);四、亚像素级角点检测cornerSubPix()函数
原理见上 cornerSubPix()函数用于寻找亚像素级角点位置更精确的浮点类型位置
void cornerSubPix(
InputArray _image, // 输入的单通道图像
InputOutputArray _corners, // 提取的初始整数角点比如用goodFeatureToTrack提取的强角点
Size winSize, // 为求取亚像素角点的窗口大小比如设置Size11,11需要注意的是11为半径则窗口大小为23x23
Size zeroZone, // 设置的“零区域”在搜索窗口内设置的“零区域”内的值不会被累加权重值为0。如果设置为Size(-1,-1)则表示没有这样的区域
TermCriteria criteria // 条件阈值包括迭代次数阈值和误差精度阈值一旦其中一项条件满足设置的阈值则停止迭代获得亚像素角点
)五示例一harris角点检测
#include opencv2/opencv.hppusing namespace cv;
using namespace std;#define WINDOW_NAME1 【程序窗口1】 //为窗口标题定义的宏
#define WINDOW_NAME2 【程序窗口2】 //为窗口标题定义的宏Mat g_srcImage, g_srcImage1,g_grayImage;
int thresh 30; //当前阈值
int max_thresh 175; //最大阈值int main()
{// 1、载入原始图并进行克隆保存g_srcImage imread(F:/C/2. OPENCV 3.1.0/TEST/corner.jpg, 1 );if(!g_srcImage.data ) { printf(读取图片错误请确定目录下是否有imread函数指定的图片存在~ \n); return false; }imshow(原始图,g_srcImage);g_srcImage1g_srcImage.clone( );// 2、存留一张灰度图cvtColor( g_srcImage1, g_grayImage, COLOR_BGR2GRAY );// 3、创建窗口和滚动条namedWindow( WINDOW_NAME1, WINDOW_AUTOSIZE );createTrackbar( 阈值: , WINDOW_NAME1, thresh, max_thresh, on_CornerHarris );on_CornerHarris( 0, 0 );waitKey(0);return 0;
}void on_CornerHarris( int, void* )
{// 1、定义一些局部变量Mat dstImage;//目标图Mat normImage;//归一化后的图Mat scaledImage;//线性变换后的八位无符号整型的图// 2、初始化//置零当前需要显示的两幅图即清除上一次调用此函数时他们的值dstImage Mat::zeros( g_srcImage.size(), CV_32FC1 );g_srcImage1g_srcImage.clone( );// 3、正式检测// 进行角点检测// 领域大小为 2// sobel 算子孔径 3// harris 参数cornerHarris( g_grayImage, dstImage, 2, 3, 0.04, BORDER_DEFAULT );// 归一化与转换normalize( dstImage, normImage, 0, 255, NORM_MINMAX, CV_32FC1, Mat() );convertScaleAbs( normImage, scaledImage ); //将归一化后的图线性变换成8位无符号整型// 4、进行绘制// 将检测到的且符合阈值条件的角点绘制出来int corner_count 0;for( int j 0; j normImage.rows ; j )for( int i 0; i normImage.cols; i ){if( (int) normImage.atfloat(j,i) thresh80 ) // 设定阈值{circle( g_srcImage1, Point( i, j ), 5, Scalar(10,10,255), 2, 8, 0 );circle( scaledImage, Point( i, j ), 5, Scalar(0,10,255), 2, 8, 0 );}}cout角点个数corner_countendl;// 4、显示最终效果imshow( WINDOW_NAME1, g_srcImage1 );imshow( WINDOW_NAME2, scaledImage );
}结果
六、示例二确定图像强角点Shi-Tomasi角点检测亚像素级角点检测cornerSubPix()函数
#include opencv2/opencv.hppusing namespace cv;
using namespace std;#define WINDOW_NAME 【Shi-Tomasi角点检测】 //为窗口标题定义的宏Mat g_srcImage, g_grayImage;
int g_maxCornerNumber 50; // 角点的最大数量
int g_maxTrackbarNumber 500;
int g_minDistance 10;
RNG g_rng(12345);//初始化随机数生成器int main()
{// 1、载入原始图并进行克隆保存
// g_srcImage imread(F:/C/2. OPENCV 3.1.0/TEST/corner2.jpg, 1 );g_srcImage imread(F:/C/2. OPENCV 3.1.0/TEST/test1.png, 1 );if(!g_srcImage.data ) { printf(读取图片错误请确定目录下是否有imread函数指定的图片存在~ \n); return false; }cvtColor( g_srcImage, g_grayImage, COLOR_BGR2GRAY );// 2、创建窗口和滑动条并进行显示和回调函数初始化namedWindow( WINDOW_NAME, WINDOW_AUTOSIZE );createTrackbar( 最大角点数, WINDOW_NAME, g_maxCornerNumber, g_maxTrackbarNumber, on_GoodFeaturesToTrack );createTrackbar( 最小距离, WINDOW_NAME, g_minDistance, 100, on_GoodFeaturesToTrack );imshow( 原始图, g_srcImage );on_GoodFeaturesToTrack( 0, 0 );waitKey(0);return 0;
}void on_GoodFeaturesToTrack( int, void* )
{// 1、对变量小于等于1时的处理if( g_maxCornerNumber 1 ){g_maxCornerNumber 1;}// 2、Shi-Tomasi算法goodFeaturesToTrack函数的参数准备vectorPoint2f corners;double qualityLevel 0.01;//角点检测可接受的最小特征值int blockSize 3;//计算导数自相关矩阵时指定的邻域范围double k 0.04;//权重系数Mat copy g_srcImage.clone(); //复制源图像到一个临时变量中作为感兴趣区域// 3、进行Shi-Tomasi角点检测goodFeaturesToTrack( g_grayImage, // 输入图像corners, // 检测到的角点的输出向量g_maxCornerNumber, // 角点的最大数量qualityLevel, // 角点检测可接受的最小特征值g_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 );// 7、亚像素角点检测的参数设置Size winSize Size( 5, 5 );Size zeroZone Size( -1, -1 );// TermCriteria术语标准TermCriteria criteria TermCriteria( TermCriteria::EPS TermCriteria::MAX_ITER, 40, 0.001 );// 8、计算出亚像素角点位置vectorPoint2f corners_subcorners;cornerSubPix( g_grayImage, corners_sub, winSize, zeroZone, criteria );// 9、输出角点信息for( int i 0; i corners.size(); i ){cout \t亚像素级/像素级 角点坐标[i] (corners_sub[i]) (corners[i].x,corners[i].y)endl;}
}结果