一、问题背景
下图是一张单据的扫描件,编程计算旋转角度对其进行校正、并补全断裂的表格线。
二、算法原理
1.基于sobel算子的边缘检测
要想将倾斜表格旋转进行校正,首先要计算表格倾斜的角度,我们用Hough变化来计算倾斜角度,Hough变换前先用sobel算子进行边缘检测;
2.基于Hough变化的倾斜角度计算
Hough变化计算倾斜角度。Hough变换的基本原理在于,利用点与线的对偶性,将图像空间的线条变为参数空间的聚集点,从而检测给定图像是否存在给定性质的曲线。采用直线的极坐标表示,直线可表示为 ,由此方程可知,原图像空间中的一条直线与极坐标系下的一个点 对应;而原图像空间的任一点 都与一个正弦曲线对应;所有共线的点,其正弦曲线一定过同一个点。可以通过检测参数空间中过某个点的正弦曲线的条数来检测图像空间中共线的点数。设置一个累加数组 ,用它来对过 的曲线进行计数。然后对每一个图像空间中的点给出一个 的取值,根据 计算出对应的 ,对所有过 点的曲线在 中累加计数;最后找出数组中数目最大的 ,此时的 值即为表格的倾斜角度;
3.基于imrotate函数的图像旋转
利用imrotate函数对表格进行旋转;
4.基于Hough变换的图像复原
再次使用Hough变换,对旋转校正后的图像进行处理,设定阈值,找出 大于阈值时的所有直线,并找出直线上的所有点 ,令其对应的灰度值 ,即可将所有表格补全;
三、算法步骤
(1)sobel算子边缘检测;
(2)Hough变化计算倾斜角度;
(3)图像旋转校正;
(4)再次Hough变化找出所有直线;
(5)令直线上所有像素灰度值为0,补全表格;
四、MATLAB程序代码
f=imread('hw4_table.jpg');
g=edge(f,'sobel',0.05);%边缘检测
figure
imshow(f);title('原图像');
figure;imshow(g);title('原图像边缘检测');
[row,col]=size(f);
rho_max=round(sqrt(row*row+col*col));
A=zeros(2*rho_max,180);%记录点数
pix=cell(2*rho_max,180);%记录坐标x,y
for x=1:row
for y=1:col
if g(x,y)<1
continue;
end
for theta=1:180
rad=theta/180*pi;
rho = round(x*cos(rad)+y*sin(rad))+rho_max;
A(rho,theta) = A(rho,theta)+1;%累加计数
pix{rho,theta}=[pix{rho,theta},[x,y]'];
end
end
end
B=A(:);
[new,ind]=sort(B,'descend');
[~,b]=find(A==new(1,1))
w=180-b %旋转角度
F=imrotate(f,w);%校正后图像
F(1:50,:)=255;
F(700:745,:)=255;
F(:,1:40)=255;
F(:,1280:1324)=255;
figure;imshow(F);title('图像校正');
G=edge(F,'sobel',0.05);%边缘检测
[row1,col1]=size(F);
rho_max1=round(sqrt(row1*row1+col1*col1));
A1=zeros(2*rho_max1,180);%记录点数
pix1=cell(2*rho_max1,180);%记录坐标x,y
for x=1:row1
for y=1:col1
if G(x,y)<1
continue;
end
for theta1=1:180
rad1=theta1/180*pi;
rho1 = round(x*cos(rad1)+y*sin(rad1))+rho_max1;
A1(rho1,theta1) = A1(rho1,theta1)+1;%累加计数
pix1{rho1,theta1}=[pix1{rho1,theta1},[x,y]'];
end
end
end
[rho1,theta1]=find(A1>=250);
for i=1:length(rho1)
pos1=pix1{rho1(i),theta1(i)};
[~,m]=size(pos1);
F(pos1(1,1):pos1(1,m),pos1(2,1):pos1(2,m))=0;
end
figure;imshow(F);title('补全表格');
五、处理结果(包括必要的中间结果)
sobel算子边缘检测后的图像:
Hough变化计算倾斜角度为:
对倾斜图像进行旋转校正
设定阈值: ,找出所有直线并对其补全
六、算法改进
(1)sobel算子边缘检测;
(2)Hough变化计算倾斜角度;
(3)图像旋转校正;
(4)再次Hough变化找出所有直线;
(5)用plot函数连接所有点
改进的MATLAB程序如下:
clc;
clear;
close all;
f=imread('hw4_table.jpg');
figure(1);
imshow(f(:,:,1));
f=padarray(f,[100 100],'symmetric','both');
i=imrotate(f,2); %theat=178
f=i(:,:,1);
f=f(101:800,101:1400);
g=edge(f,'sobel',0.05);
figure(2);
imshow(f);title('原图');
figure;imshow(g);
[row,col]=size(f);
rho_max=round(sqrt(row*row+col*col));
A=zeros(2*rho_max,180);
pix=cell(2*rho_max,180);
for x=1:row
for y=1:col
if g(x,y)<1
continue;
end
for theta=1:180
rad=theta/180*pi;
rho = round(x*cos(rad)+y*sin(rad))+rho_max;
A(rho,theta) = A(rho,theta)+1;
pix{rho,theta}=[pix{rho,theta},[x,y]'];
end
end
end
figure(3);imshow(f);title('hough变换');
[rho1,theta1]=find(A>207);
for i=1:length(rho1)
if theta1(i)==90
pos=pix{rho1(i),theta1(i)};
hold on
plot(pos(2,1),pos(1,1):pos(1,end),'.k','LineWidth',0.5);
end
end
[rho2,theta2]=find(A>230);
for i=1:length(rho2)
if theta2(i)==180
pos=pix{rho2(i),theta2(i)};
hold on
plot(pos(2,1):pos(2,end),pos(1,1),'.k','LineWidth',0.5);
end
end
改进后处理结果:
参考文献:
[1]顾亚芳. 高斯模糊图像的盲复原[D].东南大学,2006.