OpenCV3入门(十二)角点检测
1、角点介绍
角点检测(Corner Detection)是计算机视觉系统中用来获得图像特征的一种方法,广泛应用于运动检测、图像匹配、视频跟踪、三维建模和目标识别等领域中,也称为特征点检测。在图像中角点是一个重要的局部特征,它决定了图像中关键区域的形状,体现了图像中重要的特征信息。目前,角点检测方法主要有2大类:
1)基于图像边缘轮廓特征的方法。
2)基于图像灰度信息的方法。此方法主要通过计算曲率及梯度进行角点检测,通过计算边缘的曲率来判断角点的存在性。典型代表有Harris算法、Susan算法、Moravec算法等。
角点通常被定义为两条边的交点,更严格的说,角点的局部邻域应该具有两个不同区域的不同方向的边界。而实际应用中,大多数所谓的角点检测方法检测的是拥有特定特征的图像点,而不仅仅是“角点”。这些特征点在图像中有具体的坐标,并具有某些数学特征,如局部最大或最小灰度、某些梯度特征等。现有的角点检测算法并不是都十分的健壮。很多方法都要求有大量的训练集和冗余数据来防止或减少错误特征的出现。另外,角点检测方法的一个很重要的评价标准是其对多幅图像中相同或相似特征的检测能力,并且能够应对光照变化、图像旋转等图像变化。
2、Harris算法介绍
Harris 是 Harris 和 Stephens 在 1988 年提出,专门针对 Moravec 算子的改进版。Harris 算子,又称 Plessey算子,它基于与 Moravec 相同的角点定义,即定义在各个方向上灰度值变化的点。
角点可以如下图形象的定义,如果在各个方向上移动这个小窗口,窗口内的灰度发生了较大的变化,那么说明窗口内存在角点;如果在各个方向移动,灰度几乎不变,说明是平坦区域;如果只沿着某一个方向移动,灰度几乎不变,说明是直线(边缘)。
设图像窗口平移[u,v] ,产生的灰度变化为E[u,v] ,则:
上式中,窗口函数是一个矩形窗口或高斯窗口,它给在其中的像素加权。
我们必须使边角检测的函数最大化,这意味着,我们必须最大限度地利用第二个参数。
根据角点的定义,平坦区域,像素变化小,那么上式后半部分基本接近为0;在边缘区域,会在沿着边缘方向上差值为一个稳定值;只有在角点处,无论向那个方向移动,都会发生变化。
根据泰勒级数展开:
那么f(x+u, y+v)可以简化为:
f(x+u, y+v) ≈ f(x,y) + ufx(x,y) + vfy(x,y)
Harris算式的可以写成矩阵模式。
Harris算式可以近似得到下面的表达:
其中M为:
其中,表示 Ix 方向的梯度,表示Iy 方向的梯度,为高斯函数。矩阵的特征值是自相关函数的一阶曲率。特征值的大小与特征点的性质息息相关。即当两个特征值都比较小时,则此点可能位于平坦区,不为角点或边界点; 当两个特征值一个较大、而另一个却相对较小时,则此点位于边界上,属于边界点; 当两个特征值均相对较大时,则此点沿任意方向的曲率都较大,为需要提取的角点。
M为梯度的协方差矩阵,在实际应用中为了能够应用更好的编程,定义了角点响应函数R,通过判定R大小来判断像素是否为角点。R取决于M的特征值,对于角点|R|很大,平坦的区域|R|很小,边缘的R为负值。Harris角点检测算法就是对角点响应函数R进行阈值处理:R > threshold,即提取R的局部极大值。
其中,det(M) = λ1* λ1, trace(M) =λ1+ λ1 。k是经验参数,一般取值为0.04~0.06。
当R为大数值正数的时候,表示为角点。如下图所示:
3、Harris实验
OpenCV函数原型:
C++:void cornerHarris( InputArray src, //输入8bit单通道灰度Mat矩阵
OutputArray dst, //保存角点检测结果,32位单通道,大小与src相同
int blockSize, //滑块窗口的尺寸、邻域的大小
int ksize, //Sobel边缘检测滤波器大小
double k, //Harris中间参数,经验值0.04~0.06
int borderType=BORDER_DEFAULT //插值类型
);
测试实例:
int threshod_val = ;
int max_threshod_val = ;
Mat src_img; void call_back(int, void*)
{
Mat normImage, scaledImage;
Mat Img_scr1 = src_img.clone();
Mat Img_dst = Mat::zeros(src_img.size(), CV_32FC1); cornerHarris(src_img, Img_dst, , , 0.04, BORDER_DEFAULT); //进行角点检测
normalize(Img_dst, normImage, , , NORM_MINMAX, CV_32FC1, Mat()); // 归一化
convertScaleAbs(normImage, scaledImage);//将归一化后的图线性变换成8位无符号整型 for (int i = ; i < normImage.rows; i++)
{
for (int j = ; j < normImage.cols; j++)
{
if ((int)normImage.at<float>(i, j) > threshod_val + )
{
circle(Img_scr1, Point(j, i), , Scalar(, , ), , , );
circle(scaledImage, Point(j, i), , Scalar(, , ), , , );
}
} } imshow("corner", Img_scr1);
imshow("scaledImage", scaledImage);
} int main() {
src_img = imread("D:\\WORK\\5.OpenCV\\LeanOpenCV\\pic_src\\checkerboard.png");
imshow("原图", src_img); cvtColor(src_img, src_img, COLOR_BGR2GRAY);
namedWindow("corner");
createTrackbar("thresh", "corner", &threshod_val, max_threshod_val, call_back);
call_back(threshod_val, ); waitKey();
}
输出结果如下图:
测试2:
4、参考文献
1、A COMBINED CORNER AND EDGE DETECTOR,Chris Harris,Mike Stephens,1988
http://www.bmva.org/bmvc/1988/avc-88-023.pdf
2、Harris Corner Detection
3、Harris 角点检测子
4、【OpenCV入门教程之十六】OpenCV角点检测之Harris角点检测
https://blog.csdn.net/poem_qianmo/article/details/29356187
5、(四)OpenCV中的特征检测之Harris Corner检测
https://blog.csdn.net/u014403318/article/details/80562785
6、OpenCV学习笔记(八)——Harris角度特征从原理到实现详解
https://blog.csdn.net/weixin_41695564/article/details/79962401
7、《OpenCV3 编程入门》,电子工业出版社,毛星雨著
8、《学习OpenCV》,清华大学出版社,Gary Bradski, Adrian kaehler著
技术博客,转载请注明。
OpenCV3入门(十二)角点检测的更多相关文章
- Android入门(十二)SQLite事务、升级数据库
原文链接:http://www.orlion.ga/610/ 一.事务 SQLite支持事务,看一下Android如何使用事务:比如 Book表中的数据都已经很老了,现在准备全部废弃掉替换成新数据,可 ...
- ES6入门十二:Module(模块化)
webpack4打包配置babel7转码ES6 Module语法与API的使用 import() Module加载实现原理 Commonjs规范的模块与ES6模块的差异 ES6模块与Nodejs模块相 ...
- OpenCV3入门(二)Mat操作
1.Mat结构 1.1.Mat数据 Mat本质上是由两个数据部分组成的类: 矩阵头:包含信息有矩阵的大小,用于存储的方法,矩阵存储的地址等 数据矩阵指针:指向包含了像素值的矩阵. 矩阵头部的大小是恒定 ...
- SpringBoot入门 (十二) 定时任务
本文记录在SpringBoot中使用定时任务. 在我们的项目中,经常需要用到定时任务去帮我们做一些事情,比如服务状态监控,业务数据状态的更改等,SpringBoot中实现定时任务有2中方案,一种是自带 ...
- java web开发入门十二(idea创建maven SSM项目需要解决的问题)基于intellig idea(2019-11-09 11:23)
一.spring mvc action返回string带双引号问题 解决方法: 在springmvc.xml中添加字符串解析器 <!-- 注册string和json解析适配器 --> &l ...
- Hibernate入门(十二)离线条件检索
Hibernate——离线条件检索DetachedCriteria DetachedCriteria翻译为离线条件查询,因为它是可以脱离Session来使用的一种条件查询对象,我们都知道Criteri ...
- [WebGL入门]十二,模型数据和顶点属性
注:文章译自http://wgld.org/,原作者杉本雅広(doxas),文章中假设有我的额外说明,我会加上[lufy:].另外.鄙人webgl研究还不够深入,一些专业词语.假设翻译有误.欢迎大家指 ...
- Spring入门(十二):Spring MVC使用讲解
1. Spring MVC介绍 提到MVC,参与过Web应用程序开发的同学都很熟悉,它是展现层(也可以理解成直接展现给用户的那一层)开发的一种架构模式,M全称是Model,指的是数据模型,V全称是Vi ...
- Spring入门(十四):Spring MVC控制器的2种测试方法
作为一名研发人员,不管你愿不愿意对自己的代码进行测试,都得承认测试对于研发质量保证的重要性,这也就是为什么每个公司的技术部都需要质量控制部的原因,因为越早的发现代码的bug,成本越低,比如说,Dev环 ...
- 网络编程懒人入门(十):一泡尿的时间,快速读懂QUIC协议
1.TCP协议到底怎么了? 现时的互联网应用中,Web平台(准确地说是基于HTTP及其延伸协议的客户端/服务器应用)的数据传输都基于 TCP 协议. 但TCP 协议在创建连接之前需要进行三次握手(如下 ...
随机推荐
- P1010 幂次方 P1022 计算器的改良
P1010 幂次方 一.题目 https://www.luogu.org/problemnew/show/P1010 二.代码 #include<bits/stdc++.h> using ...
- tomcat更新class不生效
替换线上lib里的class不生效,需要想想是不是前人为了图方便在classes里面扔了一份老版本class
- 有关于i++,i=i++等符号的笔记
最近在看一些基础知识,发现自己以前忽略掉了很多东西,而这些东西恰恰是面试笔试中最常考到的 1.i=i+1 这个是最简单,最明了的一个表达式 2.有关于i++和++i的区别 i++和++i都是代表i=i ...
- k8s中command、args和dockerfile中的entrypoint、cmd之间的关系
当用户同时写了command和args的时候自然是可以覆盖DockerFile中ENTRYPOINT的命令行和参数,那么对于具体情况呢,比如仅仅写了command或者args的时候呢?完整的情况分类如 ...
- 信息熵、信息增益、信息增益率、gini、woe、iv、VIF
整理一下这几个量的计算公式,便于记忆 采用信息增益率可以解决ID3算法中存在的问题,因此将采用信息增益率作为判定划分属性好坏的方法称为C4.5.需要注意的是,增益率准则对属性取值较少的时候会有偏好,为 ...
- SCI|EI|ISTP|万方|istic|NSTL|CASTD|CNKI|nlc|ethesys|CALIS|CETD|proquest|NDLTD|中国科学院学位论文检索系统|学位论文
BD AC D 三大检索指的是:SCI(科学引文索引 ).EI(工程索引 ).ISTP(科技会议录索引 ) 即Science Citation Index.Engineering Index.Conf ...
- <JZOJ5941>乘
emmm还挺妙 不过我没想到qwq 考场上瞎写的还mle了心碎 把b分两..预处理下 O1询问qwq #include<cstdio> #include<iostream> # ...
- Monkey命令参数介绍
1) 参数: -p 参数-p用于约束限制,用此参数指定一个或多个包(Package,即App).指定 包之后,Monkey将只允许系统启动指定的APP.如果不指定包,Monkey将允许系统启动 ...
- log4j简单的使用
1.引入log4j.jar包 2.在类中使用 package com.donghai.log4j; import org.apache.log4j.Logger; public class LogTe ...
- 第一次安装vs2010无法运行程序,系统找不到exe文件,LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
最近在看数据结构的一些书籍,怎奈代码是c写的,所以安装一个编译器vs2010来测试代码,但是建完文件后编译ok,f5却出现错误:无法启动程序,系统找不到指定文件.上网找了一些解决办法,但是仍然无法解决 ...