Hough是基于特征值提取技术的图像变换方案。Hough运用两个坐标空间的之间的变换将在一个空间中具有相同形状的曲线或直线映射到另一个坐标空间的一个点上形成峰值,从而把检测任意形状的问题转换为统计峰值问题。
基本原理
Hough变换是利用表决原理的参数轨迹技术,说到参数估计,大家能够想到过冷水做的有关概率统计的推文不?——统计分布讲解。基本原理在于利用图像空间和Hough参数空间点与线的对偶性,把图像空间中检测问题转换为参数空间。通过在参数空间里进行简单的累加统计,然后在Hough参数空间寻找累加器峰值的方法找检测直线。Hough变换的实质是将图像空间内具有一定关系的像元进行聚类,寻找能把这些像元用某一解析形势联系起来的参数空间累计对应点。在参数空间不超过二维的情况下,这种变换效果理想。将原始图像空间的给定的曲线表达形式变为参数空间的一个点,这样就把原始图像中给定曲线的检测问题转化为寻找参数空间的峰值问题,也就是把检测整体特性转化为检测局部特性,例如直线、椭圆、圆、弧线等。
简而言之,Hough变换思想是:在原始图像坐标系下的一个点对应了参数坐标系中的一条直线同样参数坐标系的一条直线对应原始坐标系下的一个点,然后,坐标系下呈现直线的所有点,它们的斜率和截距是相同的,所以它们在参数坐标系下对应于同一个点。这样在原始坐标系下的各个点的投影到多数坐标系下之后,看参数坐标系下没有聚集点,这样的聚集点就对应了原始坐标系下的直线。 在图像处理中,从图像中识别几何形状的基本方法之一是Hough变换,它有很多改进算法。最基本的Hough变换是从黑白图像中检测直线。广义的Hough变换已经不仅仅局限于提取直线,二值任意可以用表达式表达的曲线都可以提取,例如圆、椭圆、正弦余弦曲线等。曲线越是复杂.所需参数越多,运算的时间也就越多。Hough 变换的精髓在于投票算法,将图像空间转换到参数空间进行求解。假如已知黑白图像上画了一 条直线,要求出这条 直线所在的位置。直线的方程用y=kx+b来表示,其中k和b是参数,分别是斜率和截距,过某一点(x0,y0)的所有直线的参数都会满足方程y0=kx0+b,即点(x0,y0)确定了一组直线。方程y0=kx0+b在参数k-b平面上是一条直线,这样,图像x-y平面上的一个像素点就对应到参数k-b平面上的一条直线。Hough变换的基本思想就是把图像平面上的点对应到参数平面上的线。在实际应用中,y=kx+b形式的直线方程没有办法表示x=c形式的直线。
Hough进行边缘检测
clear
f=imread('11.png'); %读入彩色图像,注意不能使用灰度图像
o=f; %保留彩色原图
f=rgb2gray(f); %将彩色图像转换为灰度图像,[检查下看能否运行,给的代码里没有这个程序。没有运行结果]
f=im2double(f);
figure();
subplot(231);imshow(o);title('原图');
[m,n]=size(f); %得到图像矩阵行数m,列数n
for i=3:m-2
for j=3:n-2 %处理领域较大,所以从图像(3,3)开始,在(m-2,n-2)结束
%LoG算子
l(i,j)=-f(i-2,j)-f(i-1,j-1)-2*f(i-1,j)-f(i-1,j+1)-f(i,j-2)-2*f(i,j-1)+16*f(i,j)-2*f(i,j+1)...
-f(i,j+2)-f(i+1,j-1)-2*f(i+1,j)-f(i+1,j+1)-f(i+2,j);
end
end
subplot(232);
imshow(l);
title('LoG算子提取图像边缘');
%均值化滤波处理
[m,n]=size(l);
for i=2:m-1
for j=2:n-1
%LoG算子提取边缘后,对结果进行均值滤波以去除噪声,为下一步hough变换提取直线作准备
y(i,j)=l(i-1,j-1)+l(i-1,j)+l(i-1,j+1)+l(i,j-1)+l(i,j)+l(i,j+1)+l(i+1,j-1)+l(i+1,j)+l(i+1,j+1);
y(i,j)=y(i,j)/9;
end
end
subplot(233);imshow(y);title('均值滤波器处理后')
%二值化处理
q=im2uint8(y);
[m,n]=size(q);
for i=1:m
for j=1:n
if q(i,j)>80; %设置二值化的阈值为80
q(i,j)=255; %对图像进行二值化处理,使图像边缘更加突出清晰
else
q(i,j)=0;
end
end
end
subplot(234);imshow(q);title('二值化处理后');
%Hough变换检测直线,使用(a,p)参数空间,a∈[0,180],p∈[0,2d])
a=180; %角度的值为0到180度
d=round(sqrt(m^2+n^2)); %图像对角线长度为p的最大值
s=zeros(a,2*d); %存储每个(a,p)个数
z=cell(a,2*d); %用元胞存储每个被检测的点的坐标
for i=1:m
for j=1:n %遍历图像每个点
if(q(i,j)==255) %只检测图像边缘的白点,其余点不检测
for k=1:a
%对每个点从1到180度遍历,取得经过该点的所有直线的p值
p = round(i*cos(pi*k/180)+j*sin(pi*k/180));
%若p大于0,则将点存储在(d,2d)空间
if(p > 0)
s(k,d+p)=s(k,d+p)+1; %(a,p)相应的累加器单元加1
z{k,d+p}=[z{k,d+p},[i,j]']; %存储点坐标
else
ap=abs(p)+1; %若p小于0,则将点存储在(0,d)空间
s(k,ap)=s(k,ap)+1; %(a,p)相应的累加器单元加一
z{k,ap}=[z{k,ap},[i,j]'];%存储点坐标
end
end
end
end
end
for i=1:a
for j=1:d*2 %检查每个累加器单元中存储数量
if(s(i,j) >35) %将提取直线的阈值设为35
lp=z{i,j}; %提取对应点坐标
%对满足阈值条件的累加器单元中(a,p)对应的所有点进行操作
for k=1:s(i,j)
o(lp(1,k),lp(2,k),1)=255; %每个点R分量=255,G分量=0,B分量=0
o(lp(1,k),lp(2,k),2)=0;
o(lp(1,k),lp(2,k),3)=0; %为满足阈值要求的直线上的点赋红色
end
end
end
end
subplot(235)
imshow(o);title('hough变换提取边界直线');