《opencv学习笔记》-- 霍夫变换

目录

霍夫线变换

霍夫圆变换 


霍夫变换是图像处理中的一种特征提取技术,该过程在一个参数空间中通过计算累计结果的局部最大值得到一个符合该特定形状的集合作为霍夫变换结果。
霍夫变换分为霍夫线变换霍夫圆变换两种。

霍夫线变换

霍夫线变换是一种用来寻找直线的方法。在使用霍夫线变换之前, 首先要对图像进行边缘检测的处理,也即霍夫线变换的直接输入只能是边缘二值图像。

三种不同的霍夫线变换:

        标准霍夫变换(SHT):             由HoughLines函数调用。

        多尺度霍夫变换(MSH):         由HoughLines函数调用。

        累计概率霍夫变换(PPHT):    由HoughLinesP函数调用。

霍夫线变换的原理:

1、一条直线在图像二维空间可由两个变量表示. 如:

(1)在笛卡尔坐标系:可由参数斜率和截距(m,b)表示。

(2)在极坐标系:可由参数极径和极角(r,θ)表示。

对于霍夫变换, 将采用第二种方式极坐标系来表示直线. 因此, 直线的表达式可为:

   简化后  

2、对于点(x0, y0),可以通过这个点的一组直线统一定义为:

         rθ= x0 * cosθ + y0 * sinθ

        每一对(rθ,θ)代表一条通过点(x0,y0)的直线。

3、对于一个给定点(x0,y0),在极坐标对极径和极角平面绘制出所有通过它的直线将得到一条正弦曲线。例如:对于给定点 x0 = 8, y0 = 6 可以绘出:

         只绘出满足下列条件的点 r > 0 和 0 < θ < 

4、对于图像的所有点进行上述操作,得到曲线图集合。如果两个不同点进行上述操作后得到的曲线在平面θ-r相交,说明通过同一条直线。例如,接上面的例子继续对点x1=9,y1=4和x2=12,y2=3绘图如下:

这三条曲线在平面相交于点0.925,  9.6,坐标表示的是参数对θ-r或者是说点(x0, y0)、(x1, y1)和(x2, y2)组成的平面内的直线,所以其实是计算平面内的每个点的每个角度的距离,绘制成曲线后,如果3个点交叉了,那么3个点就是在一条直线上。 

5、以上得出,一条直线能够通过在平面θ - r寻找交于一点的曲线数量来检测。而越多曲线交于一点也就意味着这个交点表示的直线由更多的点组成。一般来说,可以通过设置直线上点的阈值来定义多少条曲线交于一点我们才认为检测到了一条直线。

6、霍夫线变换:追踪图像中每个点对应曲线间的交点. 如果交于一点的曲线的数量超过了阈值, 那么可以认为这个交点所代表的参数对(θ,rθ) 在原图像中为一条直线。

void HoughLines( InputArray image, OutputArray lines, double rho, 
                 double theta, int threshold, double srn = 0, 
                 double stn = 0, double min_theta = 0, 
                 double max_theta = CV_PI );

参数1,InputArray类型的image,输入图像,即源图像,需为8位的单通道二进制图像,

             可以将任意的源图载入进来后由函数修改成此格式后,再填入。

参数2,InputArray类型的lines,经过调用HoughLines函数后储存了霍夫线变换检测到线条的

            输出矢量。每一条线由具有两个元素的矢量(ρ,  θ表示,其中,ρ是离坐标原点

            (0,0)(也就是图像的左上角)的距离。θ 是弧度线条旋转角度(0 --- 垂直线,

             π/2 ---- 水平线)。

参数3,double类型的rho,以像素为单位的距离精度。

             另一种形容方式是直线搜索时的进步尺寸的单位半径。PS: Latex中/rho就表示ρ

参数4,double类型的theta,以弧度为单位的角度精度。

             另一种形容方式是直线搜索时的进步尺寸的单位角度。

参数5,int类型的threshold,累加平面的阈值参数,即识别某部分为图中的一条直线时它在

            累加平面中必须达到的值。大于阈值threshold的线段才可以被检测通过并返回到结果

            中。

参数6,double类型的srn,有默认值0。对于多尺度的霍夫变换,这是第三个参数进步尺寸

             rho的除数距离。粗略的累加器进步尺寸直接是第三个参数rho,而精确的累加器进步

             尺寸为rho/srn。

参数7,double类型的stn,有默认值0,对于多尺度霍夫变换,srn表示第四个参数进步尺寸

            的单位角度theta的除数距离。且如果srn和stn同时为0,就表示使用经典的霍夫变

             换。否则,这两个参数应该都为正数。

参数8,double类型的min_theta,对于标准和多尺度霍夫变换,检查线的最小角度。

             必须介于 0 和 max_theta 之间。
参数9,double类型的max_theta,对于标准和多尺度霍夫变换,检查线的最大角度。

             必须介于 min_theta 和 CV_PI 之间。

可以通过调节line(dstImage, pt1, pt2, Scalar(55,100,195), 1, CV_AA);

Scalar(55,100,195)参数中G、B、R颜色值的数值,得到想要的线条颜色。

函数cvRound,cvFloor,cvCeil 都是将输入浮点数转换成整数:

cvRound():返回跟参数最接近的整数值,即四舍五入;

cvFloor():  返回不大于参数的最大整数值,即向下取整;

cvCeil():    返回不小于参数的最小整数值,即向上取整;

void HoughLinesP(InputArray image,  OutputArray lines,  double rho,
                 double theta, int threshold, double minLineLength = 0,  
                 double maxLineGap = 0 )

在HoughLines的基础上末尾加了一个代表Probabilistic(概率)的P,表明它可以采用累计概率霍夫变换(PPHT)来找出二值图像中的直线。

参数1,InputArray类型的image,输入图像,即源图像,需为8位的单通道二进制图像,

             可以将任意的源图载入进来后由函数修改成此格式后,再填入。

参数2,InputArray类型的lines,经过调用HoughLinesP函数后存储了检测到的线条的输出

           矢量,每一条线由具有四个元素的矢量(x1,y1, x2, y2)表示,其中,(x1, y1)

           和(x2, y2)是每个检测到的线段的结束点。

参数3,double类型的rho,以像素为单位的距离精度

             另一种形容方式是直线搜索时的进步尺寸的单位半径。

参数4,double类型的theta,以弧度为单位的角度精度

             另一种形容方式是直线搜索时的进步尺寸的单位角度。

参数5,int类型的threshold,累加平面的阈值参数,即识别某部分为图中的一条直线时它在

            累加平面中必须达到的值。大于阈值threshold的线段才可以被检测通过并返回到结果

            中。

参数6,double类型的minLineLength,有默认值0,表示最低线段的长度,比这个设定参数

             短的线段就不能被显现出来。

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

             的距离。

霍夫圆变换 

霍夫圆变换,其实是针对圆,是用来寻找圆的方法。

对直线来说, 一条直线能由参数极径极角(r,θ)表示。而对圆, 需要三个参数来表示一个圆(圆心(x,  y), 半径r)。

通过霍夫梯度法解决圆变换问题。

霍夫梯度法的原理:

【1】首先对图像应用边缘检测,比如用canny边缘检测。

【2】然对边缘图像中的每一个非零点,考虑其局部梯度,即用Sobel()函数计算x和y方向

         的Sobel一阶导数得到梯度。

【3】利用得到的梯度,由斜率指定的直线上的每一个点都在累加器中被累加,这里的斜率是

          从一个指定的最小值到指定的最大值的距离。

【4】同时,标记边缘图像中每一个非0像素的位置。

【5】从二维累加器中这些点中选择候选的中心,这些中心都大于给定阈值并且大于其所有近

         邻。这些候选的中心按照累加值降序排列,以便于最支持像素的中心首先出现。

【6】对每一个中心,考虑所有的非0像素。

【7】这些像素按照其与中心的距离排序。从到最大半径的最小距离算起,选择非0像素最支

         持的一条半径。

【8】如果一个中心收到边缘图像非0像素最充分的支持,并且到前期被选择的中心有足够的

         距离,那么它就会被保留下来。

霍夫梯度法优点:

        算法高效,并能够解决三维累加器中会产生许多噪声并且使得结果不稳定的稀疏分布的

        问题;

霍夫梯度法缺点:  

        1、使用Sobel导数来计算可能导致更多的噪声;

        2、在边缘图像中整个非0像素都被当做候选中心,所以把累加器值设置偏低会导致点

              暴涨,以致于计算量较大,算法消耗时间过长;

        3、中心按照其关联的累加器的升序排列的,并且如果新的中心过于接近之前已经接受

              的中心点的话,就不会保留该点,等于是会倾向于同心圆只保留最大半径的圆;

void HoughCircles(InputArray image, OutputArray circles, int method, 
                  double dp, double minDist, double param1 = 100, 
                  double  param2 = 100, int minRadius = 0, int maxRadius = 0)

可以利用霍夫变换算法检测出灰度图中的圆。

HoughCircles和HoughLines、HoughLinesP比较明显的一个区别是它不需要源图是二值的

而HoughLines和HoughLinesP都需要源图为二值图像

参数1,InputArray类型的image,输入图像,即源图像,需为8位的灰度单通道图像。

参数2,InputArray类型的circles,经过调用HoughCircles函数后此参数存储了检测到的圆的

            输出矢量,每个矢量由包含了3个元素的浮点矢量(x, y, radius)表示。

参数3,int类型的method,即使用的检测方法,目前OpenCV中就霍夫梯度法一种可以

             使用,它的标识符为HOUGH_GRADIENT

枚举

描述

HOUGH_STANDARD

0

CV_HOUGH_STANDARD - 传统或标准 Hough 变换(SHT)。每一个线段由两个浮点数 (ρ, θ) 表示,其中 ρ 是直线与原点 (0,0) 之间的距离,θ 线段与 x-轴之间的夹角。因此,矩阵类型必须是 CV_32FC2 type;

HOUGH_PROBABILISTIC

1

CV_HOUGH_PROBABILISTIC- 概率 Hough 变换(PPHT)。如果图像包含一些长的线性分割,则效率更高。它返回线段分割而不是整个线段。每个分割用起点和终点来表示,所以矩阵(或创建的序列)类型是 CV_32SC4 type;

HOUGH_MULTI_SCALE

2

传统 Hough 变换的多尺度变种。线段的编码方式与 CV_HOUGH_STANDARD 的一致

HOUGH_GRADIENT

3

基本上是 21HT

参数4,double类型的dp,用来检测圆心的累加器图像的分辨率于输入图像之比的倒数,且

             此参数允许创建一个比输入图像分辨率低的累加器。例如,如果dp= 1时,累加器和

             输入图像具有相同的分辨率。如果dp = 2,累加器便有输入图像一半那么大的宽度和

             高度。

参数5,double类型的minDist,为霍夫变换检测到的圆的圆心之间的最小距离,即让我们的

             算法能明显区分的两个不同圆之间的最小距离。参数如果太小,多个相邻的圆可能被

              错误地检测成了一个重合的圆。反之,参数设置太大,某些圆就不能被检测出来。

参数6,double类型的param1,有默认值100。它是第三个参数method设置的检测方法的对

            应的参数。对当前唯一的方法霍夫梯度法CV_HOUGH_GRADIENT,它表示传递给

            canny边缘检测算子的高阈值,而低阈值为高阈值的一半。

参数7,double类型的param2,也有默认值100。它是第三个参数method设置的检测方法的

            对应的参数。对当前唯一的方法霍夫梯度法CV_HOUGH_GRADIENT,它表示在检

            测阶段圆心的累加器阈值。param2越小,就可以检测到更多根本不存在的圆,

            而param2越大,能通过检测的圆就更加接近完美的圆形。

参数8,int类型的minRadius,有默认值0,表示圆半径的最小值。

参数9,int类型的maxRadius,也有默认值0,表示圆半径的最大值。

绘制圆形circle函数

void circle(CvArr* img, CvPoint center, int radius, CvScalar color, 
            int thickness = 1, int lineType = 8, int shift = 0)

Img                源图像指针

Center           画圆的圆心坐标

Radius           圆的半径

Color              设定圆的颜色,规则根据B(蓝)G(绿)R(红)

thickness        如果是正数,表示组成圆的线条的粗细程度。否则,-1表示圆是否被填充

lineType          线条的类型。默认是8

shift                 圆心坐标点和半径值的小数点位数

绘制椭圆函数ellipse

void ellipse( CvArr* img,  CvPoint center,  CvSize axes,  double angle,
             double start_angle,  double end_angle,  CvScalar color,
             int thickness = 1,  int line_type = 8,  int shift = 0);

img                 源图像。

center             椭圆圆心坐标。

axes               轴的长度。

angle              偏转的角度。

start_angle     圆弧起始角的角度。

end_angle      圆弧终结角的角度。

color               线条的颜色。

thickness        线条的粗细程度。

line_type         线条的类型,见CVLINE的描述。

shift                 圆心坐标点和数轴的精度。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值