主博客:https://blog.csdn.net/Gou_Hailong/article/details/106092705
【日志】
2020/6/15
早就想开这个博客了,一直没有用到 Matlab 读文件,这不最近要用 Matlab 读取 txt 文件,就先把这部分介绍一下。
2020/8/19
加了读文本文件的例子,将文章结构优化了一下,加了读取图片的方法。
2020/8/20
加了写图片文件,nc,excle。
2020/10/29
加入了一个读写geotiff的例子。
2020/11/1
加了一个txt存文件名,之后读txt的例子。
以 txt 为例
常用的主要有以下几种方法:
1.load
/*1.该函数只能加载仅含有数字的文本文件,如果文档中夹杂着字母或者文字,就会报错。
2.支持的分割符有 “,”、“,”、“ ”、“ ”...
3.每行列数必须相等
4.Data 是一个矩阵*/
Data = load("filename.txt");
2.importdata
/*1.既可以读取数据又可以读取字符:
Data.data矩阵里存放的是纯数字,
Data.textdata矩阵里是以文本形式存放的所有数据。
2.支持的分割符有 “ ”、“ ”...
3.个人感觉不太好用*/
Data = importdata("filename.txt");
3.textread
/*它的基本语法是:
[A,B,C,...] = textread(filename,format)
[A,B,C,...] = textread(filename,format,N)
其中filename就是文件名, format就是要读取的格式,A,B,C就是从文件中读取到的数据。
中括号里面变量的个数必须和format中定义的个数相同。 如果每N行相同格式的数据,可采用[A,B,C,...] = textread(filename,format,N)的语法,读取N次。
详细介绍如下博客链接*/
textread(filename,'%s%f-%f-%f%f:%f%f',... %文件名用' ' ,格式
'headerlines',1,... %忽略前1行
'delimiter' ,';'); %分隔符为;
textread用法示例:https://blog.csdn.net/jisuanjiguoba/article/details/79997805
将数据写入 txt 需要用到 fopen、fprintf 函数,这就有点像C、C#了。
FID = fopen(FILENAME,PERMISSION)
/*FID 获取到的文件句柄
FILENAME 文件名
PERMISSION 打开方式*/
fprintf(fid,format,A)
/*fid为文件句柄,指定要写入数据的文件,
format是用来控制所写数据格式的格式符,与fscanf函数相同,
A是用来存放数据的矩阵。*/
help('fopen')
help('fprintf')
doc fopen
doc fprintf
/*上面介绍的比较简单
更详细的介绍可以通过这些命令查看*/
例子1:这个例子是读写文本文件里边存着数据的那类。
先写一下:
clear; clc;
r=1:1:10;
results=[r;pi*r.^2];
fid=fopen('draft.txt','w'); %以写的方式打开/新建一个txt,
fprintf(fid,'%7s %9s\r\n','Radius','Area'); %右对齐占位7,前不够补空格
fprintf(fid,'%3d %11.4f\r\n',results); %占位11,小数点后4位,前不够补空格
results=results';
fprintf(fid,'\n');
fprintf(fid,'%3d %11.4f\r\n',results);
fclose(fid);
这个例子说明了:matlab 写文件是按照列来存取数据的,为了后续读,把后面几行删了
读:
[R,Area]= textread('draft.txt','%3d %11.4f',... %文件名用' ' ,格式
'headerlines',1,... %忽略前1行
'delimiter' ,' '); %分隔符为;
type draft.txt %在命令窗口查看txt
这步得到俩列向量。
例子2:有时候由于批量操作某些文件,但是文件名字规律性不是很强,所以就需要将文件名字存到一个文本文档里边,然后读这个文件来获得文件名,这个例子是针对这种类型的。
soupath='D:\matlab\mat\CHLA\sorce\'; %source
year=[2010 2005 2020 2015];%
soufilename=[soupath,'filename.txt'];
filename=textread(soufilename,'%s'); %将txt中的数据搞成元胞filename
count=-1;
for i=year
count=count+1;
for j=1:3
str1=char(filename(count*4+j)); %注意这行,是将元胞转化为字符串。
soufile=[soupath,str1,'.mat'];
disp(soufile);
end
end
结果如下:
D:\matlab\mat\CHLA\sorce\chla_201001.mat
D:\matlab\mat\CHLA\sorce\chla_201002.mat
D:\matlab\mat\CHLA\sorce\chla_201003.mat
D:\matlab\mat\CHLA\sorce\chla_201501.mat
D:\matlab\mat\CHLA\sorce\chla_201502.mat
D:\matlab\mat\CHLA\sorce\chla_201503.mat
D:\matlab\mat\CHLA\sorce\chla_202001.mat
D:\matlab\mat\CHLA\sorce\chla_202002.mat
D:\matlab\mat\CHLA\sorce\chla_202003.mat
D:\matlab\mat\CHLA\sorce\chla_202501.mat
D:\matlab\mat\CHLA\sorce\chla_202502.mat
D:\matlab\mat\CHLA\sorce\chla_202503.mat
Matlab用来读取图像的函数是imread(),顾名思义image read,同样的道理写图片的函数是imwrite();
图片的格式有(我去,竟然有那么多种图片格式,看来我是孤陋寡闻了)见于百度百科。常见的几种有:jpg, bmp, gif, tif, png等,其中几种简介如下:
格式 | 简介 |
---|---|
BMP格式 | Windows系统下的标准位图格式,未经过压缩,一般图像文件会比较大。在很多软件中被广泛应用. |
JPEG格式 | 也是应用最广泛的图片格式之一,它采用一种特殊的有损压缩算法,将不易被人眼察觉的图像颜色删除,从而达到较大的压缩比(可达到2:1甚至40:1),因为JPEG格式的文件尺寸较小,下载速度快,所以是互联网上最广泛使用的格式! |
GIF格式 | 最大的特点是不仅可以是一张静止的图片,也可以是动画,并且支持透明背景图像,适用于多种操作系统,“体型”很小,网上很多小动画都是GIF格式。但是其色域不太广,只支持256种颜色. |
PSD格式 | Photoshop的专用图像格式,可以保存图片的完整信息,土层,通道,文字都可以被保存,图像文件一般较大。 |
PNG格式 | 与JPG格式类似,网页中有很多图片都是这种格式,压缩比高于GIF,支持图像透明,可以利用Alpha通道调节图像的透明度,是网页三剑客之一Fireworks的源文件。 |
TIFF格式 | 它的特点是图像格式复杂、存贮信息多,在Mac中广泛使用的图像格式,正因为它存储的图像细微层次的信息非常多,图像的质量也得以提高,故而非常有利于原稿的复制。很多地方将TIFF格式用于印刷. |
TGA格式 | TGA的结构比较简单,属于一种图形、图像数据的通用格式,在多媒体领域有着很大影响,在做影视编辑时经常使用,例如3DS MAX输出TGA图片序列导入到AE里面进行后期编辑。 |
EPS格式 | 苹果Mac机的用户则用得较多。它是用PostScript语言描述的一种ASCII码文件格式,主要用于排版、打印等输出工作。 |
Photo=imread(photofilenme);%读的话,这一行就搞定了
Tif=imread('1.tiff'); %例子
下面介绍一下我做的实验:
imread()
读取图片,都得到了91x317x3 uint8
这样一个三维矩阵,之后又用 imshow()
显示图片,看到结果都是一样的。但是,得到的三维矩阵并不是完全相同的,我觉得可能是图片压缩方式不同导致的。至于为啥是三维的,很容易猜到,91x317x3
对应行x列x页
,即宽x长xRGB
imread()
读取图片,得到了298x395x1x71
这样一个四维矩阵,之后又用 imshow()
显示图片,Info=imfinfo('1.gif');
可查询图片信息。为啥第三维不是RGB呢?我晓得了,先看一下Info:Gif=imread('1.gif');%将gif搞到一个四维矩阵中
Info=imfinfo('1.gif');%图片信息。
mat=Gif(:,:,:,1);%第一帧,这时是二维的
colortable=Info(1).ColorTable;%由于是5位,所以是32x3
bit=size(colortable,1);
[a,b]=size(mat);
Rimg=zeros(a,b);
Gimg=zeros(a,b);
Bimg=zeros(a,b);
for i=0:bit-1
j=i+1;%由于mat是从0-31, so...
Rimg(mat==i)=colortable(j,1);%找到mat中等于i的元素位置,然后Rimg相应位置填充元素colortable(j,1)
Gimg(mat==i)=colortable(j,2);
Bimg(mat==i)=colortable(j,3);
end
img=cat(3,Rimg,Gimg,Bimg);%将三个二维矩阵合成一个三维矩阵
imshow(img);
imread()
非常之强大!!总结:
mat=imread(filepath);%将图片读到矩阵mat中
Info=imfinfo(filepath);%查看图片信息。
imshow(mat);%显示图片
img=cat(3,Rimg,Gimg,Bimg);%将三个二维矩阵合成一个三维矩阵
Rimg(mat==i)=colortable(j,1);%找到mat中等于i的元素位置,然后Rimg相应位置填充元素colortable(j,1)
这里提供一个小函数,用来根据二维矩阵(整数)和colortable 来画图。
function showgif(mat,colortable)
bit=size(colortable,1);
[a,b]=size(mat);
Rimg=zeros(a,b);
Gimg=zeros(a,b);
Bimg=zeros(a,b);
for i=0:bit-1
j=i+1;%由于mat是从0-31, so...
Rimg(mat==i)=colortable(j,1);%找到mat中等于i的元素位置,然后Rimg相应位置填充元素colortable(j,1)
Gimg(mat==i)=colortable(j,2);
Bimg(mat==i)=colortable(j,3);
end
img=cat(3,Rimg,Gimg,Bimg);%将三个二维矩阵合成一个三维矩阵
imshow(img);
end
如果要读的tif有好几页图片,可用
Image=zeros(Height,Width,Slice);
for i=1:Slice
Image(:,:,i)=imread(filepath,i); %%一层一层的读入图像
end
更多显示图片的方法:https://blog.csdn.net/Gou_Hailong/article/details/107619919
1.写简单tif, png, jpg, bmp
imwrite(Tif,[num2str(1,'%04d'),'.tif']);
imwrite(Tif,[num2str(1,'%04d'),'.png']);
imwrite(Tif,[num2str(1,'%04d'),'.jpg']);
imwrite(Tif,[num2str(1,'%04d'),'.bmp']);
2.写gif,这里提供一个例子(来源于百度经验)
clear;clc;
figure %新建一张图
axis([0 5 0 2])%定义x轴(从0到5)和y轴的范围(从0到2)
for i=1:4
if i==1
text(i,1,'百','fontsize',40,'color','red');%i=1时,写一个‘百’字
end
if i==2
text(i,1,'度','fontsize',40,'color','green');%i=2时,写一个‘度’字
end
if i==3
text(i,1,'经','fontsize',40,'color','blue'); %i=3时,写一个‘经’字
end
if i==4
text(i,1,'验','fontsize',40,'color','black');%i=4时,写一个‘验’字
end
picname=[num2str(i) '.fig'];%保存的文件名:如i=1时,picname=1.fig
axis off;
hold on % 写后面的字时,不把前面的字冲掉
saveas(gcf,picname) %保存下中间结果,
end
stepall=4;
for i=1:stepall
picname=[num2str(i) '.fig'];
open(picname)
% set(gcf,'outerposition',get(0,'screensize'));% matlab窗口最大化
frame=getframe(gcf);
im=frame2im(frame);%制作gif文件,图像必须是index索引图像
[I,map]=rgb2ind(im,20);
if i==1
imwrite(I,map,'baidujingyan.gif','gif', 'Loopcount',inf,'DelayTime',0.5);%第一次必须创建!
elseif i==stepall
imwrite(I,map,'baidujingyan.gif','gif','WriteMode','append','DelayTime',0.5);
else
imwrite(I,map,'baidujingyan.gif','gif','WriteMode','append','DelayTime',0.5);
end
close all
delete(picname);
end
https://blog.csdn.net/u013921430/article/details/79283305
为了方便看,这里copy 一下:
灰度tiff读写代码
clear all
clc;
filepath='test.tif'; %%图像名称与路径
Info=imfinfo(filepath); %%获取图片信息并判断是否为tif
tif='tif';
format=Info.Format;
if (strcmp(format ,tif)==0)
disp('载入的不是tif图像,请确认载入的数据'); %%确保载入的图像是tiff图像
end
Slice=size(Info,1); %%获取图片z向帧数
Width=Info.Width;
Height=Info.Height;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Image=zeros(Height,Width,Slice);
for i=1:Slice
Image(:,:,i)=imread(filepath,i); %%一层一层的读入图像
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
for i=1:Slice
J=uint8(Image(:,:,i)); %%一层一层写出图像
%%imwrite(J,[num2str(i,'%4d'),'.tif'],'WriteMode','Append');
imwrite(J,[num2str(i,'%04d'),'.tif']);
end
彩色tiff图像读写代码:
clear all
clc;
filepath='test.tif'; %%图像名称与路径
Info=imfinfo(filepath); %%获取图片信息并判断是否为tif
tif='tif';
format=Info.Format;
if (strcmp(format ,tif)==0)
disp('载入的不是tif图像,请确认载入的数据'); %%确保载入的图像是tiff图像
end
Slice=size(Info,1); %%获取图片z向帧数
Width=Info.Width;
Height=Info.Height;
Image=zeros(Height,Width,Slice*3);
for i=1:Slice
Image(:,:,(i-1)*3+1:i*3)=imread(filepath,i); %%一层一层的读入彩色图像
end
%%%%%%%%%%%%%%%%%%%%%
图像处理操作
%%%%%%%%%%%%%%%%%%%%%
for i=1:Slice
J=uint8(Image(:,:,(i-1)*3+1:i*3)); %%一层一层写出图像
%%imwrite(J,[num2str(i,'%4d'),'.tif'],'WriteMode','Append');
imwrite(J,[num2str(i,'%04d'),'.tif']);
end
如何读取tif并且获取其经纬度信息;读取之后还要把它另存为另一个tif呢?这个问题问的可能有点作,但是我今天缺失要实现这个功能,因为我有一张tif的模板图片,还有很多张比较大的图片。我想把所有的图片都裁剪成和模板图片一样的大小,用arcgis或者envi的话会一个一个操作,太枯燥了,所以我想着能否用matlab帮我裁剪。话不多说,直接开整:
file20150='G:\Light\data\annual\2015\20150.tif';
Info0=geotiffinfo(file20150); %将tif的信息都搞到一个叫Info0的结构体中
img0=imread(file20150); %读取图像的灰度信息
第二行,得到的结构体如下:
里边包含的信息比较丰富,像坐标系(GCS)、分辨率(PixelScale)、经纬度(BoundingBox)等等,关于经纬度这个,下面记下笔记,真的很容易忘。
file20150='G:\Light\data\annual\2015\20150.tif';
Info0=geotiffinfo(file20150);
img0=imread(file20150); %数据的读取
lat_min=Info0.BoundingBox(1,2);
lat_max=Info0.BoundingBox(2,2);
lon_min=Info0.BoundingBox(1,1);
lon_max=Info0.BoundingBox(2,1);
GeoRef = georasterref('Rastersize',size(img0),'Latlim',[lat_min,lat_max],'Lonlim',[lon_min,lon_max]);
%数据的写出
SST_Tif = 'G:\Light\data\annual\2015\20151.tif';
%img1=imread(SST_Tif); %数据的读取
%Info1=geotiffinfo(SST_Tif);
geotiffwrite(SST_Tif,img0,GeoRef)
disp('finished');
可见,它是被上下翻转了一下,所以,我们要先提前翻转一下,再写入文件。
ok。再来对比一下,info信息:
可以看到,图片的大小发生了变化,其他信息保持不变。
总结代码如下所示:
file20150='G:\Light\data\annual\2015\20150.tif';
Info0=geotiffinfo(file20150);
img0=imread(file20150); %数据的读取
lat_min=Info0.BoundingBox(1,2);
lat_max=Info0.BoundingBox(2,2);
lon_min=Info0.BoundingBox(1,1);
lon_max=Info0.BoundingBox(2,1);
GeoRef = georasterref('Rastersize',size(img0),'Latlim',[lat_min,lat_max],'Lonlim',[lon_min,lon_max]);
%数据的写出
SST_Tif = 'G:\Light\data\annual\2015\20151.tif';
%img1=imread(SST_Tif); %数据的读取
%Info1=geotiffinfo(SST_Tif);
geotiffwrite(SST_Tif,flipud(img0),GeoRef); %注意,这里上下翻转一下!!!!
disp('finished');
其实 nc 文件也是文本文件,但是是比较专业化那种,matlab 专门提供了读取 nc 文件的函数。
//nc文件的读取
filename='A20160922016121.L3m_MO_SST_sst_4km.nc';
ncdisp(filename);//展示文件包含的信息
Lon = ncread(filename);//读取信息到Lon中
a=xlsread('1.xlsx'); %读
[num,txt,raw]=xlsread(file,2);%num 存数字,txt 存文本,raw 存元胞(包含两者)。第2个表
xlswrite('2.xlsx',a); %写
help.. %更多用法
若出现Excel Worksheet could not be activated.
问题,
解决办法:打开excel,“文件→选项→加载项→管理(位于界面坐下角)→点击选择COM加载项→转到→把可用加载项的√全部去掉“,之后重启 matlab 即可。
vbb文件是啥类型的文件呢?目前没有找到比较正规的解释,我好像是在大二时做行人检测的时候遇到过。vbb直接打开是乱码,所以需要借助一个vbb工具箱,把vbb转换成txt,工具箱链接下面会提供,还有一个数据集当时下的,压缩超nb,128M的直接压成了13M。
工具箱:链接: https://pan.baidu.com/s/1ZdfH1kot7eT8DZbBaS1uYg 提取码: uub8
数据集:链接: https://pan.baidu.com/s/1GpUI4P3lyGkBm56-oMtV4A 提取码: akq4
下好工具箱解压后,将文件夹放在一个不常动的地方,我放在了D:\MATLAB\R2017a\toolbox
中,然后打开matlab,点击set path(设置路劲)
,将vbb路径加进去就行了。测试是否成功的话,就在matlab命令空间敲help vbb
,成功的话就不会报错。vbb转txt的话,下面提供一个函数:
function vbb2txt(file,out)
A = vbb( 'vbbLoad',file);%当然不要拘泥于此函数,具体问题具体分析,可以看看A是啥
c=fopen(out,'w');
for i = 1:A.nFrame
iframe = A.objLists(1,i);
iframe_data = iframe{
1,1};
n1length = length(iframe_data);
for j = 1:n1length
iframe_dataj = iframe_data(j);
if iframe_dataj.pos(1) ~= 0 %pos ?posv
fprintf(c,'%d %s %f %f %f %f \r\n', i, 'person', iframe_dataj.pos(1), iframe_dataj.pos(2), iframe_dataj.pos(3), iframe_dataj.pos(4));
end
end
end
fclose(c);
disp('Finished');
end
第一次接触shp文件是在大一时上CAD时接触的,那时候叫“形文件”。我目前理解中的shp文件有点像矢量图,它存储的是坐标,可无限放大,不会出现马赛克(不知道对不对,2020.8.22)。shp 包括一个主文件,一个索引文件,和一个dBASE表。
文件名 | 后缀 | 描述 |
---|---|---|
主文件 | .shp | 主文件是一个直接存取,变量记录长度文件,其中每个记录描述一个有它自己的vertices列表的shape。 |
索引文件 | .shx | 在索引文件中,每个记录包含对应主文件记录离主文件头开始的偏移, |
dBASE文件 | .dbf | dBASE表包含 feature 一个记录的feature的特征。 |
几何和属性间的一一对应关系是基于记录数目的。在dBASE文件中的属性记录必须和主文件中的记录是相同顺序的。
读写代码
shp=shaperead(filename); //这步搞出来一个shp结构体
shapewrite(shp,filename);//这步搞出来三个文件,如上所述
世界如此简单,更多详见help!
[1] 仙女阳-CSDN博主:https://blog.csdn.net/wangyang20170901/article/details/79617881
[2] 样young-CSDN博主:https://blog.csdn.net/jisuanjiguoba/article/details/79997805
[3] 百度经验-https://jingyan.baidu.com/article/9f63fb917c09ecc8410f0e66.html
[4] 不用先生-CSDN博主:https://blog.csdn.net/u013921430/article/details/79283305
[5] 百度经验:https://jingyan.baidu.com/article/a378c960a47c24b3282830b7.html
[6] csdn_funquiz-CSDN博主:https://blog.csdn.net/qq_38712026/article/details/78783422