文档图像倾斜角检测及校正(三)
- 斜率空间投票原理
- Matlab程序
阅读之前注意:
Hi,你好,我是Cooper Liu,欢迎来到我写的“文档图像校正”系列博客。基于三种原理,我写了四个实验性的Matlab验证程序,以及两个文档校正Matlab程序。在这里你将能够获取所有的源代码以及测试图片,完全可以在你自己的Matlab上跑这些程序。
如果你是学生,请注意不要抄袭,课程设计作业的话,这种程序仅仅只能让你得到80%左右的成绩。
如果你是工作人士或者只是感兴趣的极客,Okay,我想这些程序对于理解原理是如何应用为程序的已经足够 。最后,请勿将这些资源用于商业用途(如你所见,这些程序都非常的初级)或者是谋取个人利益,知识在传播的过程中能展现更大的价值^-^
本文阅读建议用时:42min
本文阅读结构如下表:
项目 | 下属项目 | 测试用例数量 |
---|---|---|
斜率空间投票原理 | 无 | 0 |
Matlab程序 | 无 | 2 |
斜率空间投票原理1
斜率空间投票指的是,在文档图像的某一个区域中,如果我们知道有一个点
我们将斜率值映射到一组累加器上,每求出一个斜率值,对应的累加器加一。因为同一直线上的点求得的斜率相同,所以累加器会出现局部最大值,该值所对应的斜率即是所求直线的斜率,倾斜角也能相应的求出。
值得注意的是,当
Matlab程序
基于以上原理,我编写了Matlab程序来进行实验,源代码可以参考angleDetection3.m文件和angleDetection4.m文件。测试图片为line5.bmp。2
测试图片可以从这里获取,链接:https://pan.baidu.com/s/1dGmmGjn 密码:okt3
我编写了两个版本的Matlab程序,其中版本一(angleDetection3.m文件)的思想是把斜率区间尽可能的细分,比如分成10000份,再计算对应10000个累加器的最大值,从而反推出斜率。而版本二(angleDetection4.m文件)的思想则是先把斜率空间分为10个子区间,求出累加器的最大值,把最大值对应的子区间再分为10个子区间,如此迭代,直至区间宽度小于我们所控制的迭代精度。
以下是版本一的实验结果:
以下是版本二的实验结果:
如果您不想打开新的页面查看matlab源代码,也可以直接参考以下代码:
版本一(angleDetection3.m文件):
%%本版基于斜率空间投票原理
%%2018.01.20_14:09 by Cooper Liu
%%Questions? Contact me: [email protected]
clear;clc; %清空之前的变量
I=imread('line5.bmp'); %读取图像
level=graythresh(I); %使用最大类间方差法找到图片的一个合适的阈值
bw=im2bw(I,level); %根据阈值,使用im2bw函数将灰度图像转换为二值图像
figure(1);imshow(bw);
[m,n]=size(bw); %获取尺寸
flag=0;
tic; %计时开始
for i=1:m
for j=1:n
if bw(i,j)==0
if flag==0
x0=i;y0=j; %获取第一个点
flag=1;
end
end
end
end
range=10000; %range越大对角度分得更细,计算量更大
low=-1;
high=3;
a=zeros(range,1);
for i=1:m
for j=1:n
if bw(i,j)==0
if i==x0
k=2;
area=floor((k-(-1))/4*range); %向下取整
a(area+1,1)=a(area+1,1)+1; %区间计数
else
k=(j-y0)/(i-x0);
k2=k;
if k>1 || k<-1
k2=2-1/k; %转换斜率,保证斜率范围(-1, 3)
end
area=floor((k2-(-1))/4*range); %向下取整
a(area+1,1)=a(area+1,1)+1;
end
end
end
end
toc %获取时间
[s_i,index] = sort(a,'descend'); %降序排序并获取原来序列的序号至index
max=index(1);
tmp=(-1)+max/range*4;
if tmp>1
k=1/(2-tmp); %还原原来的斜率
else
k=tmp;
end
angle=atan(k); %用atan求出来的角度在-pi/2到+pi/2之间
angle=angle*180/pi
rot=90-angle;
pic=imrotate(I,rot,'crop'); %旋转图像
figure(2);imshow(pic);
版本二(angleDetection4.m文件):
%%本版基于斜率空间投票原理,改进自angleDetection3.m
%%2018.01.20_15:41 by Cooper Liu
%%Questions? Contact me: [email protected]
clear;clc; %清空之前的变量
I=imread('line5.bmp'); %读取图像
level=graythresh(I); %使用最大类间方差法找到图片的一个合适的阈值
bw=im2bw(I,level); %根据阈值,使用im2bw函数将灰度图像转换为二值图像时
figure(1);imshow(bw);
[m,n]=size(bw); %获取尺寸
flag=0;
for i=1:m
for j=1:n
if bw(i,j)==0
if flag==0
x0=i;y0=j;
flag=1;
end
end
end
end
range=10; %整个斜率区间分为10个子区间
low=-1;
high=3;
tmpLow=low;
tmpHigh=high;
max=0;
areaAddtion=0;
tic; %开始计时
while high-low>0.0001
a=zeros(range,1);
for i=1:m
for j=1:n
if bw(i,j)==0
if i==x0 %如果x坐标与x0相同
k=2; %则固定k为2
if k>=low && k<=high
area=floor((k-low)/(high-low)*range); %向下取整
if area==range %如果等于最后一个区间
area=area-1; %请考虑到后面区间计数的area+1
end
a(area+1,1)=a(area+1,1)+1; %区间计数
end
else %如果x坐标与x0不同
k=(j-y0)/(i-x0); %则计算斜率
k2=k;
if k>1 || k<-1
k2=2-1/k;
end
if k2>=low && k2<=high
area=floor((k2-low)/(high-low)*range); %向下取整
if area==range
area=area-1;
end
a(area+1,1)=a(area+1,1)+1;
end
end
end
end
end
[s_i,index] = sort(a,'descend');
max = index(1);
tmpLow = low;
tmpHigh = high;
if max>=2 && max<=9
areaAddition=0; %根据需要可以更改子区间的范围
else
areaAddtion=0;
end
low = tmpLow + (max - 1 - areaAddition)/range*(tmpHigh - tmpLow);
high = tmpLow + (max + areaAddtion)/range*(tmpHigh - tmpLow);
end
toc %获取计时时间
tmp=tmpLow+max/range*(tmpHigh-tmpLow);
if tmp>1
k=1/(2-tmp);
else
k=tmp;
end
angle=atan(k); %用atan求出来的角度在-pi/2到+pi/2之间
angle=angle*180/pi
rot=90-angle;
pic=imrotate(I,rot,'crop'); %旋转图像
figure(2);imshow(pic);