当前位置: 首页 > news >正文

【OpenCV C++20 学习笔记】霍夫圆形变换-Hough Circle Transform

霍夫圆形变换

  • 原理
  • API
  • 实例

原理

霍夫圆形变换和霍夫直线变换的原理类似:

  • 在霍夫直线变换中,笛卡尔坐标系中的直线被变换成了霍夫空间中的 ( r , θ ) (r, \theta) (r,θ)
  • 在霍夫圆形变换中,笛卡尔坐标系中的圆被变换乘霍夫空间中的 C : ( x c e n t e r , y c e n t e r , r ) C:(x_{center}, y_{center}, r) C:(xcenter,ycenter,r);其中 ( x c e n t e r , y c e n t e r ) (x_{center},y_{center}) (xcenter,ycenter)为圆心, r r r为圆的半径。

在OpenCV中,处于效率的考虑,使用的并不是标准霍夫变换,而是霍夫斜率方法(Hough gradient method),这个方法分为两个主要步骤:

  1. 边缘检测,并找出可能的圆心
  2. 为每个可能的圆心找到最合适的半径

API

OpenCV中霍夫圆形变换的方法为HoughCircles()函数,其原型如下:

void cv::HoughCircles(	InputArray	image,			//8为单通道灰度输入图OutputArray	circles,		//圆形结果向量数组int			method,			//检测方法double		dp,				//霍夫空间中的最小单元与图片像素的比例的倒数double		minDist,		//检测到的圆形的圆心之间的最小距离double		param1 = 100,	//定义检测方法的辅助参数double		param2 = 100,	//定义检测方法的辅助参数int			minRadius = 0,	//圆形的最小半径int			maxRadius = 0)	//圆形的最大半径
  • method对应HoughModes枚举变量,其中与圆形检测相关的方法主要有2个,分别是HOUGH_GRANDIENTHOUGH_GRADIENT_ALT,后者对前者做了点修改使得精确度更高
  • 该函数同时还执行了边缘检测,所以要确定边缘检测中的阈值,而param1定义了HOUGH_GRANDIENTHOUGH_GRADIENT_ALT方法中的边缘检测的上阈值,下阈值则默认为上阈值的1/2。注意,在HOUGH_GRADIENT_ALT方法中,使用的是Scahrr算法,所以阈值相对Canny方法会更高
  • 如果使用的是HOUGH_GRANDIENT方法,那么param2就是该方法中圆形检测的阈值,这个值越小就会检测出越多错误的圆形;如果使用的是HOUGH_GRADIENT_ALT方法,那么param2就是圆形“完美指数”,它的值越接近1,则检测出来的圆越完整,一般设置为0.9最合适,如果想要更多的小圆被检测到,可以调低到0.85或0.8及以下。
  • dp是霍夫空间中的最小单元(accumulator)和图片像素的比例的倒数。比如,当dp = 1时,霍夫空间中的最小单元的数量与图片中像素的数量相同;当dp = 2时,霍夫空间的行数和列数仅为图片行数和列数的一半。HOUGH_GRADIENT_ALT方法中,该参数建议指定为1.5,否则的话一些非常小的圆也被识别。
  • minDist参数表示在什么范围内只允许检测出1个圆心。比如,当minDist = 10时,表示检测出来的两个圆形,它们圆心的距离不能小于10个像素。这个参数如果很小,则会导致同一个区域检测出多个圆心非常相近的圆,从而混淆了真实的圆。
  • minRadiusmaxRadius分别定义了检测出的圆形的最小半径和最大半径。注意:如果maxRadius = 0,使用图片的宽和高中较大的那个作为最大半径;如果maxRadius < 0HOUGH_GRANDIENT方法只范围圆心,不返回半径,HOUGH_GRADIENT_ALT方法则还是会计算半径

HoughCircles()方法检测圆心的精确率比检测半径要高,所以如果用户知道图片中的圆的半径的范围,则最好在参数中指定这个范围。也可以将maxRadius设置为负数,这样就只检测圆心,然后再用别的方法去确定半径。

实例

使用OpenCV的示例图:"...\opencv\sources\samples\data\smarties.png"
圆形检测的完整步骤:

  1. 灰度化+中值滤波,去除噪音
  2. 使用HoughCircles()函数进行圆形检测
  3. 绘制检测结果

完整代码如下:

#include <opencv2/imgproc.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>using namespace cv;
using namespace std;int main() {Mat src{ imread("smarties.png") };//灰度化Mat gray;cvtColor(src, gray, COLOR_BGR2GRAY);//中值滤波-去除噪音medianBlur(gray, gray, 5);//检测圆形vector<Vec3f> circles;HoughCircles(gray, circles, HOUGH_GRADIENT, 1,gray.rows / 16,	//圆心间的距离最小为图片高度的1/16100,			//Canny边缘检测的上阈值30,				//圆形检测的阈值1,				//最小半径30);			//最大半径//绘制检测结果Mat dst{ src.clone() };for (size_t i{ 0 }; i < circles.size(); i++) {Vec3i c{ circles[i] };Point center{ Point(c[0], c[1]) };//圆心circle(dst, center, 1, Scalar(0, 100, 100), 3, LINE_AA);//圆周int radius{ c[2] };circle(dst, center, radius, Scalar(255, 0, 255), 3, LINE_AA);}imshow("原图", src);imshow("检测结果", dst);waitKey(0);
}

运行效果如下(左图为原图,右图为检测结果):
圆形检测效果

相关文章:

  • Can‘t import openai in Node
  • 2024 某公司python 面试真题
  • C# Unity 面向对象补全计划 泛型约束
  • 代码随想录算法训练营第三十九天 | 322. 零钱兑换、279.完全平方数、139.单词拆分、多重背包理论基础、背包问题总结
  • 到底是低度还是高度的白酒对身体的伤害更大?
  • Linux网络编程3
  • 20240807 每日AI必读资讯
  • UNI-APP_点击,长按,触摸,结束触摸事件
  • 【C/C++笔记】:易错难点3 (二叉树)
  • Redis哨兵集群部署 一主两从三哨兵以及持久化
  • 动态规划之——背包DP(进阶篇)
  • 网络原理(2)——封装和分用
  • 鸿蒙图形开发【3D引擎接口示例】
  • 数据结构——排序(1):插入排序
  • 递归深度问题和尾调用的关系
  • 【跃迁之路】【477天】刻意练习系列236(2018.05.28)
  • 2017-08-04 前端日报
  • Apache Zeppelin在Apache Trafodion上的可视化
  • Apache的基本使用
  • Cookie 在前端中的实践
  • E-HPC支持多队列管理和自动伸缩
  • es6--symbol
  • Essential Studio for ASP.NET Web Forms 2017 v2,新增自定义树形网格工具栏
  • GitUp, 你不可错过的秀外慧中的git工具
  • iOS动画编程-View动画[ 1 ] 基础View动画
  • Java多态
  • Js基础——数据类型之Null和Undefined
  • mongodb--安装和初步使用教程
  • Python 基础起步 (十) 什么叫函数?
  • SpringCloud集成分布式事务LCN (一)
  • VirtualBox 安装过程中出现 Running VMs found 错误的解决过程
  • WePY 在小程序性能调优上做出的探究
  • 从零搭建Koa2 Server
  • 分类模型——Logistics Regression
  • 浏览器缓存机制分析
  • 提升用户体验的利器——使用Vue-Occupy实现占位效果
  • 异常机制详解
  • 主流的CSS水平和垂直居中技术大全
  • ionic入门之数据绑定显示-1
  • python最赚钱的4个方向,你最心动的是哪个?
  • 阿里云IoT边缘计算助力企业零改造实现远程运维 ...
  • 积累各种好的链接
  • ​configparser --- 配置文件解析器​
  • ​如何在iOS手机上查看应用日志
  • ​字​节​一​面​
  • # C++之functional库用法整理
  • ### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTr
  • #[Composer学习笔记]Part1:安装composer并通过composer创建一个项目
  • (LeetCode 49)Anagrams
  • (三分钟了解debug)SLAM研究方向-Debug总结
  • (十三)Maven插件解析运行机制
  • (十一)c52学习之旅-动态数码管
  • (四)Tiki-taka算法(TTA)求解无人机三维路径规划研究(MATLAB)
  • (太强大了) - Linux 性能监控、测试、优化工具
  • (一)appium-desktop定位元素原理