我们在日常生活中有时看到的pdf文档是扫描件,那扫描的结果有时很不好 ,歪歪斜斜还有阴影。这样就会影响到我们的阅读心情。例如我前两天找到的一本《矩阵论》的pdf文档就是扫描件,给大家看一下。
很明显可以看到左边这张歪了,而且中间还有一条黑线,看着不太舒服。
对于以上这种情况,我们要做的就是1.把中间的黑线去掉。2.把图像一分为二,因为是两页。3.把图像矫正过来。针对以上步骤,可以参照我下面给出的代码,理解其内容。
clc
clf
clear
path='C:\Users\ASUS\Desktop\juzhen\'; %%需要处理的图像文件夹
list=dir(path);
path1='C:\Users\ASUS\Desktop\矩阵论处理1\'; %%处理后图像所在文件夹
for i=3:length(list)
% i=66;
path2=[path list(i).name];
I=imread(path2);%读取图片
[a,b,c]=size(I);
if c==3
I=rgb2gray(I);
end
BW=imbinarize(I,graythresh(I));
BW(:,round(b/2)-200:round(b/2)+200) = 1;
A=BW(:,1:round(b/2));
B=BW(:,round(b/2)+1:end);
A1=~A(600:1200,:);
% A1=~A(400:1600,:);
A1=imclearborder(A1,8);
stats_1 = regionprops(A1,'Eccentricity');
statsangle_1=regionprops(A1,'Orientation');
m1=cell2mat(struct2cell(stats_1));
[~,maxnum1]=max(m1);
statsangle_1=cell2mat(struct2cell(statsangle_1));
angle_1=statsangle_1(maxnum1);
if abs(angle_1)>=0.1
pic_1=imrotate(~A,-(angle_1),'bilinear','crop');
else
pic_1=~A;
end
B1=~B(600:1200,:);
% B1=~B(400:1600,:);
B1=imclearborder(B1,8);
stats_2 = regionprops(B1,'Eccentricity');
statsangle_2=regionprops(B1,'Orientation');
m2=cell2mat(struct2cell(stats_2));
[~,maxnum2]=max(m2);
statsangle_2=cell2mat(struct2cell(statsangle_2));
angle_2=statsangle_2(maxnum2);
if abs(angle_2)>=0.1
pic_2=imrotate(~B,-(angle_2),'bilinear','crop');
else
pic_2=~B;
end
name1=num2str(2*i-1);
name2=num2str(2*i);
imwrite(~pic_1,[path1,name1,'.png']);
imwrite(~pic_2,[path1,name2,'.png']);
% imshow(B1)
end
这个处理流程比较简单。但是前提得是你把pdf文档先转换成图片。
1.首先根据路径读取图片列表,然后依次读取图片进行处理。
2.对于读取到的图片判断其大小,如果是正常的三通道图片就要转换成灰度图像,否则就跳过该步骤。
3.对读取的图像进行二值转换,然后用BW(:,round(b/2)-200:round(b/2)+200) = 1覆盖其中间的黑线(注意这个范围要根据实际适当的调整)。
4.将二值图像进行分离,分成A,B两个图像A=BW(:,1:round(b/2));B=BW(:,round(b/2)+1:end);
5.采集其标头部分的横线,这是本次处理的重点,因为横线的方向就代表了页面的倾斜程度。所以要完整的采集此线条。(适当调整A1=~A(600:1200,:)的范围)
6.计算不同连通域的离心率,并找出最大的离心率。(regionprops(A1,'Eccentricity');是标量,与区域具有相同标准二阶中心矩的椭圆的离心率(可作为特征)。本属性只支持二维标注矩阵)
stats_1 = regionprops(A1,'Eccentricity');
m1=cell2mat(struct2cell(stats_1));
[~,maxnum1]=max(m1);
7.计算每个连通域的倾斜角度,并按照上一步的结果找到离心率最大的连通域的倾斜角度。实际上就是本线条的倾斜角度。(regionprops(A1,'Orientation');是标量,与区域具有相同标准二阶中心矩的椭圆的长轴与x轴的交角(度)。本属性只支持二维标注矩阵)
statsangle_1=regionprops(A1,'Orientation');
statsangle_1=cell2mat(struct2cell(statsangle_1));
angle_1=statsangle_1(maxnum1);
8.根据计算结果进行旋转矫正。这里面的'crop'意思是不改变图片尺寸大小。
if abs(angle_1)>=0.1
pic_1=imrotate(~A,-(angle_1),'bilinear','crop');
else
pic_1=~A;
end
9.最后,将处理好的图片存储到准备好的文件夹中。
本方法利用的就是页眉横线,没有页眉横线的文档该处理方法不适用。而且本文所述方法仅适用于纯黑白的pdf文档。这里有一点要注意就是matlab的imread函数读进去的图像是uint8精度的,所以说如果你的图像是uint16的就要提前转换一下,转成uint8,转换的方法详见下面的连接。