OpenCV开发笔记(六十二):红胖子8分钟带你深入了解亚像素角点检测(图文并茂+浅显易懂+程序源码)
若该文为原创文章,未经允许不得转载
原博主博客地址:https://blog.csdn.net/qq21497936
原博主博客导航:https://blog.csdn.net/qq21497936/article/details/102478062
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/106665993
各位读者,知识无穷而人力有穷,要么改需求,要么找专业人士,要么自己研究
红胖子(红模仿)的博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中…(点击传送门)
上一篇:《OpenCV开发笔记(六十一):红胖子8分钟带你深入了解Shi-Tomasi角点检测(图文并茂+浅显易懂+程序源码)》
下一篇:持续补充中…
前言
红胖子,来也!
本篇主要说亚像素角点,又叫次级像素角点,其实通俗来说,就是输入整数坐标,使用最小二乘法迭代计算所需精度的实数坐标。
Demo






亚像素角点
概述
进行图像处理提取用于识别的特征点进行几何测量,这通常需要更高的精度,而函数goodFeaturesToTrack()只能提供简单的像素的坐怀值,也就是说,有时候会需要要实数坐标值而不是整数坐标值。
亚像素级角点检测的位置在摄像机标定、跟踪并重建摄像机的轨迹,或者重被功跟踪目标的三维结构时候,是一个基本的测量值 。
Shi-Tomasi角点检测
goodFeaturesToTrack()函数检测是的Shi-Tomasi角点。
《OpenCV开发笔记(六十一):红胖子8分钟带你深入了解Shi-Tomasi角点检测(图文并茂+浅显易懂+程序源码)》
亚像素角点检测原理

其中,(a)点p附近的图像是均匀的,其梯度为0,(b)边缘的梯度与沿地缘方向的q-p向量正交。在图中的两种情况下,p点梯度与q-p向量的点积均为0。
假设起始角点q在实际亚像素级角点的附近。检测所有的q-p向量。若点p位于一个均匀的区域,则点p处的梯度为0。若q-p向量的方向与边缘的方向一致,则此边缘上p点处的梯度与q-p向量正交,在这两种情况下,p点处的梯度与q-p向量的点积为0。可以在p点周围找到很多组梯度以及相关的向量q节,令其点集为0,然后可以通过求解方程组,方程组的解即为角点q的亚像素级精度的位置,也就是精确的角点位置。
TermCriteri迭代标注类的构造函数
TermCriteria(int type,
int maxCount,
double epsilon);
- 参数一:int类型的type,枚举为TermCriteria::Type类型,终止标准的类型:

- 参数二:int类型的maxCount,最大迭代次数/元素数;
- 参数三:double类型的epsilon,所需的精度。
函数原型
void cornerSubPix( InputArray image,
InputOutputArray corners,
Size winSize,
Size zeroZone,
TermCriteria criteria );
- 参数一:InputArray类型的image,输入图像,即源图像,填Mat类的对象,必须为单通道图像;
- 参数二:InputOutputArray类型的corners,提供输入角点的初始坐标和精确的输出坐标;
- 参数三:Sjze类型的winSjze,搜索窗口的一半尺寸。若winSize=Size(5,5),那么就表示使用(52+1)x(52+1)=11x11大小的搜索窗口。
- 参数四:Size类型的zeroZone,表示死区的一半尺寸。而死区为不对搜索区的中央位置做求和运算的区域,用来避免自相关矩阵出现的某些可能的奇异性。值为(-1,-1)表示没有死区。
- 参数五:TermCriteria类型的criteria,求角点的迭代过程的终止条件。即角点位置的确定,要么迭代数大于某个设定值,或者是精到达某个设定值。cirteria可以是最大迭代数目,或者是设定的精确度,也可以是它们的组合。
Demo源码
void OpenCVManager::testCornerSubPix()
{
QString fileName1 =
"E:/qtProject/openCVDemo/openCVDemo/modules/openCVManager/images/1.jpg";
int width = 400;
int height = 300;
cv::Mat srcMat = cv::imread(fileName1.toStdString());
cv::resize(srcMat, srcMat, cv::Size(width, height));
cv::String windowName = _windowTitle.toStdString();
cvui::init(windowName);
cv::Mat windowMat = cv::Mat(cv::Size(srcMat.cols * 2, srcMat.rows * 3),
srcMat.type());
int qualityLevel = 1;
int minDistance = 10;
int iterations = 5;
int epsilon = 1;
while(true)
{
windowMat = cv::Scalar(0, 0, 0);
cv::Mat mat;
cv::Mat tempMat;
// 原图先copy到左边
mat = windowMat(cv::Range(srcMat.rows * 0, srcMat.rows * 1),
cv::Range(srcMat.cols * 0, srcMat.cols * 1));
cv::addWeighted(mat, 0.0f, srcMat, 1.0f, 0.0f, mat);
{
// 灰度图
cv::Mat grayMat;
cv::cvtColor(srcMat, grayMat, cv::COLOR_BGR2GRAY);
cv::Mat grayMat2;
cv::cvtColor(grayMat, grayMat2, cv::COLOR_GRAY2BGR);
cv::addWeighted(mat, 0.0f, grayMat2, 1.0f, 0.0f, mat);
cvui::printf(windowMat, width * 1 + 20, height * 0 + 10, "qualityLevel / 100.0f");
cvui::trackbar(windowMat, width * 1 + 20, height * 0 + 30, 200, &qualityLevel, 1, 99);
cvui::printf(windowMat, width * 1 + 20, height * 0 + 80, "minDistance");
cvui::trackbar(windowMat, width * 1 + 20, height * 0 + 100, 200, &minDistance, 1, 100);
cvui::printf(windowMat, width * 1 + 20, height * 0 + 150, "iterations");
cvui::trackbar(windowMat, width * 1 + 20, height * 0 + 170, 200, &iterations, 1, 100);
cvui::printf(windowMat, width * 1 + 20, height * 0 + 220, "epsilon/100.0f");
cvui::trackbar(windowMat, width * 1 + 20, height * 0 + 240, 200, &epsilon, 1, 1000);
// Shi-Tomasi角点检测
std::vector<cv::Point2f> corners;
cv::goodFeaturesToTrack(grayMat, // 输入图像
corners, // 输出角点
100, // 最大输出角点数量
qualityLevel / 100.0f, // 最小特征值
minDistance, // 最小间隔距离
cv::noArray(), // 感兴趣的区域
3, // 计算矩阵时的领域范围
false, // 不适用harris角点检测
0.04); // 权重系数
cv::Mat tempMat4 = srcMat.clone();
for (int i = 0; i < corners.size(); i++)
{
cv::circle(tempMat4, corners[i], 5, cv::Scalar(0, 255, 0), 2, 8, 0);
cvui::printf(windowMat, width * 0 + 20, height * 1 + 20 * i, "%f,%f", corners[i].x, corners[i].y);
}
// copy
mat = windowMat(cv::Range(srcMat.rows * 2, srcMat.rows * 3),
cv::Range(srcMat.cols * 0, srcMat.cols * 1));
cv::addWeighted(mat, 0.0f, tempMat4, 1.0f, 0.0f, mat);
//指定亚像素计算迭代标注
cv::TermCriteria criteria = cv::TermCriteria(
cv::TermCriteria::EPS,
iterations, // 迭代次数
epsilon); // 精度
//亚像素检测
cv::cornerSubPix(grayMat,
corners,
cv::Size(5, 5),
cv::Size(-1, -1),
criteria);
//将检测到的亚像素角点绘制到原图上
cv::Mat tempMat3 = srcMat.clone();
for (int i = 0; i < corners.size(); i++)
{
cv::circle(tempMat3, corners[i], 5, cv::Scalar(0, 255, 0), 2, 8, 0);
cvui::printf(windowMat, width * 1 + 20, height * 1 + 20 * i, "%f,%f", corners[i].x, corners[i].y);
}
// copy
mat = windowMat(cv::Range(srcMat.rows * 2, srcMat.rows * 3),
cv::Range(srcMat.cols * 1, srcMat.cols * 2));
cv::addWeighted(mat, 0.0f, tempMat3, 1.0f, 0.0f, mat);
}
// 更新
cvui::update();
// 显示
cv::imshow(windowName, windowMat);
// esc键退出
if(cv::waitKey(25) == 27)
{
break;
}
}
}
工程模板:对应版本号v1.56.0
对应版本号v1.56.0
上一篇:《OpenCV开发笔记(六十一):红胖子8分钟带你深入了解Shi-Tomasi角点检测(图文并茂+浅显易懂+程序源码)》
下一篇:持续补充中…
原博主博客地址:https://blog.csdn.net/qq21497936
原博主博客导航:https://blog.csdn.net/qq21497936/article/details/102478062
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/106665993
OpenCV开发笔记(六十二):红胖子8分钟带你深入了解亚像素角点检测(图文并茂+浅显易懂+程序源码)的更多相关文章
- OpenCV开发笔记(六十九):红胖子8分钟带你使用传统方法识别已知物体(图文并茂+浅显易懂+程序源码)
若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...
- OpenCV开发笔记(六十四):红胖子8分钟带你深入了解SURF特征点(图文并茂+浅显易懂+程序源码)
若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...
- OpenCV开发笔记(六十五):红胖子8分钟带你深入了解ORB特征点(图文并茂+浅显易懂+程序源码)
若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...
- OpenCV开发笔记(五十六):红胖子8分钟带你深入了解多种图形拟合逼近轮廓(图文并茂+浅显易懂+程序源码)
若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...
- OpenCV开发笔记(五十五):红胖子8分钟带你深入了解Haar、LBP特征以及级联分类器识别过程(图文并茂+浅显易懂+程序源码)
若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...
- OpenCV开发笔记(七十一):红胖子8分钟带你深入级联分类器训练
前言 红胖子,来也! 做图像处理,经常头痛的是明明分离出来了(非颜色的),分为几块区域,那怎么知道这几块区域到底哪一块是我们需要的,那么这部分就涉及到需要识别了. 识别可以自己写模板匹配.特征 ...
- OpenCV开发笔记(七十二):红胖子8分钟带你使用opencv+dnn+tensorFlow识别物体
前言 级联分类器的效果并不是很好,准确度相对深度学习较低,本章使用opencv通过tensorflow深度学习,检测已有模型的分类. Demo 可以猜测,1其实是人,18序号类是狗 ...
- OpenCV开发笔记(七十三):红胖子8分钟带你使用opencv+dnn+yolov3识别物体
前言 级联分类器的效果并不是很好,准确度相对深度学习较低,上一章节使用了dnn中的tensorflow,本章使用yolov3模型,识别出具体的分类. Demo 320x320,置信度0 ...
- java之jvm学习笔记六-十二(实践写自己的安全管理器)(jar包的代码认证和签名) (实践对jar包的代码签名) (策略文件)(策略和保护域) (访问控制器) (访问控制器的栈校验机制) (jvm基本结构)
java之jvm学习笔记六(实践写自己的安全管理器) 安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用 AccessCo ...
- 树莓派开发笔记(十二):入手研华ADVANTECH工控树莓派UNO-220套件(一):介绍和运行系统
前言 树莓派也可以做商业应用,工业控制,其稳定性和可靠性已经得到了验证,故而工业控制,一些停车场等场景也有采用树莓派作为主控的,本片介绍了研华ADVANTECH的树莓派套件组UNO-220-P4N ...
随机推荐
- [转帖]xsos - Summarize system info from sosreports
https://github.com/ryran/rsar I'M LOOKING FOR RSAR SCREEN SHOTS INTRO INSTALLATION EXAMPLES IN ACTIO ...
- [转帖]一行Python代码实现同一局域网内的文件共享
在不同的设备之间传输文件除了数据线,网盘传输外是否还有其他优雅的方法?我们可以使用一行Python代码使局域网内的所有设备都可以访问并下载文件夹内的文件. 要求: 电脑中安装配置好python 访问的 ...
- [转帖]鹅厂微服务发现与治理巨作PolarisMesh实践-上
文章目录 概述 定义 核心功能 组件和生态 特色亮点 解决哪些问题 官方性能数据 架构原理 资源模型 服务治理 基本原理 服务注册 服务发现 安装 部署架构 集群安装 SpringCloud应用接入 ...
- 某环境私有云 rpm 包安装失败总结
1. 最近公司同事说一个项目搭建环境时 rpm 安装mysql数据库会报错 错误图片主要如下: 第一个错误提示是 提示 /etc/host.conf line 2: bad command `nosp ...
- SMFL 教程&个人笔记(2)
本文大部分来自官方教程的Google翻译 但是加了一点点个人的理解和其他相关知识 转载请注明 原文链接 :https://www.cnblogs.com/Multya/p/16317401.html ...
- ZCube:在我的优惠券中的落地实践 | 京东云技术团队
前言 我的优惠券作为营销玩法的一种运营工具,在营销活跃场中起到很至关重要的作用.如何更加高效的赋能业务,助理业务发展,灵活扩展业务,是我们一直追求和思考的方向 一.背景 1.1 现状 营销中台作为 ...
- drools规则动态化实践
作者:京东物流 李振 康睿 刘斌 王北永 一 . 规则引擎业务应用背景 业务逻辑中经常会有一些冗长的判断,需要写特别多的if else,或者一些判断逻辑需要经常修改.这部分逻辑如果以java代码来实现 ...
- css3写一个加载动画
先制作一个正方形,让圆点在正方形的最外侧 <style> body { margin: 0; } .loading { width: 200px; height: 200px; backg ...
- 理解Vuex的辅助函数mapState
参考的地址是: https://www.cnblogs.com/tugenhua0707/p/9794423.html 之所以会在这里记录下来,是为了方便自己以后忘记的时候查看学习而已~: 并没有别的 ...
- 通杀无限 debugger,目前只有 1% 的人知道!
前言 相信很多小伙伴在进行 web 逆向的时候,都遇到过无限 debugger.最简单的方法,在 debugger 位置,点击行号,右键 Never pause here,永远不在此处断下即可.但是这 ...