当前位置:文档之家› 霍夫变换

霍夫变换

‘IEEE Transactions on Pattern Recognition And Machine Intelligence’‘IEEE Transactions on Image Processing’是最重要的两本,其它的如ICCV、CVPR、ECCV、NIPS、BMVC等的会议文章也非常好。

最小二乘线性拟合算法、随机霍夫变换、局部霍夫变换、canny算子边缘检测、图像增强霍夫变换霍夫变换(Hough Transform)是图像处理中从图像中识别几何形状的基本方法之一,应用很广泛,也有很多改进算法。

主要用来从图像中分离出具有某种相同特征的几何形状(如,直线,圆等)。

最基本的霍夫变换是从黑白图像中检测直线(线段)。

详细内容我们先看这样一个问题:设已知一黑白图像上画了一条直线,要求出这条直线所在的位置。

我们知道,直线的方程可以用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)。

应用这个性质就为我们解决问题提供了方法:首先,我们初始化一块缓冲区,对应于参数平面,将其所有数据置为0.对于图像上每一前景点,求出参数平面对应的直线,把这直线上的所有点的值都加1。

最后,找到参数平面上最大点的位置,这个位置就是原图像上直线的参数。

上面就是霍夫变换的基本思想。

就是把图像平面上的点对应到参数平面上的线,最后通过统计特性来解决问题。

假如图像平面上有两条直线,那么最终在参数平面上就会看到两个峰值点,依此类推。

在实际应用中,y=k*x+b形式的直线方程没有办法表示x=c形式的直线(这时候,直线的斜率为无穷大)。

所以实际应用中,是采用参数方程p=x*cos(theta)+y*sin(theta)。

这样,图像平面上的一个点就对应到参数p—theta平面上的一条曲线上。

其它的还是一样。

应用实例1在看下面一个问题:我们要从一幅图像中检测出半径已知的圆形来。

这个问题比前一个还要直观。

我们可以取和图像平面一样的参数平面,以图像上每一个前景点为圆心,以已知的半径在参数平面上画圆,并把结果进行累加。

最后找出参数平面上的峰值点,这个位置就对应了图像上的圆心。

在这个问题里,图像平面上的每一点对应到参数平面上的一个圆。

把上面的问题改一下,假如我们不知道半径的值,而要找出图像上的圆来。

这样,一个办法是把参数平面扩大称为三维空间。

就是说参数空间变为x-y-R 三维,对应圆的圆心和半径。

图像平面上的每一点就对应于参数空间中每个半径下的一个圆,这实际上是一个圆锥。

最后当然还是找参数空间中的峰值点。

不过,这个方法显然需要大量的内存,运行速度也会是很大问题。

有什么更好的方法么?我们前面假定的图像都是黑白图像(2值图像),实际上这些2值图像多是彩色或灰度图像通过边缘提取来的。

我们前面提到过,图像边缘除了位置信息,还有方向信息也很重要,这里就用上了。

根据圆的性质,圆的半径一定在垂直于圆的切线的直线上,也就是说,在圆上任意一点的法线上。

这样,解决上面的问题,我们仍采用2维的参数空间,对于图像上的每一前景点,加上它的方向信息,都可以确定出一条直线,圆的圆心就在这条直线上。

这样一来,问题就会简单了许多。

应用实例2接下来还有许多类似的问题,如检测出椭圆,正方形,长方形,圆弧等等。

这些方法大都类似,关键就是需要熟悉这些几何形状的数学性质。

霍夫变换的应用是很广泛的,比如我们要做一个支票识别的任务,假设支票上肯定有一个红颜色的方形印章,我们可以通过霍夫变换来对这个印章进行快速定位,在配合其它手段进行其它处理。

霍夫变换由于不受图像旋转的影响,所以很容易的可以用来进行定位。

霍夫变换有许多改进方法,一个比较重要的概念是广义霍夫变换,它是针对所有曲线的,用处也很大。

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

%% 利用hough变换检测直线clear allclcclose all%% 读入图片======================================================In = imread('image.tif');subplot(221)imshow(In);title('original image');%% 参数设定=======================================================k = 1; % 检测直线条数(即一个方向的直线)%% 边缘提取=======================================================BW = edge(In, 'canny');subplot(222)imshow(BW);title('edge image')%% hough变换=========================================================[H, T, R] = hough(BW, 'RhoResolution', 0.5,'Theta',-90:0.5:89.5); % hough变换subplot(223)imshow(H,'XData',T,'YData',R,'InitialMagnification','fit')title('Hough transform')xlabel('\theta'),ylabel('\rho')axis on, axis normal,hold on;%% 峰值检测=============================================================P = houghpeaks(H,k); % 找到H中的最大的几个值所在H中的坐标% 具体几个由后面的参数决定% 每一个点都对应一条线段% 但是并不是最后会找到这么多条线段% 因为由于后面houghlines函数可能会合并和舍去线段plot(T(P(:,2)),R(P(:,1)),'s','color','red'); % 在theta-rho坐标中标出峰值点%% 直线检测============================================================== subplot(224),imshow(In),hold ontitle('Display the lines')lines = houghlines(BW,T,R,P); % 返回一个结构体,存放的是每个线段的始末点坐标 % 以及在theta-rho坐标系下的坐标。

% 默认情况下,两条线断的距离低于20时就合并 % 如果一条线段的长度小于40时就舍去% 用法:lines = houghlines(BW,T,R,P,'FillGap',20,'MinLength',40) max_len = 0;% 找到并绘出线段for k = 1 : length(lines)xy = [lines(k).point1;lines(k).point2]; % xy为第k条线段始末点的坐标矩阵% 画出线段plot(xy(:,1),xy(:,2),'LineWidth',2,'Color','green')% 画出线段起始点plot(xy(1,1),xy(1,2),'x','LineWidth',2,'Color','yellow')plot(xy(2,1),xy(2,2),'x','LineWidth',2,'Color','red')% 判断最长线段len = norm(lines(k).point1-lines(k).point2); % 计算二范数,即线段长度% 找最长的线段,将其始末点坐标存入xy_long矩阵中if len > max_lenmax_len = len;xy_long = xy;endend% 突出最长线段plot(xy_long(:,1),xy_long(:,2),'LineWidth',2,'Color','blue')Hough变换的原理:将图像从图像空间变换至参数空间,变换公式如下:变换以后,图像空间与参数空间存在以下关系:图像空间中的一点在参数空间是一条曲线,而图像空间共线的各点对应于参数空间交于一点的各条曲线。

下面使用Matlab实现Hough变换对图像中的直线划痕进行检测 .1.close all;2.clear all;3.I = imread('scratch.tif');4.figure;5.subplot(1,3,1);6.imshow(I);7.BW = edge(I,'canny');%Canny方法提取图像边界,返回二值图像(边界1,否则0)8.[H,T,R] = hough(BW);%计算二值图像的标准霍夫变换,H为霍夫变换矩阵,I,R为计算霍夫变换的角度和半径值9.subplot(1,3,2);10.imshow(H,[],'XData',T,'YData',R,'InitialMagnification','fit');%hough变换的图像11.xlabel('\theta'), ylabel('\rho');12.axis on,axis square,hold on;13.P = houghpeaks(H,3);%提取3个极值点14.x = T(P(:,2));15.y = R(P(:,1));16.plot(x,y,'s','color','white');%标出极值点17.lines=houghlines(BW,T,R,P);%提取线段18.subplot(1,3,3);19.imshow(I), hold on;20.for k = 1:length(lines)21.xy = [lines(k).point1; lines(k).point2];22. plot(xy(:,1),xy(:,2),'LineWidth',2,'Color','green');%画出线段23.plot(xy(1,1),xy(1,2),'x','LineWidth',2,'Color','yellow');%起点24.plot(xy(2,1),xy(2,2),'x','LineWidth',2,'Color','red');%终点25.end/content/14/0404/14/16239681_36 6361318.shtml梯度:在二元函数的情形,设函数z=f(x,y)在平面区域D内具有一阶连续偏导数,则对于每一点P(x,y)∈D,都可以定出一个向量(δf/x)*i+(δf/y)*j;这向量称为函数z=f(x,y)在点P(x,y)的梯度,记作gradf(x,y)。

相关主题