霍夫变换

  • 一、什么是霍夫变换
  • 二、基本原理
    • 1. 用霍夫变换拟合直线
    • 2. 霍夫变换中的难点
  • 三、函数原型
  • 四、应用实例
  • 五、总结

一、什么是霍夫变换

霍夫变换是一种特征检测(feature extraction),被广泛应用在图像分析(image analysis)、计算机视觉(computer vision)以及数位影像处理(digital image processing)。霍夫变换是用来辨别找出物件中的特征,例如:线条。他的算法流程大致如下,给定一个物件、要辨别的形状的种类,算法会在参数空间(parameter space)中执行投票来决定物体的形状,而这是由累加空间(accumulator space)里的局部最大值(local maximum)来决定。
现在广泛使用的霍夫变换是由RichardDuda和PeterHart在公元1972年发明,并称之为广义霍夫变换(generalizedHoughtransform),广义霍夫变换和更早前1962年的PaulHough的专利有关。经典的霍夫变换是侦测图片中的直线,之后,霍夫变换不仅能识别直线,也能够识别任何形状,常见的有圆形、椭圆形。1981年,因为DanaH.Ballard的一篇期刊论文"Generalizing the Hough transform to detect arbitrary shapes",让霍夫变换开始流行于计算机视觉界。

二、基本原理

假如想将标识符集拟合成某个结构模型(例如将点集拟合成直线),亦即将可能位于相同模型上的标识符聚类,方法之一就是:记录每个标识符可能位于的所有的结构模型,并将每个模型记上一票,然后寻找得票最多的结构模型。这种很通用的技术叫做霍夫变换(Hough transform)。为了用霍夫变换拟合某一结构模型,应考察每一个图像标识符,并确定所有“经过该标识符”的结构模型。记录这个模型集——你可以认为这是在投票——对每一个标识符进行重复的操作,并决定投票结果到底代表什么。例如,如果意欲将点集拟合成直线,就考察每个点,投票给所有经过该点的直线,注意,对每个点都进行这种操作。于是,这一条直线(或多条直线)将显现出来,因为它经过许多共线的点从而获得了大量投票。

1. 用霍夫变换拟合直线

直线参数化模型为满足如下方程的点集(x,y)(x,y)(x,y):
xcosθ+ysinθ+r=0xcos\theta + ysin\theta + r = 0 xcosθ+ysinθ+r=0
任何一对 (θ,r)(\theta, r)(θ,r) 值代表一条唯一的直线,其中 rrr 表示原点到直线的垂直距离 (r≥0)(r\ge0)(r≥0), 而 0≤θ≤π0\le \theta \le \pi0≤θ≤π。 (θ,r)(\theta, r)(θ,r) 的值域称为直线空间(line space),它能可视化为一个半无限(指 rrr 无限而 θ\thetaθ 有限)的圆柱体。任意一点都有一簇直线经过,特别地,直线空间中位于曲线 r=−x0cosθ+y0sinθr = -x_0cos\theta + y_0sin\thetar=−x0​cosθ+y0​sinθ 上的点所代表的所有直线都经过点 (x0,y0)(x_0, y_0)(x0​,y0​)。

由于图像尺寸已知,那么必定存在某个值 RRR ,对那些 r>Rr>Rr>R 的直线就不必考虑,因为这些直线离原点太远。这意味着感兴趣的直线形成直线空间平面的有界子集,于是可以用离散化的网格(grid)来描述它。一个网格单元表示一个装有投票的桶,这些桶形成的网格则叫做累积阵列(accumulator array,又称accumulator cells,即累积单元,亦即离散化的直线空间,其中的一点代表直角坐标系中的一条直线)。对于每个点而言,将累积阵列里其对应的投票曲线所经过的每个网格单元都加一票。如果有许多点共线,可推测该直线对应的网格单元就有不少投票。

2. 霍夫变换中的难点

霍夫变换是一种非常通用的算法,既可以用它将平面内的点拟合成圆,也可以用它将三维数据拟合成球体或者椭球体。理论上这都是可行的,但实践中,原始的霍夫变换即使是用来检测直线也很难实用。这是因为有下述几个困难:

  • 网格维度:直线的累积阵列只有两个维度,但圆的累积阵列却有三个维度(圆心位置和半径),对称轴与坐标轴平行的椭圆对应的累积阵列有四维,而一般椭圆却有五维;三维球体有四维,对称轴与坐标轴平行的三维椭球体有七维,而一般的椭球体则有十维。即使是非常简单的结构模型,其累积阵列也可能维数甚高,这需要巨大的存储容量。
  • 量化误差:选择合适的网格尺寸比较困难。太粗的网格会导致许多错误投票,因为差别很大的结构都投票到同一网格中。过细的网格则难以发现结构,因为标识符通常不会严格整齐地位于某结构模型上,致使投票分散到多个不同的网格桶中,于是没有一个网格桶得票较高,因此不易挑出最大值。
  • 噪声:霍夫变换的诱人之处在于它能将间隔较大但都靠近某结构模型的标识符联系起来。但这也是个弱点,因为这很可能导致在大致均匀分布的标识符集中发现许多不错却不实的结构模型。这意味着纹理区域在累积阵列会产生很多峰值,其值可能比要检测的直线对应的峰值还要高。




三、函数原型

四、应用实例

五、总结

计算机视觉中经常需要识别或者定位某些几何图形,比如直线、圆、椭圆,还有其他一些图形。检测直线的霍夫变换提供了在图像中寻找直线的一种算法,是最简单的一种情形,后来发展到检测圆、椭圆、还有一般图形的霍夫变换,其核心思想是把图像中属于某种图形的点集(二维)映射到一个点(可以是高维)上,这个点记录了点集中点的数目,使得程序通过搜索峰值找到该点,这个点就是后面要说到的图形的参数,而该参数的范围就叫做参数空间。霍夫变换不仅能够识别出图像中有无需要检测的图形,而且能够定位到该图像(包括位置、角度等),这就非常有用了。接下来将通过分析从简单到复杂的霍夫变换,导出霍夫变换的实质。

为什么要用极坐标式而不直接用一般形式:ax+by=c(归一化可以去掉参数c),或者其他的如斜截式、截距式呢?首先它们都会遇到奇异情况,比如c=0,斜率=无穷大,其中一个截距=0;再一个是某些形式的参数空间不是闭的,比如斜截式的斜率k,取值范围从0到无穷大,给量化搜索带来了困难。而极坐标式就妙在距离和角度两个参数都是有界的,而且正余弦函数也有界不会发生奇异情况。

直线霍夫变换有两个参数,且这两个参数通过极坐标式相关联,所以程序在投票阶段(图形点集转换到一个点)只需要遍历其中一个,搜索峰值在二维参数空间进行。

   圆:霍夫变换检测圆使用圆的标准式就可以了——

我们发现圆的方程又比直线多了一个参数,这三个参数通过上面的方程相关联,因此在投票阶段需要遍历其中两个,搜索峰值在三维参数空间进行。如果图像比较大,那么这样的遍历搜索是相当耗时的,所以为了满足实时性后来又发展出其他检测圆的霍夫变换,比如概率霍夫变换,结合梯度信息的霍夫变换。

  霍夫变换检测椭圆如果使用椭圆的标准式,那么将会有五个参数,它们通过标准式相关,检测圆就已经相当耗时了,如果再用这中方程形式处理势必失去实际用途。Ballard (1981)一般化了霍夫变换(Hough,1962),利用图形梯度量加快算法速度,形成了广义霍夫变换。透过前面的检测直线、圆、广义霍夫变换,已经可以提取出霍夫变换的一个本质——给出图形的一个描述模式,比如图形点集的方程、函数、表格等,然后利用这个模式加上遍历参数空间,把属于该模式的图形点集投射到参数空间的一个点(实际的离散情况一般不会完美的集中到一点),这个点记录的是图形点数目。广义霍夫变换之所以能处理任意形状的图形并不是找到了可以表示任意图形的方程(这是不可能的),而是使用表的形式描述一种图形,把图形边缘点坐标保存在一张表中,那么该图形就确定下来了,所以其实无论是直线(其实是线段)、圆、椭圆还是其他形状的几何图形,都可以使用同一方法处理,所不同的是这时候的图形是自定义的,是实在的,而代数方程表示的模式是连续的、抽象的,圆的方程只有一种,但自定义的圆却是无穷的,只要你认为它足够圆了就可以。当然两种表示都会有各自的优势和局限。有了表之后就需要找到一种可以把图形点集投射到参数空间的一点的转换算法,例如直线和圆霍夫变换通过方程(函数)及遍历把点集进行投射,使得属于某直线或圆的点集中到一个点;那么仅有一张描述图形边缘坐标点的表如何进行投射呢?我们可以把这张表看作是模板,进行模板匹配,大部分的点匹配成功也就可以理解为这些点都投射到一个点上,不过这时候不需要再搜索参数空间峰值了,这种模式可以认为是参数间没有任何关联,所以是完全的遍历。但有旋转加上缩放的情况模板匹配型的霍夫变换是十分耗时的,也可以想象成因为参数不相关所以增加遍历搜索时间。Ballard (1981)的广义霍夫变换最精妙之处在于为参数增加了两个关联,使得有平移和旋转(无缩放)的情况只需要遍历一个参数,三个参数分别是图形的中心坐标(横纵),旋转角度(相对参考图形),Ballard的算法预先把参考图形边缘点对中心的径向量保存起来,利用待搜索图形边缘点的梯度方向(用相对坐标轴的角度表示)作为索引找到相应的径向量,加上该量后就完成了投射,所以要遍历的参数只有旋转角度,所以说有两个关联。当然如果加上缩放就要遍历两个参数,这也只是和霍夫检测圆的规模一样而已。这种广义霍夫变换的图形表不再是直接保存坐标,而是边缘点的梯度加上径向量,给出了这些量同样的也就能够表示出一种图形了。然而这种广义霍夫变换也是有缺陷的,不少后来者提出了改进方法,这不在本文讨论范围。再来强调一次,霍夫变换就是通过图形的一种表示模式,加上一种转换方法,把图形的点集投射到一个点上以便检测。我们已经能够知道,参数个数越少,需要遍历的参数个数约少(关联越多),参数空间越小则处理速度越快。所以设计一种合理的转换方法非常关键。对于一种图形,在现实世界中可以有多种形变,线性的如:平移、旋转、透视;非线性的如:径变、切变、扭曲。每多考虑一种形变都会增加参数,比如把椭圆看作是圆的透视形变,结果多了两个参数,理论上可以去遍历每一个参数空间,但这不能满足实时性要求,所以参数之间约束(关联)越多则处理速度越快,Ballard的广义霍夫变换就是例子,这就需要发挥主观创造力了。

自动驾驶感知-车道线系列(三)——霍夫变换相关推荐

  1. 自动驾驶感知-车道线系列(一)——车道线基础流程实现

    车道线基础流程实现 OpenCV的安装 图片的读取,展示和保存 Canny边缘检测 ROI_Mask 霍夫变换 离群值过滤 最小二乘拟合 直线绘制 视频流读写 总结 最近开始接触车道线相关的工作,由于 ...

  2. 自动驾驶感知-车道线系列(二)——Canny边缘检测

    Canny边缘检测 前言 一.Canny是什么? 二.算法详细步骤 1. 平滑处理 2. 梯度检测 3. 非极大值抑制 4. 滞后阈值处理 三.函数原型 四.应用实例 五.总结 前言 边缘检测是图像处 ...

  3. 【自动驾驶】车道线拟合算法---最小二乘法拟合直线

    概览 关于自动驾驶车道线拟合算法,常用的方法有B样条.三次样条插值.Ransac.最小二乘法等等. 但是针对于高精度地图的车道线拟合,由于车道线坐标点已知,所以不需要有控制点进行约束,那么B样条.贝塞 ...

  4. 【Python】自动驾驶检测车道线

    检测车道线-- 检测尼玛的车道线,别检测了,除了深度学习,那些什么颜色阈值.梯度阈值.霍夫检测.透视变换都不靠谱-- 反正是老板和师兄们说的--现在车道线检测在深度学习里面已经很成熟了--没必要自己再 ...

  5. 自动驾驶:车道线检测及车位线检测

    文章目录 环境搭建 anaconda 步骤 使用颜色分割 边缘检测方法 霍夫变换 + canny 以下是部分源码 环境搭建 anaconda 步骤 从视频获取每一帧 使每帧灰度 使用Canny算法检测 ...

  6. 自动驾驶——ADAS车道线方程推导

    很长时间,对ADAS中的控制方程不求甚解,在高校读书的时候也没使用过这种方式.而且下述公式在我之前的技术博客提到多次,今日就彻底把它说明白了吧. 对公式(8)的手写推导如下: 上述公式(8)的推导精度 ...

  7. 【camera】自动驾驶感知系统实现(车道线检测和拟合、目标检测与跟踪、道路可行驶区域分割、深度估计、图像视野到BEV空间映射、像平面到地平面映射)

    自动驾驶感知系统实现(车道线检测和拟合.目标检测与跟踪.道路可行驶区域分割.深度估计.图像视野到BEV空间映射.像平面到地平面映射) 项目下载地址:项目下载地址 推理引擎下载地址:推理引擎下载地址 支 ...

  8. Apollo星火计划学习笔记——第六讲上自动驾驶感知基础(I)

    文章目录 1. 感知的作用 2. 常见传感器 2.1 相机 2.1.1 相机的种类 2.1.2 相机的特点 2.2 激光雷达 2.2.1 激光雷达系统构成与方案 2.2.2 激光雷达光源 2.2.3 ...

  9. 自动驾驶感知——环境感知的基本概念

    文章目录 1. 智能汽车概述 1.1 汽车新四化 1.2 智能网联汽车 1.3 SAE J3016自动驾驶分级标准 2. 环境感知定义 2.1 智能网联汽车系统架构 2.2 环境感知定义及对象 3. ...

最新文章

  1. 今天开始搞CentOS 7
  2. python控制nao机器人_python控制nao机器人身体动作实例详解
  3. POJ - 1696 Space Ant(极角排序)
  4. springmvc报错 nested exception is org.mybatis.spring.MyBatisSystemException:
  5. mvn install:install-file将本地一个中央仓库没有的jar包,推到本地仓库----所有依赖不上仓库不能用
  6. 强制删除页面上出错的WebParts
  7. 安卓rom制作教程_【ROM消息】Simplicity官改:MIUI11 9.12.14全机型更新
  8. Microsoft SQL Server 2000的版本区别及选择
  9. 密码算法测试向量——目录
  10. ps 如何制作动态打字图?
  11. pixhawk固定翼起飞逻辑分析
  12. 新能源车电机控制器源代码资料 基于TI芯片的FOC源代码资料
  13. 商业智能 BI 赋能年底的财务分析
  14. linux上执行sql乱码,linux sqlplus乱码怎么办
  15. ZYNQ上无DDR加载应用
  16. 低频数字式相位测试仪的原理与使用
  17. Jquery查找父级添加样式
  18. matlab神经网络报错net.LW{1,1}must be a 7-by-5 matrix解决方法
  19. 解决:miniUSB 驱动无效 设备不识别
  20. u3d honey hex framework 代码解读记录(四)

热门文章

  1. 图像形态学运算之图像开闭运算 含python实现
  2. 开源媒体标注系统cvat
  3. 静态RAM六个MOS管组成1位结构图
  4. MFC_选择目录对话框_选择文件对话框_指定目录遍历文件
  5. 51Nod 1873 - 初中的算术(JAVA)
  6. DirectX (13) 粒子系统
  7. [转载] python:numpy数学函数和逻辑函数
  8. [转载] Python学习之Numpy
  9. [转载] [556]python实现神经网络
  10. [转载] java中对象作为参数传递给一个方法,到底是值传递,还是引用传递