前言:
本片博客记录了使用matlab读取tif文件的像素数组、标签信息,以及写tif文件。
问题前瞻:
- 无法对已有的tif文件重新读取和写操作
- 写操作成功,但显示跟原tif文件不一样,有时出现全黑的图片
代码如下:
clear all;
% 读取tif文件标签信息,为下面tag设置做参考
% Info = imfinfo('1.tif');
% 或者
t0 = Tiff('1.tif','r');
tags = ["ImageLength","ImageWidth","SampleFormat","BitsPerSample",...
"SamplesPerPixel","Photometric","RowsPerStrip","PlanarConfiguration"];
for i = 1:length(tags)
tag = getTag(t0, tags(i));
tagValue(1,i) = tags(i);
tagValue(2,i) = tag;
end
%t0Img = read(t0); % bitspersample 为12位!!!!
% 待存储的图像数组,可以为任意二维数组,就以 1.tif 为例
data = imread('1.tif');
min1 = min(min(data));
max1 = max(max(data));
%data = data * 16;
data = uint16(data);
min2 = min(min(data));
max2 = max(max(data));
% imshow(data,[]) % 加[]使适应灰度值的显示
% 生成一个tif对象,为写入数据做准备
mytif = 'demo.tif';
t = Tiff(mytif,'w');
% 设置tif标签信息
tagstruct.ImageLength = size(data,1); % 长度
tagstruct.ImageWidth = size(data,2); % 宽度
tagstruct.SampleFormat = 1; % 对数据类型的解释(1-4)
tagstruct.BitsPerSample = 16; % 像素数值位数,single为单精度,32位系统为32.!!!!=12
tagstruct.SamplesPerPixel = 1; % 像素波段个数,一般为1或3(rgb),遥感图像常大于3
tagstruct.Photometric = 1; % 颜色空间解释方式:最小值表示黑色
tagstruct.RowsPerStrip = 12; %
tagstruct.PlanarConfiguration = 1; %
tagstruct.Software = 'MATLAB'; %生成图片的软件
% 将上述tag信息写入
t.setTag(tagstruct)
% 开始写数据
t.write(data);
% 关闭图片
t.close;
% 检验矩阵是否相同,显示是否正常
img = imread('demo.tif');
imshow(img)
isequal(img,data)
问题解决:
1. 无法对tif图像进行读操作
tif源文件BitsPerSample属性为12位,无法使用matlab中的Tiff直接读取!这也是下面显示图片为全黑的一个原因。
2. 读写成功后的文件,用电脑查看显示为几乎全黑
以上述为例,待存储的图像灰度值数组范围为 0 ~ 4095,这个数字正好是上述12位能够存储的数据范围,即0 ~ 2^12 -1。但上面写tif文件时,设置BitsPerSample为16位(读写tif时都不能为12位,所以用imread读数据,用16位写tif),也就是说能够存储的灰度数据范围为0~2^16-1。
显示为几乎全黑的原因就来了,保存成功后,当用电脑自带的图片浏览器查看图片时,浏览器检测到BitsPerSample为16位,所以就以 0~ 2^16-1 的灰阶显示图片,但实际上,图片的灰度值范围只为 0~ 2^12-1。正常情况下,如果以0~ 2^12 -1灰阶范围来显示图片,最暗为0,最亮为2^12-1,此时为正常,但如果以0~ 2^16-1灰阶来显示数据量为2 ^12 -1的灰度值图像时,同样最暗为0,但此时2^12-1灰度值的像素此时就不是最亮的了,而是最亮的1/16左右,因此会显示为灰色,最大灰度值显示尚且如此,那么整张图可不就显示为几乎全黑了吗。
如果把原始的待存储的图像灰度值数组data*16,也就是使数组灰度值范围等比扩大到 致0~2^16-1范围,最后就会发现,写tif后显示的图片跟原图片几乎一样。
BTW,imshow()函数中,加入[]的意思就是以像素灰度值 min~max的范围显示图片。