1.算法仿真效果
matlab2022a仿真结果如下:
2.算法涉及理论知识概要
霍夫变换是一种特征提取(feature extraction),被广泛应用在图像分析(image analysis)、计算机视觉(computer vision)以及数位影像处理(digital image processing)。霍夫变换是用来辨别找出物件中的特征,例如:线条。他的算法流程大致如下,给定一个物件、要辨别的形状的种类,算法会在参数空间(parameter space)中执行投票来决定物体的形状,而这是由累加空间(accumulator space)里的局部最大值(local maximum)来决定。
现在广泛使用的霍夫变换是由RichardDuda和PeterHart在公元1972年发明,并称之为广义霍夫变换(generalizedHoughtransform),广义霍夫变换和更早前1962年的PaulHough的专利有关。经典的霍夫变换是侦测图片中的直线,之后,霍夫变换不仅能识别直线,也能够识别任何形状,常见的有圆形、椭圆形。1981年,因为DanaH.Ballard的一篇期刊论文"Generalizing the Hough transform to detect arbitrary shapes",让霍夫变换开始流行于计算机视觉界。
一条直线可以用如下的方程来表示:y=kx+b,k是直线的斜率,b是截距。
图像是一个个离散的像素点构成的,如果在图像中有一条直线,那也是一系列的离散点构成的。那么怎样检测这些离散的点构成了直线呢?
我们再看上面的直线方程:y=kx+b,(x,y)就是点。我们转换下变成:b=-kx+y。我们是不是也可以把(k,b)看作另外一个空间中的点?这就是k-b参数空间。
我们看到,图1中,在x-y图像空间中的一个点,变成了k-b参数空间中的一条直线,而x-y图像空间中的2点连成的直线,变成了k-b参数空间中的一个交点。
如果x-y图像空间中有很多点在k-b空间中相交于一点,那么这个交点就是我们要检测的直线。这就是霍夫变换检测直线的基本原理。
当然,有一个问题需要注意,图像空间中如果一条直线是垂直的,那么斜率k是没有定义的(或者说无穷大)。为了避免这个问题,霍夫变换采用了另一个参数空间:距离-角度参数空间。
相反,图片上的点在霍夫空间就可以表示为线,我们要检测线条的话,就可以把图像上的每个点转换到霍夫空间去,找到霍夫空间上线条相交的点,就可以确定参数m, b.
3.MATLAB核心程序
Thetab=90-Thetaa;
bw1=imrotate(B,Thetab,'bicubic');
figure(7);
imshow(bw1);title('纠正后的二值图')
BW1=imrotate(BW,Thetab,'bicubic');
figure(8);
imshow(BW1);title('纠正后的边缘图')
[p,q]=size(BW1);
m=0;
for y=ceil(p/2):p
for x=1:q
if BW1(y,x)==1
m=m+1
else m=m
end
end
if m<60
y1=y
break
else m=0
end
end
n=0;
for yl=floor(p/2):-1:1
for xl=1:q
if BW1(yl,xl)==1
n=n+1
else n=n
end
end
if n<60
y2=yl
break
else n=0
end
end
BW2=imcrop(BW1,[1,y2,q,y1-y2]);
figure(9);imshow(BW2);title('上下分割')
bw2=imcrop(bw1,[1,y2,q,y1-y2]);
figure(10);imshow(bw2);title('上下分割')
[a,b]=size(BW2);
k=0
for yi=1:a
for xi=1:ceil(b/3)
if BW2(yi,xi)==1
k=k+1
A(k)=xi
else k=k
end
end
K=k
for c=1:K-4
L1=A(c+4)-A(c+3);
L2=A(c+3)-A(c+2);
L3=A(c+2)-A(c+1);
L4=A(c+1)-A(c);
L=(L1+L2+L3)/3
if (L2/L1)>0.5&(L2/L1)<1.5&(L3/L2)>0.5&(L3/L2)<1.5&(L4/L)>9
C=c
xx1=A(C)+1
break
else k=0
continue
end
end
end
..............................................................................
k = 1;
for i=1:59
if rem(i,2)
for j=1:bar_int(i)
bar_01(k) = 1;
k = k+1;
end
else
for j=1:bar_int(i)
bar_01(k) = 0;
k = k+1;
end
end
end
if ((bar_01(1)&&~bar_01(2)&&bar_01(3))...
&&(~bar_01(46)&&bar_01(47)&&~bar_01(48)&&bar_01(49)&&~bar_01(50))...
&&(bar_01(95)&&~bar_01(94)&&bar_01(93)))
l = 1;
for i=1:6
bar_left(l) = 0;
for k=1:7
bar_left(l) = bar_left(l)+bar_01(7*(i-1)+k+3)*(2^(7-k));
end
l = l+1;
end
l = 1;
for i=1:6
bar_right(l) = 0;
for k=1:7
bar_right(l) = bar_right(l)+bar_01(7*(i+6)+k+1)*(2^(7-k));
k = k-1;
end
l = l+1;
end
end