一:问题描述
收到小卿的一个求助,他得到一个 misc100.txt (提取码: c2d7) 文件,猜想是一幅图片,于是需要我将其还原成原图,至于目的和缘由不细究。
二:思路及实现过程
打开文件,看到的都是数字,逗号分隔。马上想到应该有很多数字 和矩阵 运算。于是决定采用matlab作为工具进行下一步。
load misc100.txt之后,发现是一个61366*3的矩阵,我们于是认为3列是一个RGB像素点,于是图片有61366 个像素点。我们于是就考虑 这些像素点 是怎么分布的,很幸运,61366 = 503 * 122 于是,我们将 前 122 个类似(255,255,255)的数据当做第一行,接下来 123-244个数据当做第二行,依次进行。后来证明这种想法 是正确的。
然后构造好所需的三维矩阵,显示,发现图片可以显示,但是,还需要镜面反射,对称,和旋转,所幸,这些过程 matlab都提供 了相应函数。具体的代码见下:
三:m文件:
%%
%说明:
%1.运行环境:windows 7 + 32位机器 + matlab R2009b
%2.确保 misc100.txt 和 此m文件 在同一目录下
%带刺的银杏 2015.05.15 于 苏州 (大雨)
%%
clc;clear;
load misc100.txt
temp = misc100; %temp是2维矩阵 61366*3.我们猜想 3代表RGB. 61366可能为长宽像素点的乘积。
A(1,1,1) = 0;
i = 0;
j = 0;
[pix,dimension] = size(temp); %pix 为 61366 = 2 * 61 * 503 ;
if( dimension ~= 3)
disp('输入维数不对!');
return ;
end
width = 2*61; %通过 factor(pix) 可知道大致了解图片的长宽信息。
height = 503 ;
for i = 1:height % 将二位矩阵转化为三维矩阵,为了matlab识别
for j = 1:width
A(i,j,1) = temp(width*(i-1)+j,1);
A(i,j,2) = temp(width*(i-1)+j,2);
A(i,j,3) = temp(width*(i-1)+j,3);
end
end
A(:,:,1) = fliplr(A(:,:,1)); %图片做镜面反射
A(:,:,2) = fliplr(A(:,:,2));
A(:,:,3) = fliplr(A(:,:,3));
B(:,:,1) = A(:,:,1)'; %'图片旋转
B(:,:,2) = A(:,:,2)'; %'
B(:,:,3) = A(:,:,3)'; %'
for i = 1:62 %图片对称
chg = B(i,:,:);
B(i,:,:) = B(123-i,:,:);
B(123-i,:,:)= chg;
end
P = uint8(B); %图片显示
imagesc(P);
四.结果如下
五.小结
过程思路较为清楚,代码量较少,重点在猜想和摸索的过程,需要注意的是 镜面反射和对称,旋转的原理。当然,关于时间效率,比其他语言效率要高很多,还有一个想改进的地方,就是 将二位矩阵转化为三维矩阵 的时候,怎么将 二重循环 转化为 向量计算 仍然是一个 值得去 深究的问题,程序写的不到位的点 还望 收到您的建议和指导!