当前位置:网站首页 > 技术博客 > 正文

霍夫变换在图像分割中的应用



---恢复内容开始---

@[toc]

# 1 简述

霍夫变换是一个经典的特征提取技术,本文主要说的是霍夫线/圆变换,即从图像中获取直线与圆,同时需要对图像进行二值化操作,效果如下。

![这里写图片描述](https://www.mushiming.com/uploads//28/563cc0b899afefe1.jpg)

霍夫变换目的通过投票程序在特定类型的形状内找到对象的不完美示例,这个投票程序是在一个参数空间中进行的,在这个参数空间中,候选对象被当作所谓的累加器空间中的局部最大值来获得,所述累加器空间由用于计算霍夫变换的算法明确的构建,霍夫变换不仅能够识别出图像中有无需要检测的图形,而且能够定位到该图像(包括位置、角度等),有标准霍夫变换,多尺度霍夫变换,统计概率霍夫变换3种较为经典的方法,主要优点是

能容忍特征边界描述中的间隙,并且相对不受图像噪声的影响。

  直线的方程形式有截距式,斜截式,一般式,点斜式等,但是这些形式都有“奇异”情况,其中一个截距为0,斜率为0, c=0(通常把c除到等式左面,减少一个参数的搜索),另外某些形式的参数空间不是闭的,比如斜截式的斜率k,取值范围从0到无穷大,给量化搜索带来了困难。所以在霍夫线变换中采用了如下方程的形式:

  对于直线来说,可以将图像的每一条直线与一对参数相关联,这个参数平面有时被称为霍夫空间,用于二维直线的集合,因此,对于某一指定的点,不同的代表了不同的直线,我们把之间的关系通过图像表示出来——固定一个点(3,4),角度取[0,2]时,的范围取值情况:
这里写图片描述
会发现曲线的形状类似一条正弦曲线,通常越大,正弦曲线的振幅越大,反而就会越小。




  举一个具体的例子,来体现霍夫变换的流程同时更深的理解一下该算法(此例子摘取某博客,下文会给出所有参考博客的链接)

  1. 读取原始图像,并转换成灰度图,利用阈值分割或者边缘检测算子转换成二值化边缘图像
  2. 初始化霍夫空间, 令所有
  3. 对于每一个像素点,在参数空间中找出所有满足的对,然后令
  4. 统计所有的大小,取出的参数(是所设的阈值),从而得到一条直线。
  5. 将上述流程取出的直线,确定与其相关线段的起始点与终止点(有一些算法,如蝴蝶形状宽度,峰值走廊之类)
  1. 随机抽取图像中的一个特征点,即边缘点,如果该点已经被标定为是某一条直线上的点,则继续在剩下的边缘点中随机抽取一个边缘点,直到所有边缘点都抽取完了为止;
  2. 对该点进行霍夫变换,并进行累加和计算;
  3. 选取在霍夫空间内值最大的点,如果该点大于阈值的,则进行步骤4,否则回到步骤1;
  4. 根据霍夫变换得到的最大值,从该点出发,沿着直线的方向位移,从而找到直线的两个端点;
  5. 计算直线的长度,如果大于某个阈值,则被认为是好的直线输出,回到步骤1。
 
  

第一个参数,InputArray类型的image,输入图像,即源图像,需为8位的单通道二进制图像,可以将任意的源图载入进来后由函数修改成此格式后,再填在这里。

第二个参数,InputArray类型的lines,经过调用HoughLines函数后储存了霍夫线变换检测到线条的输出矢量。每一条线由具有两个元素的矢量表示,其中,是离坐标原点((0,0)(也就是图像的左上角)的距离。 是弧度线条旋转角度(0垂直线,π/2水平线)。

第三个参数,double类型的rho,以像素为单位的距离精度。另一种形容方式是直线搜索时的进步尺寸的单位半径。PS:Latex中/rho就表示 。

第四个参数,double类型的theta,以弧度为单位的角度精度。另一种形容方式是直线搜索时的进步尺寸的单位角度

第五个参数,int类型的threshold,累加平面的阈值参数,即识别某部分为图中的一条直线时它在累加平面中必须达到的值。大于阈值threshold的线段才可以被检测通过并返回到结果中。

第六个参数,double类型的srn,有默认值0。对于多尺度的霍夫变换,这是第三个参数进步尺寸rho的除数距离。粗略的累加器进步尺寸直接是第三个参数rho,而精确的累加器进步尺寸为rho/srn。

第七个参数,double类型的stn,有默认值0,对于多尺度霍夫变换,srn表示第四个参数进步尺寸的单位角度theta的除数距离。且如果srn和stn同时为0,就表示使用经典的霍夫变换。否则,这两个参数应该都为正数。

 
  

第一个参数,InputArray类型的image,输入图像,即源图像,需为8位的单通道二进制图像,可以将任意的源图载入进来后由函数修改成此格式后,再填在这里。

第二个参数,InputArray类型的lines,经过调用HoughLinesP函数后后存储了检测到的线条的输出矢量,每一条线由具有四个元素的矢量表示,其中,和是每个检测到的线段的结束点。

第三个参数,double类型的rho,以像素为单位的距离精度。另一种形容方式是直线搜索时的进步尺寸的单位半径。

第四个参数,double类型的theta,以弧度为单位的角度精度。另一种形容方式是直线搜索时的进步尺寸的单位角度

第五个参数,int类型的threshold,累加平面的阈值参数,即识别某部分为图中的一条直线时它在累加平面中必须达到的值。大于阈值threshold的线段才可以被检测通过并返回到结果中。

第六个参数,double类型的minLineLength,有默认值0,表示最低线段的长度,比这个设定参数短的线段就不能被显现出来。

第七个参数,double类型的maxLineGap,有默认值0,允许将同一行点与点之间连接起来的最大的距离。

此部分参考几位博主的博客,更改了里面一些我认为不太对的地方以及加上了一些自己的理解还有就是一些没有解释的地方

阅读源码之后,发现源码确实细节方面做得比较好,无论是内存方面,还是效率方面,包括一些小细节,比如避免除法,等等。所以源码值得借鉴与反复参考,具体解释如下。

 
  

这个代码与之前HoughLines风格完全不同,个人感觉没有之前HoughLines的优美,同时小优化也并不是特别注意,不过实现算法思想的大体思路还是值得我这个初学者借鉴的,但是里面那个shitf操作没看懂,不是很理解,如果有同学会的话,希望解释一下

 
  

霍夫圆变换和霍夫线变换的原理类似。霍夫线变换是两个参数(r,θ),霍夫圆需要三个参数,圆心的x,y坐标和圆的半径,他的方程表达式为,按照标准霍夫线变换思想,在xy平面,三个点在同一个圆上,则它们对应的空间曲面相交于一点(即点(a,b,c))。故我们如果知道一个边界上的点的数目,足够多,且这些点与之对应的空间曲面相交于一点。则这些点构成的边界,就接近一个圆形。上述描述的是标准霍夫圆变换的原理,由于三维空间的计算量大大增大的原因, 标准霍夫圆变化很难被应用到实际中。

HoughCircles函数实现了圆形检测,它使用的算法也是改进的霍夫变换——2-1霍夫变换(21HT)。也就是把霍夫变换分为两个阶段,从而减小了霍夫空间的维数。第一阶段用于检测圆心,第二阶段从圆心推导出圆半径。检测圆心的原理是圆心是它所在圆周所有法线的交汇处,因此只要找到这个交点,即可确定圆心,该方法所用的霍夫空间与图像空间的性质相同,因此它仅仅是二维空间。检测圆半径的方法是从圆心到圆周上的任意一点的距离(即半径)是相同,只要确定一个阈值,只要相同距离的数量大于该阈值,我们就认为该距离就是该圆心所对应的圆半径,该方法只需要计算半径直方图,不使用霍夫空间。圆心和圆半径都得到了,那么通过公式1一个圆形就得到了。从上面的分析可以看出,2-1霍夫变换把标准霍夫变换的三维霍夫空间缩小为二维霍夫空间,因此无论在内存的使用上还是在运行效率上,2-1霍夫变换都远远优于标准霍夫变换。但该算法有一个不足之处就是由于圆半径的检测完全取决于圆心的检测,因此如果圆心检测出现偏差,那么圆半径的检测肯定也是错误的。

version 1:

2-1霍夫变换的具体步骤为:

version 2:

第一阶段:检测圆心

 
  
 
  
 
  

---恢复内容结束---

@

  直线的方程形式有截距式,斜截式,一般式,点斜式等,但是这些形式都有“奇异”情况,其中一个截距为0,斜率为0, c=0(通常把c除到等式左面,减少一个参数的搜索),另外某些形式的参数空间不是闭的,比如斜截式的斜率k,取值范围从0到无穷大,给量化搜索带来了困难。所以在霍夫线变换中采用了如下方程的形式:

  对于直线来说,可以将图像的每一条直线与一对参数相关联,这个参数平面有时被称为霍夫空间,用于二维直线的集合,因此,对于某一指定的点,不同的代表了不同的直线,我们把之间的关系通过图像表示出来——固定一个点(3,4),角度取[0,2]时,的范围取值情况:
这里写图片描述
会发现曲线的形状类似一条正弦曲线,通常越大,正弦曲线的振幅越大,反而就会越小。




  举一个具体的例子,来体现霍夫变换的流程同时更深的理解一下该算法(此例子摘取某博客,下文会给出所有参考博客的链接)

  1. 读取原始图像,并转换成灰度图,利用阈值分割或者边缘检测算子转换成二值化边缘图像
  2. 初始化霍夫空间, 令所有
  3. 对于每一个像素点,在参数空间中找出所有满足的对,然后令
  4. 统计所有的大小,取出的参数(是所设的阈值),从而得到一条直线。
  5. 将上述流程取出的直线,确定与其相关线段的起始点与终止点(有一些算法,如蝴蝶形状宽度,峰值走廊之类)
  1. 随机抽取图像中的一个特征点,即边缘点,如果该点已经被标定为是某一条直线上的点,则继续在剩下的边缘点中随机抽取一个边缘点,直到所有边缘点都抽取完了为止;
  2. 对该点进行霍夫变换,并进行累加和计算;
  3. 选取在霍夫空间内值最大的点,如果该点大于阈值的,则进行步骤4,否则回到步骤1;
  4. 根据霍夫变换得到的最大值,从该点出发,沿着直线的方向位移,从而找到直线的两个端点;
  5. 计算直线的长度,如果大于某个阈值,则被认为是好的直线输出,回到步骤1。
 
  

第一个参数,InputArray类型的image,输入图像,即源图像,需为8位的单通道二进制图像,可以将任意的源图载入进来后由函数修改成此格式后,再填在这里。

第二个参数,InputArray类型的lines,经过调用HoughLines函数后储存了霍夫线变换检测到线条的输出矢量。每一条线由具有两个元素的矢量表示,其中,是离坐标原点((0,0)(也就是图像的左上角)的距离。 是弧度线条旋转角度(0垂直线,π/2水平线)。

第三个参数,double类型的rho,以像素为单位的距离精度。另一种形容方式是直线搜索时的进步尺寸的单位半径。PS:Latex中/rho就表示 。

第四个参数,double类型的theta,以弧度为单位的角度精度。另一种形容方式是直线搜索时的进步尺寸的单位角度

第五个参数,int类型的threshold,累加平面的阈值参数,即识别某部分为图中的一条直线时它在累加平面中必须达到的值。大于阈值threshold的线段才可以被检测通过并返回到结果中。

第六个参数,double类型的srn,有默认值0。对于多尺度的霍夫变换,这是第三个参数进步尺寸rho的除数距离。粗略的累加器进步尺寸直接是第三个参数rho,而精确的累加器进步尺寸为rho/srn。

第七个参数,double类型的stn,有默认值0,对于多尺度霍夫变换,srn表示第四个参数进步尺寸的单位角度theta的除数距离。且如果srn和stn同时为0,就表示使用经典的霍夫变换。否则,这两个参数应该都为正数。

 
  

第一个参数,InputArray类型的image,输入图像,即源图像,需为8位的单通道二进制图像,可以将任意的源图载入进来后由函数修改成此格式后,再填在这里。

第二个参数,InputArray类型的lines,经过调用HoughLinesP函数后后存储了检测到的线条的输出矢量,每一条线由具有四个元素的矢量表示,其中,和是每个检测到的线段的结束点。

第三个参数,double类型的rho,以像素为单位的距离精度。另一种形容方式是直线搜索时的进步尺寸的单位半径。

第四个参数,double类型的theta,以弧度为单位的角度精度。另一种形容方式是直线搜索时的进步尺寸的单位角度

第五个参数,int类型的threshold,累加平面的阈值参数,即识别某部分为图中的一条直线时它在累加平面中必须达到的值。大于阈值threshold的线段才可以被检测通过并返回到结果中。

第六个参数,double类型的minLineLength,有默认值0,表示最低线段的长度,比这个设定参数短的线段就不能被显现出来。

第七个参数,double类型的maxLineGap,有默认值0,允许将同一行点与点之间连接起来的最大的距离。

此部分参考几位博主的博客,更改了里面一些我认为不太对的地方以及加上了一些自己的理解还有就是一些没有解释的地方

阅读源码之后,发现源码确实细节方面做得比较好,无论是内存方面,还是效率方面,包括一些小细节,比如避免除法,等等。所以源码值得借鉴与反复参考,具体解释如下。

 
  

这个代码与之前HoughLines风格完全不同,个人感觉没有之前HoughLines的优美,同时小优化也并不是特别注意,不过实现算法思想的大体思路还是值得我这个初学者借鉴的,但是里面那个shitf操作没看懂,不是很理解,如果有同学会的话,希望解释一下

 
  

霍夫圆变换和霍夫线变换的原理类似。霍夫线变换是两个参数(r,θ),霍夫圆需要三个参数,圆心的x,y坐标和圆的半径,他的方程表达式为,按照标准霍夫线变换思想,在xy平面,三个点在同一个圆上,则它们对应的空间曲面相交于一点(即点(a,b,c))。故我们如果知道一个边界上的点的数目,足够多,且这些点与之对应的空间曲面相交于一点。则这些点构成的边界,就接近一个圆形。上述描述的是标准霍夫圆变换的原理,由于三维空间的计算量大大增大的原因, 标准霍夫圆变化很难被应用到实际中。

HoughCircles函数实现了圆形检测,它使用的算法也是改进的霍夫变换——2-1霍夫变换(21HT)。也就是把霍夫变换分为两个阶段,从而减小了霍夫空间的维数。第一阶段用于检测圆心,第二阶段从圆心推导出圆半径。检测圆心的原理是圆心是它所在圆周所有法线的交汇处,因此只要找到这个交点,即可确定圆心,该方法所用的霍夫空间与图像空间的性质相同,因此它仅仅是二维空间。检测圆半径的方法是从圆心到圆周上的任意一点的距离(即半径)是相同,只要确定一个阈值,只要相同距离的数量大于该阈值,我们就认为该距离就是该圆心所对应的圆半径,该方法只需要计算半径直方图,不使用霍夫空间。圆心和圆半径都得到了,那么通过公式1一个圆形就得到了。从上面的分析可以看出,2-1霍夫变换把标准霍夫变换的三维霍夫空间缩小为二维霍夫空间,因此无论在内存的使用上还是在运行效率上,2-1霍夫变换都远远优于标准霍夫变换。但该算法有一个不足之处就是由于圆半径的检测完全取决于圆心的检测,因此如果圆心检测出现偏差,那么圆半径的检测肯定也是错误的。

version 1:

2-1霍夫变换的具体步骤为:

version 2:

第一阶段:检测圆心

 
  
 
  
 
  

                            

  • 上一篇: seo案例视频教程
  • 下一篇: clr via c
  • 版权声明


    相关文章:

  • seo案例视频教程2025-05-30 23:01:05
  • 异步fifo的verilog代码2025-05-30 23:01:05
  • vc++6.0断点调试2025-05-30 23:01:05
  • 简述makefile的作用2025-05-30 23:01:05
  • java注解@autowired2025-05-30 23:01:05
  • clr via c2025-05-30 23:01:05
  • dbcp配置数据源2025-05-30 23:01:05
  • seq2seq decoder2025-05-30 23:01:05
  • 线程中通信2025-05-30 23:01:05
  • 游标sql语句2025-05-30 23:01:05