OpenCV学习(二十四 ):角点检测(Corner Detection):cornerHarris(),goodFeatureToTrack()

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参数
intborderType=BORDER_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 borderType=BORDER_DEFAULT 	// 图像像素的边界模式有默认值BORDER_DEFAULT
)

作用:计算梯度矩阵的最小特征值用于角点检测。

void cornerMinEigenVal(
InputArray src, 			// 输入单通道8位或浮点图像;
OutputArray dst, 			// 用来存储最小特征值的图像;它有src相同的大小和类型为CV_32FC1;
int blockSize, 				// 领域尺寸;
int ksize=3, 				// Sobel()算子的孔径参数;
int borderType=BORDER_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 mask=noMask(),		// 用于指定感兴趣区域的角点检测,默认是noArray()
int blockSize=3,				// 是计算导数自相关矩阵时指定的邻域范围
bool useHarrisDetector=false,	// 指示是否使用Harris角点检测
double k=0.04					// 为了用于设置Hessian 自相关矩阵行列式 的相对权重的权重系数
);

四、亚像素级角点检测:cornerSubPix()函数

原理见上:
cornerSubPix()函数用于寻找亚像素级角点位置(更精确的浮点类型位置)

void cornerSubPix( 
InputArray _image, 				// 输入的单通道图像
InputOutputArray _corners,		// 提取的初始整数角点(比如用goodFeatureToTrack提取的强角点)
Size winSize, 					// 为求取亚像素角点的窗口大小,比如设置Size(11,11),需要注意的是11为半径,则窗口大小为23x23
Size zeroZone, 					// 设置的“零区域”,在搜索窗口内,设置的“零区域”内的值不会被累加,权重值为0。如果设置为Size(-1,-1),则表示没有这样的区域
TermCriteria criteria 			// 条件阈值,包括迭代次数阈值和误差精度阈值,一旦其中一项条件满足设置的阈值,则停止迭代,获得亚像素角点
)

五示例一:harris角点检测

#include <opencv2/opencv.hpp>using 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_srcImage1=g_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_srcImage1=g_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.at<float>(j,i) > thresh+80 )    //  设定阈值{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_count<<endl;// 4、显示最终效果imshow( WINDOW_NAME1, g_srcImage1 );imshow( WINDOW_NAME2, scaledImage );
}

结果:
在这里插入图片描述
在这里插入图片描述

六、示例二:确定图像强角点:Shi-Tomasi角点检测,亚像素级角点检测:cornerSubPix()函数

#include <opencv2/opencv.hpp>using 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函数)的参数准备vector<Point2f> 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、计算出亚像素角点位置vector<Point2f> corners_sub=corners;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;}
}

结果:
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/491084.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在线ps网站

https://ps.gaoding.com/

无人驾驶技术的7大典型应用场景

来源 | 数据观综合无人驾驶风口来临&#xff0c;引得各方资本竞相追逐。据业内预测&#xff0c;2019年到2020年无人驾驶L3&#xff08;条件自动&#xff09;级别的汽车将实现量产化&#xff0c;2022年后部分企业将实现L4&#xff08;高度自动&#xff09;量产&#xff0c;若要实…

数字图像处理学习笔记(一):特征检测和匹配概述

数字图像处理学习笔记&#xff08;一&#xff09;&#xff1a;特征检测和匹配概述 参考博客&#xff1a; 特征点的匹配SIFT特征详解数字图像处理学习笔记&#xff08;二&#xff09;&#xff1a;SIFT&#xff08;尺度不变特征变换&#xff09;算法 1、特征点概述 如何高效且…

iOS强制切换横屏、竖屏

切换横竖屏最直接的方式是调用device的setOrientation方法。但是从sdk3.0以后&#xff0c;这个方法转为似有API&#xff0c;如果要上AppStore的话&#xff0c;要慎用&#xff01; if ([[UIDevice currentDevice] respondsToSelector:selector(setOrientation:)]) { [[UIDevice …

PDF在线编辑

http://edit.foxitcloud.cn/

数字图像处理学习笔记(二):SIFT(尺度不变特征变换)算法

数字图像处理学习笔记&#xff08;二&#xff09;&#xff1a;SIFT&#xff08;尺度不变特征变换&#xff09;算法 一、概述&#xff1a; 提到特征点算法&#xff0c;首先就是大名鼎鼎的SIFT算法了。SIFT的全称是Scale Invariant Feature Transform&#xff0c;尺度不变特征变…

微软向马斯克的人工智能公司OpenAI投资10亿美元

来源: 新浪财经新浪美股讯微软(Microsoft)周一宣布&#xff0c;将向埃隆-马斯克(Elon Musk)的OpenAI投资10亿美元&#xff0c;打造能够处理更复杂任务的人工智能。根据声明&#xff0c;通过合作&#xff0c;两家公司将建立新的Azure AI超级计算技术&#xff0c;微软将成为OpenA…

java堆分析神器MAT

Memory Analyzer&#xff08;MAT&#xff09;基于Eclipse的软件http://www.eclipse.org/mat/转载于:https://www.cnblogs.com/SEC-fsq/p/5282092.html

keras.metrics中的accuracy

keras.metrics有六种accuracy&#xff0c;其使用的场景如下&#xff1a; accuracy 真实标签和模型预测均为标量&#xff0c;如真实标签为[0,1,1,0,2,0]&#xff0c;模型输出的预测为[0,2,1,1,2,0]&#xff0c;此时accuracy4/6 categorical_accuracy ​​​​​​​真实标签为…

数字图像处理学习笔记(三):ORB算法(尺度不变特征变换)Oriented FAST and Rotated BRIEF

数字图像处理学习笔记&#xff08;三&#xff09;&#xff1a;ORB算法&#xff08;尺度不变特征变换&#xff09;Oriented FAST and Rotated BRIEF 一、概述 参考&#xff1a;特征点匹配特征检测方法汇总 ORB的全称是Oriented FAST and Rotated BRIEF&#xff0c;是目前来说…

华为:对部分顶尖学生实行年薪制 最高200万元

来源&#xff1a;EETOP7月23日上午消息&#xff0c;据华为总裁办签发的电子邮件&#xff0c;华为对部分2019届顶尖学生实行年薪制管理。华为以电邮通知【2019】068号文发布了8名天才少年的年薪方案&#xff0c;这8名人员全部为2019届应届顶尖学生&#xff0c;其年薪的最低限为8…

解决PendingIntent传递参数为空的问题

PendingIntent pIntent PendingIntent.getActivity(context, 0, intent, 0); 在接收端&#xff0c;接收的数据一直为null&#xff0c;在google官方网站查了下&#xff0c;发现问题出在flags上&#xff1a;PendingIntent.getActivity原型如下&#xff1a; PendingIntent.get…

matplotlib使用GridSpec自定义子图位置 (非对称的子图)

上图的结构可以用一下两种方式画&#xff1a; import matplotlib.pyplot as plt from matplotlib.gridspec import GridSpecfig plt.figure(1) gs GridSpec(3, 3)ax1 plt.subplot(gs[0, :]) ax2 plt.subplot(gs[1, :2]) ax3 plt.subplot(gs[1:, 2]) ax4 plt.subplot(gs[…

大脑简史(1)-历史上的大事件

来源&#xff1a;人机与认知实验室能够上天入地&#xff0c;却不知道自己的大脑&#xff0c;笔者认为这是很多人的疑惑。随着科技的发展&#xff0c;我们能够延伸到的地方越来越多&#xff0c;无论是伸手不见五指的海底&#xff0c;还是扶摇直上九万里的浩渺星空&#xff0c;都…

字符集和编码规范:ASCII,Unicode和UTF-8, latin1,BIG5,GBK

字符集和编码方式&#xff1a;ASCII,Unicode和UTF-8, latin1,BIG5,GBK 参考&#xff1a; 字符集 字符集编码详解 一、 ASCII码 我们知道&#xff0c;在计算机内部&#xff0c;所有的信息最终都表示为一个二进制的字符串。每一个二进制位&#xff08;bit&#xff09;有0和1两…

作业3词频统计

(1). 实现一个控制台程序&#xff0c;给定一段英文字符串&#xff0c;统计其中各个英文单词&#xff08;4字符以上含4字符&#xff09;的出现频率。 答&#xff1a; 从文件读取遍历字符串大写转小写将句子分隔成一个个单词判断是否为单词计算单词出现的频率预估时间10minutes10…

MATLAB报错Invalid ADAPTORNAME specified. Type 'imaqhwinfo' for a list of available ADAPTORNAMEs. Image

MATLAB报错Invalid ADAPTORNAME specified. Type imaqhwinfo for a list of available ADAPTORNAMEs. Image acquisition adaptors may be available as downloadable support packages. Open Support Package Installer to install additional vendors. 这时需要安装两个安装…

陈天奇:十年机器学习科研之路(附链接)

来源&#xff1a;深度学习自然语言处理链接&#xff1a;https://zhuanlan.zhihu.com/p/74249758导读十年前&#xff0c;MSRA的夏天&#xff0c;刚开始尝试机器学习研究的我面对科研巨大的不确定性&#xff0c;感到最多的是困惑和迷茫。十年之后&#xff0c;即将跨出下一步的时候…

QT示例:基于TCP 点对多Socket通讯(server,clients)

QT示例&#xff1a;基于TCP 点对多通讯&#xff08;server,clients&#xff09;一、服务器server二、客户端Client下载&#xff1a;基于TCP 点对多Socket通讯 一、服务器server 因为对于客户端来说&#xff0c;只能连接一个服务器。而对于服务器来说&#xff0c;它是面向多连…

错误 undefined reference to __cxa_guard_acquire/release

用gcc编译 c 程序时&#xff0c;出现错误 undefined reference to __cxa_guard_acquire linker error&#xff0c; 但是用icc可以正常编译&#xff0c; 问题出在static 上。从网上搜到的解决办法是加库的链接&#xff1a; To resolve this undefined references (__cxa_guard_a…