霍夫变换

原理简介 霍夫变换(Hough Transform) 霍夫变换是图像处理中从图像中识别几何形状的基本方法之一,应用很广泛,也有很多改进算法。最基本的霍夫变换是从黑白图像中检测直线(线段)。

1详细内容

我们先看这样一个问题:设已知一黑白图像上画了一条直线,要求出这条直线所在的位置。我们知道,直线的方程可以用y=k*x+b 来表示,其中k和b是参数,分别是斜率和截距。过某一点(x0,y0)的所有直线的参数都会满足方程y0=kx0+b。即点(x0,y0)确定了一组直线。方程y0=kx0+b在参数k--b平面上是一条直线,(你也可以是方程b=-x0*k+y0对应的直线)。这样,图像x--y平面上的一个前景像素点就对应到参数平面上的一条直线。我们举个例子说明解决前面那个问题的原理。设图像上的直线是y=x, 我们先取上面的三个点:A(0,0), B(1,1), C(2,2)。可以求出,过A点的直线的参数要满足方程b=0, 过B点的直线的参数要满足方程1=k+b, 过C点的直线的参数要满足方程2=2k+b, 这三个方程就对应着参数平面上的三条直线,而这三条直线会相交于一点(k=1,b=0)。 同理,原图像上直线y=x上的其它点(如(3,3),(4,4)等) 对应参数平面上的直线也会通过点(k=1,b=0)。

2应用

这个性质就为我们解决问题提供了方法:

首先,我们初始化一块缓冲区,对应于参数平面,将其所有数据置为0.

对于图像上每一前景点,求出参数平面对应的直线,把这直线上的所有点的值都加1。最后,找到参数平面上最大点的位置,这个位置就是原图像上直线的参数。上面就是霍夫变换的基本思想。就是把图像平面上的点对应到参数平面上的线,最后通过统计特性来解决问题。假如图像平面上有两条直线,那么最终在参数平面上就会看到两个峰值点,依此类推。

在实际应用中,y=k*x+b形式的直线方程没有办法表示x=c形式的直线(这时候,直线的斜率为无穷大)。所以实际应用中,是采用参数方程p=x*cos(theta)+y*sin(theta)。这样,图像平面上的一个点就对应到参数p---theta平面上的一条曲线上。其它的还是一样。

3应用实例1

在看下面一个问题:我们要从一幅图像中检测出半径已知的圆形来。这个问题比前一个还要直观。我们可以取和图像平面一样的参数平面,以图像上每一个前景点为圆心,以已知的半径在参数平面上画圆,并把结果进行累加。最后找出参数平面上的峰值点,这个位置就对应了图像上的圆心。在这个问题里,图像平面上的每一点对应到参数平面上的一个圆。

把上面的问题改一下,假如我们不知道半径的值,而要找出图像上的圆来。这样,一个办法是把参数平面扩大称为三维空间。就是说,参数空间变为x--y--R三维,对应圆的圆心和半径。

图像平面上的每一点就对应于参数空间中每个半径下的一个圆,这实际上是一个圆锥。最后当然还是找参数空间中的峰值点。不过,这个方法显然需要大量的内存,运行速度也会是很大问题。有什么更好的方法么?我们前面假定的图像都是黑白图像(2值图像),实际上这些2值图像多是彩色或灰度图像通过边缘提取来的。我们前面提到过,图像边缘除了位置信息,还有方向信息也很重要,这里就用上了。根据圆的性质,圆的半径一定在垂直于圆的切线的直线上,也就是说,在圆上任意一点的法线上。这样,解决上面的问题,我们仍采用2维的参数空间,对于图像上的每一前景点,加上它的方向信息,都可以确定出一条直线,圆的圆心就在这条直线上。这样一来,问题就会简单了许多。

4应用实例2

接下来还有许多类似的问题,如检测出椭圆,正方形,长方形,圆弧等等。这些方法大都类似,关键就是需要熟悉这些几何形状的数学性质。霍夫变换的应用是很广泛的,比如我们要做一个支票识别的任务,假设支票上肯定有一个红颜色的方形印章,我们可以通过霍夫变换来对这个印章进行快速定位,在配合其它手段进行其它处理。霍夫变换由于不受图像旋转的影响,所以很容易的可以用来进行定位。

霍夫变换有许多改进方法,一个比较重要的概念是广义霍夫变换,它是针对所有曲线的,用处也很大。就是针对直线的霍夫变换也有很多改进算法,比如前面的方法我们没有考虑图像上的这一直线上的点是否连续的问题,这些都要随着应用的不同而有优化的方法。

顺便说一句,搞图像处理这一行,在理论方面,有几本杂志是要看的,自然是英文杂志,中文期刊好像没有专门的图像处理期刊,当然也有不少涉及这方面的期刊,但实事求是来说,的确比英文杂志水平差很多。

‘IEEE Transactions on Pattern Recognition And Machine Intelligence’

‘IEEE Transactions on Image Processing’

是最重要的两本,其它的如ICCV、CVPR、ECCV、NIPS、BMVC等的会议文章也非常好

(1)理论之通俗理解:

1.在图像中检测直线的问题,其实质是找到构成直线的所有的像素点。那么问题就是从找到直线,变成找到符合y=mx+c的所有(x,y)的点的问题。

2.进行坐标系变化y=mx+c,变成c=-xm+b。直线上的点(x1,y1),在转换坐标系后为一条直线。这个原理应该是高中的。

3.直线上每一个点在MC坐标系中都表现为直线,而且,这些直线都相交于一个点,(m,c)。找到所有点的问题,转变为寻找直线的问题。

4.对于图像中的每一个点,在MC坐标系中对应着很多的直线。找到直线的交点,就对应着找到图像中的直线。

实际在使用这一原理的时候,不是采用直线的斜率和截距公式,而是用

如何实现:

1. 将θ角在-90度到90度的范围里,划分为很多区间,对所有的像素点(x,y)在所有θ角的时候,求出ρ.从而累加ρ值出现的次数。高于某个阈值的ρ就是一个直线。

2. 这个过程就类似于如下一个二维的表格,横坐标就是θ角,ρ就是到直线的最短距离。

横坐标θ不断变换,对于所有的不为0的像素点,计算出ρ,找到ρ在坐标(θ,ρ)的位置累加1.

  1. 上图中局部最大的就是找到的直线的θ和ρ的值。

(2) 具体代码片段

   for( ang = 0, n = 0; n < numangle; ang += theta, n++ )
   {
       tabSin[n] = (float)(sin(ang) * irho);
       tabCos[n] = (float)(cos(ang) * irho);
   }

// stage 1. fill accumulator
   for( i = 0; i < height; i++ )
       for( j = 0; j < width; j++ )
       {
           if( image[i * step + j] != 0 )
               for( n = 0; n < numangle; n++ )
               {
                   r = cvRound( j * tabCos[n] + i * tabSin[n] );
                   r += (numrho - 1) / 2;
                   accum[(n+1) * (numrho+2) + r+1]++;
               }
       }

// stage 2. find local maximums
   for( r = 0; r < numrho; r++ )
       for( n = 0; n < numangle; n++ )
       {
           int base = (n+1) * (numrho+2) + r+1;
           if( accum[base] > threshold &&
               accum[base] > accum[base - 1] && accum[base] >= accum[base + 1] &&
               accum[base] > accum[base - numrho - 2] && accum[base] >= accum[base + numrho + 2] )
               sort_buf[total++] = base;
       }

// stage 3. sort the detected lines by accumulator value
   icvHoughSortDescent32s( sort_buf, total, accum );

// stage 4. store the first min(total,linesMax) lines to the output buffer
   linesMax = MIN(linesMax, total);
   scale = 1./(numrho+2);
   for( i = 0; i < linesMax; i++ )
   {
       CvLinePolar line;
       int idx = sort_buf[i];
       int n = cvFloor(idx*scale) - 1;
       int r = idx - (n+1)*(numrho+2) - 1;
       line.rho = (r - (numrho - 1)*0.5f) * rho;
       line.angle = n * theta;
       cvSeqPush( lines, &line );
   }

霍夫变换,布布扣,bubuko.com

时间: 2024-10-10 17:41:28

霍夫变换的相关文章

霍夫变换理解

霍夫变换可以用于直线检测,圆检测等.我需要解决的问题是二维点云线特征提取,相关文献上说霍夫变换可以提取,决定深入学习一下. 先上两张图:直线的表达式采用极坐标表示ρ=xcosθ+ysinθ,关于ρ和θ的几何意义如图.证明下面的图可以说明. 因此过某一点A的极坐标方程可以表示所有过A点的直线族. 同理过某一点B的极坐标方程可以表示过有过点B的直线族.两个直线族的集合就是同时过A点和B点的直线. 霍夫变换首先将极坐标系的纵横坐标轴ρ和θ离散化,构成一个网格m*n的数组.这样对栅格图像的每一个非0点进

学习 opencv---(13)opencv霍夫变换:霍夫线变换,霍夫圆变换

在本篇文章中,我们将一起学习opencv中霍夫变换相关的知识点,以及了解opencv中实现霍夫变换的HoughLines,HoughLinesP函数的使用方法,实现霍夫圆变换的HoughCircles函数的使用方法. 先尝鲜一下其中一个示例程序的运行截图: 一.引言 在图像处理和计算机视觉领域中,如何从当前的图像中提取所需要的特征信息是图像识别的关键所在.在许多应用场合中需要快速准确的检测出直线或者圆.其中一种非常有效的解决问题的方法是霍夫(Hough)变换,其为图像处理中从图像识别几何形状的基

灰度图像--图像分割 霍夫变换(Hough Transform)--直线

学习DIP第50天 转载请标明本文出处:http://blog.csdn.net/tonyshengtan ,出于尊重文章作者的劳动,转载请标明出处!文章代码已托管,欢迎共同开发:https://github.com/Tony-Tan/DIPpro 开篇废话 废话开始,要过年了,到处人心惶惶,沉下心写篇博客,下一篇就等农历新年以后了.马上新年了,希望自己在新年能提高技术,找到一份图像处理的好工作,也希望大家都能学习到更多的知识,做自己喜欢做的事情. 以前基本每天都写博客,坚持了三个月感觉确实有提

OpenCV笔记(十八)——使用霍夫变换检测圆圈

这些笔记的最初,我是以接近于源码分析的形式来梳理自己学习OpenCV的过程. 然而写下来,一是执行力,二是时间的问题,确实越写越马虎了.用我老师的话:观其大略了. 但是,暂时就这么写着吧. 在笔记<十七>中,我们简单地谈到了霍夫变换检测直线的原理,就是判断相邻像素点的值(x, y)对应的r-theta曲线是否能够相交,如果有足够多的相邻的像素点的曲线相交,我们就认为这些相邻的像素点构成一条直线. 圆圈亦然,只是把直线的方程替换成了圆的方程.除了极坐标的r,多了两个变量:Xcenter和Ycen

图像处理之霍夫变换(直线检測算法)

图像处理之霍夫变换(直线检測算法) 霍夫变换是图像变换中的经典手段之中的一个,主要用来从图像中分离出具有某种同样特征的几何 形状(如,直线,圆等).霍夫变换寻找直线与圆的方法相比与其他方法能够更好的降低噪 声干扰.经典的霍夫变换经常使用来检測直线,圆,椭圆等. 霍夫变换算法思想: 以直线检測为例,每一个像素坐标点经过变换都变成都直线特质有贡献的统一度量,一个简单 的样例例如以下:一条直线在图像中是一系列离散点的集合,通过一个直线的离散极坐标公式, 能够表达出直线的离散点几何等式例如以下: X *

Opencv3编程入门笔记(4)腐蚀、膨胀、开闭运算、漫水填充、金字塔、阈值化、霍夫变换

19      腐蚀erode.膨胀dilate 腐蚀和膨胀是针对图像中的白色部分(高亮部分)而言的,不是黑色的.除了输入输出图像外,还需传入模板算子element,opencv中有三种可以选择:矩形MORPH_RECT,交叉形MORPH_CROSS,椭圆形MORPH_ELLIPSE.Matlab中会有更多一点的模板. 例如: Mat element = getStructuringElement(MORPH_RECT,Size(15,15)); erode(srcImage,dstImage,

霍夫变换(一)霍夫线性变换

霍夫变换(一)线性霍夫变换 概述:霍夫变换(Hough Transform)是图像处理中的一种特征提取技术,该过程在一个参数空间中通过计算累计结果的局部最大值得到一个符合该特定形状的集合作为霍夫变换结果.霍夫线变换和霍夫圆变换两种. 霍夫线变换: OpenCv中的霍夫线变换: <1>标准霍夫变换(StandardHough Transform,SHT),由HoughLines函数调用. <2>多尺度霍夫变换(Multi-ScaleHough Transform,MSHT),由Hou

霍夫变换Hough

http://blog.csdn.net/sudohello/article/details/51335237 霍夫变换Hough 霍夫变换(Hough)是一个非常重要的检测间断点边界形状的方法.它通过将图像坐标空间变换到参数空间,来实现直线与曲线的拟合. 1.直线检测 1.1 直线坐标参数空间 在图像x?y坐标空间中,经过点(xi,yi)的直线表示为: yi=axi+b(1) 其中,参数a为斜率,b为截矩. 通过点(xi,yi)的直线有无数条,且对应于不同的a和b值. 如果将xi和yi视为常数

霍夫变换提取圆心坐标,并拟合直线

<span style="font-family:Microsoft YaHei;font-size:14px;">#include <cmath> #include <opencv2/opencv.hpp> using namespace cv; using namespace std; const int kvalue = 15;//双边滤波邻域大小 int main() { Mat src_color = imread("1.png&