意义:破碎文件的拼接在司法物证复原、历史文献修复以及军事情报获取等领域都有着重要的应用。目前发现对碎纸片的拼接大部分由人工完成,准确率较高,但耗费大量人力财力及时间,效率很低。随着计算机技术的发展,人们试图开发碎纸片的自动拼接技术,以提高拼接复原效率。现先对仅纵切的碎纸片进行研究,开发出利用计算机,更便捷快速拼接碎纸片的方法。
碎纸拼接技术及项目背景
为从民主德国时期安全部门的档案碎片中寻找秘密,德国政府自1991年起开始着手还原这些档案。一直到2007年,负责整理这些档案碎片的部门一直采取手工还原的方式,工作人员将碎片铺在大桌子上,通过人名和签名等痕迹将它们拼凑起来。历经17年,25名工作人员已将350袋碎片拼好,但等待它们的还有106万袋,按这个速度,他们要花几个世纪才能完成任务。德国政府决定花费835万美元,准备用计算机软件将约600万块碎纸片拼接起来[1]。同样,2011年美国国防部高级研究项目局发起“拼图挑战”,谁最先将5份切碎的文件拼凑起来将获得5万美元奖金。此举旨在希望有人能够开发计算机算法,解决文件拼接问题,方便美国军方读取战场上所获文件碎片的内容[2]。因此,开展对碎纸片的自动拼接复原技术的研究有着重要的现实意义。
根据以上科学知识的研究,首先对碎纸片拼接技术建立数学建模。
由于所给碎纸片为黑字白底,仅黑白两种颜色,可以将其断定为灰度图像,从而无需将其转换为灰度图像。如果所给图像为彩色图像,则需要用rgb2gray()函数将彩色图像转换为灰度图像后再进行研究计算。
首先将灰度图像使用imread()函数转换为灰度值矩阵,由于图片为1980*72的尺寸,故得到的灰度值矩阵为1980行72列。
经分析可知,两张碎纸片若能无缝拼接,则这两张碎纸片之间的关系为,左边碎纸片对应的灰度值矩阵的最后一列与右边碎纸片对应的灰度值矩阵的第一列相似度最大,在忽略边缘效应的情况下可以认为这两列的值是完全相等的。故设计一段程序使之按照这种规律循环。由此可以判定出我们所需要的只是每个灰度值矩阵中的第一列和最后一列的数值,通过判断彼此之间的相似度关系可以得出碎纸片拼接顺序。同时,我们可以通过灰度值矩阵的第一列数值判断出第一张待接碎纸片。经过观察,我们发现第008张图片的第一列灰度值均为255,即全白,对于一张完整的印有字体的完整的纸而言,唯有其灰度值矩阵中的第一列和最后一列存在全白,由此可以断定该008图片为第一张待拼接图片。
接下来可以将008图的灰度值矩阵的最后一列作为原始的参考数列,设计算法将该列与其他灰度值矩阵的第一列进行循环比较判断,若判断出某一列的第一列与之相等,则以该列所在矩阵的最后一列作为参考数列,进行接下来的与其他数列的比较,如此循环往复的比较。判断出碎纸片的正确顺序后,用imshow函数对已经排好序的碎纸片进行输出。
应用此程序建立的模型,人工干预次数为1,机器运算次数为17,认为准确率为 16/17,较为成功。 根据上述模型,得到了复原拼接结果,经观察文件汉字笔画,拼接完整,文章文理通顺,条理清楚,碎片边缘间契合完好,且与实际手动拼接所得结果相同。即认为上述模型基本符合条件,在不考虑其他因素影响下,能完成碎纸片的自动拼接,应用于实际生活中。 此模型程序简单,准确率高,只需要在程序执行之前进行一次人工干预,不需要对待拼接图形的全部内容进行详细的分析,可以节省大量的时间和人力,在信息高速发展的今天,有着重要的现实意义。但此模型适用于在文字字数不多,文字文章连贯的,仅进行单方向切割的,简单碎纸片的拼接。
通过对程序的编写,得到各碎纸片的排列顺序,结果如下:
y =
Columns 1 through 15
9 15 13 16 4 11 3 17 2 5 6 10
14 19 12
Columns 16 through 19
8 18 1 7
完整的程序代码见附录。
对排列好的碎纸片进行输出,得到完整的拼接图像如下:
五、参考代码
碎纸拼接完整程序代码如下:
[I1 map]=imread('d:\matlab\000.bmp');II1=im2double(I1);
[I2 map]=imread('d:\matlab\001.bmp');II2=im2double(I2);
[I3 map]=imread('d:\matlab\002.bmp');II3=im2double(I3);
[I4 map]=imread('d:\matlab\003.bmp');II4=im2double(I4);
[I5 map]=imread('d:\matlab\004.bmp');II5=im2double(I5);
[I6 map]=imread('d:\matlab\005.bmp');II6=im2double(I6);
[I7 map]=imread('d:\matlab\006.bmp');II7=im2double(I7);
[I8 map]=imread('d:\matlab\007.bmp');II8=im2double(I8);
[I9 map]=imread('d:\matlab\008.bmp');II9=im2double(I9);
[I10 map]=imread('d:\matlab\009.bmp');II10=im2double(I10);
[I11 map]=imread('d:\matlab\010.bmp');II11=im2double(I11);
[I12 map]=imread('d:\matlab\011.bmp');II12=im2double(I12);
[I13 map]=imread('d:\matlab\012.bmp');II13=im2double(I13);
[I14 map]=imread('d:\matlab\013.bmp');II14=im2double(I14);
[I15 map]=imread('d:\matlab\014.bmp');II15=im2double(I15);
[I16 map]=imread('d:\matlab\015.bmp');II16=im2double(I16);
[I17 map]=imread('d:\matlab\016.bmp');II17=im2double(I17);
[I18 map]=imread('d:\matlab\017.bmp');II18=im2double(I18);
[I19 map]=imread('d:\matlab\018.bmp');II19=im2double(I19);
%将图片转换为灰度矩阵
A=zeros(1980,19);
A(:,1)=II1(:,1);A(:,2)=II2(:,1);A(:,3)=II3(:,1);A(:,4)=II4(:,1);
A(:,5)=II5(:,1);A(:,6)=II6(:,1);A(:,7)=II7(:,1);A(:,8)=II8(:,1);
A(:,9)=II9(:,1);A(:,10)=II10(:,1);A(:,11)=II11(:,1);A(:,12)=II12(:,1);
A(:,13)=II13(:,1);A(:,14)=II14(:,1);A(:,15)=II15(:,1);A(:,16)=II16(:,1);
A(:,17)=II17(:,1);A(:,18)=II18(:,1);A(:,19)=II19(:,1);
%A是每张碎纸片灰度值矩阵的第一列所组成的新矩阵,作为比较数列,
B(:,1)=II1(:,72);B(:,2)=II2(:,72);B(:,3)=II3(:,72);B(:,4)=II4(:,72);
B(:,5)=II5(:,72);B(:,6)=II6(:,72);B(:,7)=II7(:,72);B(:,8)=II8(:,72);
B(:,9)=II9(:,72);B(:,10)=II10(:,72);B(:,11)=II11(:,72);B(:,12)=II12(:,72);
B(:,13)=II13(:,72);B(:,14)=II14(:,72);B(:,15)=II15(:,72);B(:,16)=II16(:,72);
B(:,17)=II17(:,72);B(:,18)=II18(:,72);B(:,19)=II19(:,72);
%B是每张碎纸片灰度值矩阵的最后一列组成的新矩阵,是参考数列
b=II9(:,72);
%经判断008图为第一张待接碎纸片,故将其作为参考数列
[m,n]=size(A);%m为评价的指标数,n为评价对
r=1;
x=zeros(1,n-1);
for k=1:(n-1)
D=A; %A为原始数据
for i=1:n
D(:,i)=abs(D(:,i)-b);
end
mm=max(mmm);
nn=min(nnn);
for i=1:m
for j=1:n
D(i,j)=(nn+0.5*mm)/(D(i,j)+0.5*mm);
end
end
for i=1:n
r(i)=sum(D(:,i));
end
C(k,:)=r;
x(k)=find(C(k,:)==max(C(k,:)));
b=B(:,x(k));
%寻求关联度最大的数,找匹配度
end
for i=1:n-1
y(i+1)=x(i);
end
y(1)=9;
y %图像的位置
%将已排好序的碎纸片进行输出
> I0=imread('d:\matlab\008.bmp');
I1=imread('d:\matlab\014.bmp');
I2=imread('d:\matlab\012.bmp');
I3=imread('d:\matlab\015.bmp');
I4=imread('d:\matlab\003.bmp');
I5=imread('d:\matlab\010.bmp');
I6=imread('d:\matlab\002.bmp');
I7=imread('d:\matlab\016.bmp');
I8=imread('d:\matlab\001.bmp');
I9=imread('d:\matlab\004.bmp');
I10=imread('d:\matlab\005.bmp');
I11=imread('d:\matlab\009.bmp');
I12=imread('d:\matlab\013.bmp');
I13=imread('d:\matlab\018.bmp');
I14=imread('d:\matlab\011.bmp');
I15=imread('d:\matlab\007.bmp');
I16=imread('d:\matlab\017.bmp');
I17=imread('d:\matlab\000.bmp');
I18=imread('d:\matlab\006.bmp');
>> I=[I0,I1,I2,I3,I4,I5,I6,I7,I8,I9,I10,I11,I12,I13,I14,I15,I16,I17,I18];
>> imshow(I)