Opencv2.4学习::霍夫变换(2)圆变换

霍夫圆变换


基本原理 

关于基本原理,其思想大概跟霍夫线变换相似,但是有两种说法。

第一种

在霍夫线变换中,笛卡尔X-Y直角坐标系中的直线,变换到霍夫空间中则为1个点

因此类比可得,笛卡尔X-Y直角坐标系中的圆,变换到abr空间中,则为一条曲线,具体如下:

X-Y直角坐标系下圆方程:

对应的参数方程为:

所以在abr组成的三维坐标系中,一个点可以唯一确定一个圆。

那么,当我们固定(x,y),选取(a,b,r) 的不同组合,可以得到xy直角坐标系中经过某点(X,Y)的所有圆对应,

而在笛卡尔的xy坐标系中经过某一点的所有圆映射到abr坐标系中就是一条三维的曲线。【这句话应该是不严谨的,正确的说法看后面的第二种叙述】

个人认为,上面的话,应该是对于某点(x,y),

固定X时,选取不同(a,r)组合,可以得到一条(a,r)坐标系下的曲线

固定Y时,选取不同(b,r)组合,可以得到一条(b,r)坐标系下的曲线 

这里,我们先继续认为上面的叙述没有问题,即经过点(X,Y)的所有圆变换到(a,b,r)空间下是一条空间曲线。那么这条曲线上的一点,则对应一个圆。

                              

这时候,看(a,b,r)坐标系,若该坐标系中有某点(a,b,r)固定,那么经过该点的空间曲线越多,说明对应笛卡尔X-Y直角坐标系中共圆的点越多。当设定一个阈值,则可判断X-Y坐标系中是否有圆了。


 第二种

X-Y直角坐标系下圆方程:

现假设(x,y)是参数,即(x,y)固定,假设为(1,1)

那么以(a,b,r)为变量的方程,对应的空间图形是一个这样一个曲面,貌似是圆锥?

matlab画图代码:

>> a=-8:0.5:8;
>> b=a;
>> [A,B]=meshgrid(a,b);
>> R=sqrt((1-A).^2+(1-B).^2);
>> mesh(A,B,R);

这就跟上面第一种说法的叙述有矛盾了,这里表明在笛卡尔的xy坐标系中经过某一点的所有圆映射到abr坐标系中是一个圆锥体

那么,在这个曲面上的每一个点,则对应 X-Y坐标系下的一个经过点(x,y)的圆。

也就是说,在(a,b,r)坐标系中,假设有固定的某点(a0,b0,r0),若经过该点的曲面越多,则表示对应X-Y直角坐标系中有多个点共这个圆。

原理部分就先到这里,希望有大神指出纰漏。 


 

霍夫梯度法


上述描述的是标准霍夫圆变换的原理,由于三维空间的计算量大大增大的原因, 标准霍夫圆变化很难被应用到实际中。

实际上,一般用霍夫梯度法来解决这个问题。

基本原理:依据是圆心一定是在圆上的每个点的模向量上(圆上该点切线的法向量), 这些圆上点模向量的交点就是圆心, 霍夫梯度法的

第一步就是找到这些圆心, (圆心包含了圆心处的x和y坐标)这样三维的累加平面就又转化为二维累加平面.

第二步根据所有候选中心的边缘非0像素对其的支持程度来确定半径。简单来说,就是从圆心到圆周上的任意一点的距离(即半径)是相同,只要确定一个阈值,只要相同距离的数量大于该阈值,我们就认为该距离就是该圆心所对应的圆半径,该方法只需要计算半径直方图,不使用霍夫空间。

下引用给出两个版本解释的霍夫梯度法操作具体过程:

引用参考:https://blog.csdn.net/qq_37059483/article/details/77916655

version 1:

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

1)首先对图像进行边缘检测,调用opencv自带的cvCanny()函数,将图像二值化,得到边缘图像。
2)对边缘图像上的每一个非零点【即边缘点】。采用cvSobel()函数,计算x方向导数和y方向的导数,从而得到梯度。从边缘点,沿着梯度和梯度的反方向,对参数指定的min_radius到max_radium的每一个像素,在累加器中被累加。同时记下边缘图像中每一个非0点的位置。
3)从(二维)累加器中这些点中选择候选中心。这些中心都大于给定的阈值和其相邻的四个邻域点的累加值。
4)对于这些候选中心按照累加值降序排序,以便于最支持的像素的中心首次出现。
5)对于每一个中心,考虑到所有的非0像素(非0,梯度不为0),这些像素按照与其中心的距离排序,从最大支持的中心的最小距离算起,选择非零像素最支持的一条半径。
6)如果一个中心受到边缘图像非0像素的充分支持,并且到前期被选择的中心有足够的距离。则将圆心和半径压入到序列中,得以保留。
 

version 2:

第一阶段:检测圆心

1.1、对输入图像边缘检测;

1.2、考虑其局部梯度,即用Sobel()函数计算x和y方向的Sobel一阶导数得到梯度,即得到切线的法向量【指向圆心】

(这里容易把偏导、切线、梯度、法向量混淆,为此我还回去看了几天的高数下册,在下面给出一些归纳)

1.3、在二维霍夫空间内,绘出所有图形的梯度直线,某坐标点上累加和的值越大,说明在该点上直线相交的次数越多,也就是越有可能是圆心;(备注:这只是直观的想法,实际源码并没有划线)

1.4、在霍夫空间的4邻域内进行非最大值抑制;

1.5、设定一个阈值,霍夫空间内累加和大于该阈值的点就对应于圆心。

第二阶段:检测圆半径

2.1、计算某一个圆心到所有圆周线的距离,这些距离中就有该圆心所对应的圆的半径的值,这些半径值当然是相等的,并且这些圆半径的数量要远远大于其他距离值相等的数量

2.2、设定两个阈值,定义为最大半径和最小半径,保留距离在这两个半径之间的值,这意味着我们检测的圆不能太大,也不能太小

2.3、对保留下来的距离进行排序

2.4、找到距离相同的那些值,并计算相同值的数量

2.5、设定一个阈值,只有相同值的数量大于该阈值,才认为该值是该圆心对应的圆半径

2.6、对每一个圆心,完成上面的2.1~2.5步骤,得到所有的圆半径



番外:切向量&&法向量

先给出切向量的大概推导:

意思是:对于2维下参数方程,某点处的切向量为分量对参数求导(x'(t0),y'(t0))

由此,可以得到以下归纳:

在非参数方程的归纳中,将x看作是参数,将问题转化为参数方程下的切向量和法向量问题,

最终加上隐函数求导法则,可以推出2维下某点的梯度即为该点处的法向量



参考文章:

https://blog.csdn.net/xia316104/article/details/44781157 

https://blog.csdn.net/qq_37059483/article/details/77916655

https://blog.csdn.net/dcrmg/article/details/52506538

猜你喜欢

转载自blog.csdn.net/dieju8330/article/details/82911550