Hough变换

  • 一、标准Hough线变换(SHT)
    • 1.1 原理
    • 1.2 SHT步骤
    • 1.3 缺点
  • 二、渐进概率Hough变换(PPHT)
    • 2.1 原理及步骤
    • 2.2 缺点
  • 三、Hough圆变换
    • 3.1 原理及步骤
    • 3.2 缺点
  • 四、实验代码

一、标准Hough线变换(SHT)

1.1 原理

标准Hough变换(standard hough transform)
图像平面中的一条直线可以通过斜截式y = ax+b来表示,即可以化为a-b平面中的一个点,但是因为斜率的区间为-∞到+∞变化,当直线接近竖直时,此时在a-b平面中是难以表示的,因此通过极坐标形式能够更加方便地表示

如图(A)所示,在图像平面中,一个点可以通过横纵坐标来表示;而图像平面中的一条直线可以通过距离原点的距离ρ,以及垂线的角度θ来表示,将其转换到θ-ρ平面中如(C)所示,即图像平面中的一条直线可由θ-ρ平面中的一个点表示因此图像平面中的一个点可以由穿过它的直线族在θ-ρ平面中对应的点组成的曲线来表示。如(C)所示,虚线对应(B)中的直线1,2,3,4的交叉点。可以得到在θ-ρ平面中两条曲线的交点即为图像平面中的两个点共线的一条直线

1.2 SHT步骤

因此标准霍夫线变换的步骤就很明了了:
① 首先对图片img进行边缘检测得到二值边缘图像edge_img
② 对于edge_img中的每个非0点都转换为θ-ρ平面中的一条曲线
转换方法如下:
对于图像平面中的一个非0点(x0,y0),使θ由0向2π变化,分别通过下式计算所对应的ρ值,

可以得到一系列点,这些点组成点(x0,y0)在θ-ρ平面中对应的曲线。
③ 在θ-ρ中进行对所有结果进行累加,则图像平面中的直线将显示为θ-ρ平面中的局部极大值。
④ 根据所设定的阈值对局部极大值进行筛选,得到最终的结果

1.3 缺点

标准霍夫线变换(SHT)是不能提取出线的端点的,并且耗时较长

OpenCV函数原型

//函数HoughLines的原型为:
void HoughLines(
InputArray image, //输入图像,要求是单通道的二值图像
OutputArray lines, //输出直线向量,两个元素的向量(ρ,θ)代表一条直线,原点为图像左上角
double rho,  //距离分辨率,单位为像素
double theta,  //角度分辨率,单位为弧度
int threshold,  // 阈值,用于筛选p-θ平面的极大值,实际指明了返回的直线至少包含的点的数量
double srn=0, // srn与stn是用于多尺度Hough变换(MHT)的参数,与标准hough变换无关
,double stn=0)
//其中rho和theta两个分辨率参数的作用还没仔细研究

多尺度hough变换(MHT)是对SHT的细化,精度更高(是通过srn,stn这两个参数对标准huogh变换的结果进行精确化)

二、渐进概率Hough变换(PPHT)

2.1 原理及步骤

渐进概率Hough变换(Progressive Probabilistic Hough Transform)是对SHT的改进,能够极大的减少计算时间,并且能够计算出直线的端点:
其主要原理是:在Edge图像中随机选择像素,将这些像素点按照SHT中的方法转换到累加平面(p-θ)。 当在累加平面中可以通过阈值筛选出一条直线时,沿该条直线搜索Edge图像,以查看是否存在一个或多个有限长度的线。然后在该直线的所有像素被从Edge图像中除去。通过这种方式,算法返回有限长度的直线。

该算法可以概括如下:
①创建输入边 Edge 图像(IMG1)的副本(IMG2)。
②用从 IMG2 随机选择的像素更新累加器。
③从 IMG2 中删除像素。
④如果修改的累加器(BINX)中具有最大值的较低阈值,转到第1点。
⑤沿着由BINX指定的线在 IMG1 中搜索,找到连续或间隙不超过给定阈值的间隔的最长像素段。
⑥从 IMG2 中删除段中的像素,清除BINX。
⑦如果检测到的线段比给定的最小长度长,请将其添加到输出列表中。
⑧转到第2点

2.2 缺点

该算法的一个问题是,多次运行可能会产生不同的结果。 如果许多直线共享像素,则会出现这种情况。如果两条线交叉,要检测的第一条线将去除公共像素(以及其周围的部分),从而导致另一条线上出现凹陷。 如果多条线交叉,则许多像素可能会错过最后一行,并且累加器中的投票可能无法达到阈值。

OpenCV函数:

void HoughLinesP(
InputArray image, //输入图像,要求是单通道的二值图像
OutputArray lines, //输出直线向量,为四通道向量,分别是线段的两个端点的坐标:(x0,y0,x1,y1)
double rho,  //距离分辨率,单位为像素
double theta,  //角度分辨率,单位为弧度
int threshold,  // 阈值,用于筛选p-θ平面的极大值,实际指明了返回的直线至少包含的点的数量
double minLineLength=0, // 线段长度阈值
,double maxLineGap=0   //线段之间的间隔阈值)

三、Hough圆变换

3.1 原理及步骤

Hough圆变换的原理与前文的Hough线变换相似,Hough线变换是在p-θ平面中不断累加,最后寻找极大值点,Hough圆变换也可以通过类似的方式寻找,需要在三维空间中累加体积,三维分别是圆心的横坐标、纵坐标、半径,但是这样时间复杂度和空间复杂度会非常大,所以实际实现时没有采用这种方法。OpenCV中的Hough圆变换是通过Hough梯度法实现的。

首先看一张图:

可以看到圆上的每一个点(橙色点)都存在一条线(蓝色虚线)相交于圆心(红点),而这些线就是各个点的梯度方向(蓝色箭头)所在的直线。圆心是它们的交点,这就与Hough线变换中的累加平面非常相似了,此时将所有直线都累加起来,圆心就是一个局部极大值点!

所以Hough圆变换就可以通过下面的方法实现了:
① 同样的,首先对图像进行边缘检测,得到edge_img;
② 对edge_img中的每一个非0点计算局部梯度(可以通过Sobel算子计算)
③ 沿着每个点的梯度所在的直线在累加平面中进行累加,同时记录非0点的位置
④ 根据阈值选取累加平面中的局部极大值点作为候选圆心
⑤ 对于每个圆心都有一个与它相关的非0点的列表(步骤③中记录的),计算这些非0点与该圆心的距离,从中选取出最优值作为半径
⑥ 如果有足够数量的点构成圆且该圆心与其它圆心间距超过阈值,就保留这个圆
⑦ 最终就能够得到检测结果

3.2 缺点

①累加器阈值过低时速度会非常慢,因为需要考虑每个非0点
②对每个圆心只能选一个圆,同心圆时只能检测到一个
③Sobel计算的是局部梯度,所以会出现噪音,稳定性略低

OpenCV函数:

//HoughCircles中调用了Canny函数,因此不需要另外对图像进行边缘检测
void HoughCircles(
InputArray image, //输入图像,要求是8位图像,即灰度图,因为需要计算梯度,使用灰度图更精准,与HoughLines中要求二值图像不同
OutputArray circles, //输出,为矩阵或者向量,矩阵的话就是F32C3的数组,三个通道分别为圆心坐标和半径;向量的话就是vector<Vec3f>类型
int method,  //实际设置为cv::HOUGH_GRADIENT
double dp,  //累加图像的分辨率,需要大于等于1
double minDist,  // 圆之间的最小距离阈值
double param1=100, //用于Canny中的高阈值,Canny的低阈值设为它的一半
double param2=100   //累加器阈值,与HoughLines中的threshold类似
int minRadius = 0,     //最小半径阈值
int maxRadius = 0      //最大半径阈值
)

四、实验代码


void hough_test()
{Mat src = imread("../Images/10.jpg");if (src.empty()) { cout << "read the image failed!!!!!!" << endl;}//读入灰度图,用于hough圆变换检测Mat src_circles = imread("../Images/11.jpg");Mat src_circles_gray;cv::cvtColor(src_circles, src_circles_gray, cv::COLOR_BGR2GRAY);Mat src_PPHT;src.copyTo(src_PPHT);Mat edge_img;vector<Vec2f> hough_lines;vector<Vec4f> hough_P_lines;vector<Vec3f> hough_circles;//图像的宽和高int w = src.cols;int h = src.rows;//Canny滤波Canny(src, edge_img, 50, 150);//SHT 标准hough线变换HoughLines(edge_img, hough_lines, 1, CV_PI/180, 130);//PPHT 渐进hough线变换HoughLinesP(edge_img, hough_P_lines, 1, CV_PI / 180, 130, 20, 100);//Hough圆变换HoughCircles(src_circles_gray, hough_circles, cv::HOUGH_GRADIENT, 2, 50, 100, 100, 10, 300);//在原图上绘制SHT检测出的直线for (auto& line_iter : hough_lines){float rho = line_iter[0];float theta = line_iter[1];Point point1, point2;point1.x = rho*cos(theta) + w*sin(theta);point1.y = rho*sin(theta) - w*cos(theta);point2.x = rho*cos(theta) - w*sin(theta);point2.y = rho*sin(theta) + w*cos(theta);line(src, point1, point2, Scalar(0, 255, 0), 2,8);}//绘制PPHT检测到的直线for (auto& line_iter : hough_P_lines){line(src_PPHT, Point(line_iter[0], line_iter[1]), Point(line_iter[2], line_iter[3]),Scalar(0,0,255),2,8);}//绘制Hough圆变换检测到的圆for (auto& circles : hough_circles){circle(src_circles, Point(circles[0], circles[1]), circles[2], Scalar(0,0,255), 2);}namedWindow("src_SHT", WINDOW_NORMAL);imshow("src_SHT", src);namedWindow("src_PPHT", WINDOW_NORMAL);imshow("src_PPHT", src_PPHT);namedWindow("edge_img", WINDOW_NORMAL);imshow("edge_img", edge_img);namedWindow("circles_img", WINDOW_NORMAL);imshow("circles_img", src_circles);waitKey(0);
}

实验结果如图:

参考资料:
《学习OpenCV3》
https://sikasjc.github.io/2018/04/20/Hough/
https://blog.csdn.net/qq_37059483/article/details/77891698

最后,如有错误的地方还请大佬指正,同时欢迎一起讨论,转载请注明出处

图像处理算法 之 Hough变换相关推荐

  1. 图像处理(八):线段检测之Hough变换

    现阶段用最多的线段检测算法为Hough变换,对于Hough变换的原理部分已经有很多人写过,具体可以参考:点击打开链接,这里我总结一下理解Hough变换算法的难点. 一.直线表示方法: 1)最常用的方法 ...

  2. 物体识别算法——SIFT/SURF、haar特征、广义hough变换的对比分析

    著作权归作者所有. 商业转载请联系作者获得授权,非商业转载请注明出处. 作者:cvvision 链接:http://www.cvvision.cn/7780.html 来源:CV视觉网 识别算法概述: ...

  3. 图像处理:Hough变换原理分析

    一.前言 别看Hough变换似乎简单,但是,不发挥一下数学理论的功力是不可能理解的:本人早十几年前就用Hough,也一直想写Hough变换,但一懒就是10几年,乘春节前有空,就将Hough的详细细节揭 ...

  4. 三种强大的物体识别算法——SIFT/SURF、haar特征、广义hough变换的特性对比分析

    识别算法概述: SIFT/SURF基于灰度图, 一.首先建立图像金字塔,形成三维的图像空间,通过Hessian矩阵获取每一层的局部极大值,然后进行在极值点周围26个点进行NMS,从而得到粗略的特征点, ...

  5. 【数字图像处理matlab】(HSI变换融合算法)

    [数字图像处理matlab](HSI变换融合算法) 输入一张高分辨率的全色影像HR,一张低分辨率的多光谱影像MS,采用HSI变换融合算法实现影像融合,其中RGB与HSI影像的相互转换调用自定义函数RG ...

  6. 计算机视觉检测 白皓月,Hough变换和轮廓匹配相结合的瞳孔精确检测算法

    摘要 针对红外眼部视频中瞳孔直径检测精度不够高的问题,提出了一种将Hough圆变换和轮廓匹配相结合的瞳孔检测算法(Hough-Contour).对每帧图像,首先进行灰度化并滤波去噪;然后提取边缘并利用 ...

  7. 基于坐标变换与随机Hough 变换的抛物线运动目标检测算法

    波条件下,高检测概率会带来高的虚警概率:而在稀疏杂波条件下, 检测效果比较好. 关键词:随机Hough 变换, 抛物线, 曲线检测 中图分类号:TN957.51 文献标识码:A 文章编号:1009-5 ...

  8. matlab hough算法车牌识别,一种利用Hough变换和先验知识的车牌识别新方法

    随着交通管理系统的日趋现代化,车牌自动识别系统成为智能交通系统的重要组成部分.通过对当前车牌识别的基本原理和主要方法的研究,分析比较各种识别方法的优缺点,针对车牌定位.字符分割和字符识别,本文提出一套 ...

  9. hough变换连接边缘matlab,matlab图像处理hough变换程序执行问题

    matlab图像处理hough变换程序执行问题0 pxkd82013.04.23浏览184次分享举报 程序如下: I= imread('D:\MATLAB7\fenkuai.bmp','bmp');% ...

  10. 小白学习图像处理7——Hough变换检测直线

    文章目录 一.Hough变换的原理 1.过定点的直线方程 2.两点确定一条直线 3.方程的形式 二.实现过程 三.程序代码 1.程序片段 2.总程序 四.matlab 的hough函数 一.Hough ...

最新文章

  1. Python3 调试技巧 —— 死循环
  2. 【数学专题】组合数学与计数
  3. Python3 异步编程之进程与线程-1
  4. Spring Boot 获取 Bean 的 3 种方式!还有谁不会?
  5. hbase 单机 java api,HBase学习(一)hbase安装(单机模式)和javaapi客户端访问hbase例子...
  6. cmd mysql_CMD命令操作MySql数据库的方法详解
  7. 【iOS】NSNumberFormatter
  8. 网站商务通如何导出查看历史聊天纪录
  9. 小程序 国际化_在国际化您的应用程序时忘记的一件事
  10. php_self nginx,nginx中的PATH_INFO为什么会影响$_SERVIER['PHP_SELF']
  11. 【文末有福利】量子计算是对计算本质的发现
  12. byte数组转blob类型_Java类型相互转换byte[]类型,blob类型
  13. 给定一个字符串数组,将字母异位词组合在一起。字母异位词指字母相同,但排列不同的字符串。
  14. 【JavaScript】图表分析
  15. 爬取mm131套图并下载到本地
  16. 如何理解T检验和P值
  17. vue3和vue2中mian.js的区别,在其中配置路由为例
  18. 前端实现搜索联想时防抖功能:
  19. 每日一问 --发信机和收信机对信号做了那些处理?
  20. winscp 进入mysql命令_WinSCP命令行操作

热门文章

  1. 计算机数控入门,数控基础知识课件
  2. 北大计算机考研题一般出自哪里,北大计算机考研常见问题解答
  3. Pico Neo3 VR Pro 开发新手入门有感(避坑与心得,新手学习必备,瞬移射线传送,移动,射线传送光圈效果,传送指定区域)
  4. 32款图片处理软件介绍
  5. 布谷鸟哈希函数的参数_布谷鸟算法详细讲解
  6. Telerik Reporting.NET,Internet或桌面程序提供交互式报告
  7. 解析、查询身份证号代码
  8. 设置java环境变量path_配置java环境变量path怎么设置
  9. 锐起无盘服务器只能是什么系统,安装锐起无盘客户机系统要注意什么
  10. 第七章 Git操作 7.1利用gitee提交代码