数学建模-Matlab学习笔记(十六)数据导入导出

本文最后更新于:December 3, 2021 pm

MATLAB(矩阵实验室)是第四代高层次的编程语言和交互式环境数值计算,可视化和编程。由美国MathWorks公司开发的一种编程语言。用于算法开发、数据可视化、数据分析以及数值计算的高级技术计算语言和交互式环境,主要包括MATLAB和Simulink两大部分。拥有众多的内置命令和数学函数,可以帮助您在数学计算,绘图和执行数值计算方法。

目录

显示文本中的数据

1
type test.txt % 显示test文本中的数据,但必须需要已经在文本所在的目录下。

一.文本

1.导入数据

文本文件包括:CSV、TXT文件。

1.1从文本文件中读入表中(readtable函数)

  1. 使用方法
1
2
t=readtable('文件名字+后缀名') % 文件名的使用只适用 已在文件所在的目录下。
t(1:3,1:3) % 显示特定行和列。显示前3行和前3列。

1.2 从文本文件中读取矩阵(readmatrix函数)

  1. 使用方法
1
t=readmatrix('文件名字+后缀名') % 文件名的使用只适用 已在文件所在的目录下。

1.3 从指定工作表和范围中读取矩阵(readmatrix函数)

在一个表格文件中含有多个表格时,可以使用。

  1. 使用方法
  • 方法一:
1
2
3
4
5
6
7
8
9
opts = detectImportOptions('表文件名+后缀名');
% 必须先运行上述代码,否则会出错。
% 上述代码有时也可以简写为 opts=('表文件名+后缀名')
preview('表文件名+后缀名',opts) %用来输出表的数据,默认是输出第一个表的前8行数据

opts.Sheet='表名' % 需要操作的表名
opts.SelectedVariableNames=[i:j] % 操作第 i 列到第 j 列(即哪些变量的值)。这里的i 和 j是相对于第几个数据,所以前面有空列不影响
opts.DataRange='i:j'; % 操作第 i 行到第 j 行(即输出哪些数据)。这里的i 和 j是相对于第几行的数据,所以前面有空行时是会有影响的,会输出 NAN。
m=readmatrix('表文件名+后缀名',opts)
  • 方法二:
1
2
3
opts = detectImportOptions('表文件名+后缀名');

m=readmatrix('表文件名+后缀名','Sheet','表名','Range','I:J') % Rang:表示要读取的数据部分。I 和 J 表示需要的数据范围内的数据,即 I 和 J 是一个矩阵的左上角和右下角之内的所有数据,如:B2:E23(表示B2到E23之内的所有数据)。

1.4 从文件中读取元胞数组(readcell函数)

  1. 从文本文件中读取元胞数组
1
c=readcell('文件名+后缀名')
  1. 从表格中读取元胞数组
1
2
3
4
5
6
% 读取首表的所有数据
c=readcell('文件名+后缀名')

# 从指定的工作表和范围读取元胞数组
opt=detectImportOptions('表文件名+后缀名');
m=readcell('表文件名+后缀名','Sheet','表名','Range','I:J') % Rang:表示要读取的数据部分。I 和 J 表示需要的数据范围内的数据,即 I 和 J 是一个矩阵的左上角和右下角之内的所有数据,如:B2:E23(表示B2到E23之内的所有数据)。同readmatrix用法一样。

2.导出数据

2.1 写入文本文件

  1. 将表导出到文本文件(writetable函数)
  • 用法一:
1
2
3
4
5
6
7
8
Pitch = [0.7;0.8;1;1.25;1.5];
Shape = {'Pan';'Round';'Button';'Pan';'Round'};
Price = [10.0;13.59;10.50;12.00;16.69];
Stock = [376;502;465;1091;562];
T = table(Pitch,Shape,Price,Stock)

writetable(T,'tabledata.txt');
% 导出到当前目录下,名字为tabledata.txt到文本文件。默认情况,会以逗号分隔数据,将表变量名称作为列标题。
  • 用法二:
1
2
3
4
5
6
7
% 用用法一中的数据实现
rowNames = {'M4';'M5';'M6';'M8';'M10'};
T2 = table(Pitch,Shape,Price,Stock,'RowNames',rowNames)
% RowNames参数 指定行名称。

writetable(T2,'tabledata2.txt','Delimiter','\t','WriteRowNames',true);
% Delimiter参数指定 制表符为分隔符;WriteRowNames参数 包括行名称。
  1. 将元胞数组导出到文本文件(writecell函数)
  • 方法一:
1
2
C = {'Atkins',32,77.3,'M';'Cheng',30,99.8,'F';'Lam',31,80.2,'M'}
writecell(C,'data.dat')
  • 方法二:(fprintf函数)
    将数据写入一个文本中。也可以从一个文本中写入另外一个文件中。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    C = {'Atkins',32,77.3,'M';'Cheng',30,99.8,'F';'Lam',31,80.2,'M'}

    fileID = fopen('mydata.dat','w');
    formatSpec = '%s %d %2.1f %s\n'; % 使用空格分隔每个格式设定符,以指示对输出文件使用空格分隔符。在每行数据的末尾包括换行符 ('\n')。

    %确定 C 的大小,并使用 fprintf 函数一次导出一行数据。然后关闭文件。fprintf 将写入一个空格分隔的文件。
    [nrows,ncols] = size(C);
    for row = 1:nrows
    fprintf(fileID,formatSpec,C{row,:});
    end
    fclose(fileID);

  1. 将数值数组导出到文本文件(writematrix函数)
1
2
A = magic(5)/10 
writematrix(A,'myData.dat','Delimiter',';') % 将分隔符指定为 ';'。

二.图像

2.1 读取(imread函数)

  1. 读取和显示图像
1
2
A = imread('图片名.jpg');
image(A)
  1. 将索引图像转换成RGB
1
2
3
4
5
6
7
8
[X,cmap] = imread('名字.tiff');
% 索引图像 X 是 uint8 类型的 415×312 数组。颜色图 cmap 是 double 类型的 256×3 矩阵,因此索引图像中有 256 种颜色。显示图像。
imshow(X,cmap)

% 将索引图像转换为 RGB 图像。结果为一个 double 类型的 415×312×3 数组。
RGB = ind2rgb(X,cmap);
% 检查 RGB 图像的值是否在 [0, 1] 范围内。
disp(['Range of RGB image is [',num2str(min(RGB(:))),', ',num2str(max(RGB(:))),'].'])
  1. 读取多页 TIFF 文件中的特定图像
1
[X,map] = imread('corn.tif',3);
  1. 返回 PNG 图像的 Alpha 通道
1
2
[X,map,alpha] = imread('name.png');
whos alpha
  1. 读取 TIFF 图像的指定区域

用表示要读取的区域边界的向量元胞数组指定 ‘PixelRegion’ 参数。第一向量指定要读取的行范围,第二向量指定要读取的列范围。

1
2
A = imread('name.tif','PixelRegion',{[1,2],[2,5]});
% imread 读取 name.tif 中 1–2 行和 2–5 列的图像数据,并返回 2×4 数组 A。

2.2 读出(imwrite函数)

  1. 将灰度图像写入 PNG

将一个 50×50 的灰度值数组写入当前文件夹中的 PNG 文件。

1
2
A = rand(50);
imwrite(A,'myGray.png')
  1. 将索引图像数据写入 PNG

将索引图像数组和其关联的颜色图写入 PNG 文件。

1
2
load clown.mat
imwrite(X,map,'myclown.png') % 图像数组 X 和其关联颜色图 map 均加载至 MATLAB工作区。
  1. 用 MATLAB 颜色图写入索引图像

用 MATLAB 内置的颜色图 copper 将图像数据写入新的 PNG 文件。

1
2
3
load clown.mat
newmap = copper(81); %用 81 RGB 向量定义铜色调颜色图。
imwrite(X,newmap,'copperclown.png'); % 在当前文件夹中创建文件 copperclown.png。
  1. 将真彩色图像写入 JPEG

创建真彩色图像数据并将其写入 JPEG 文件。

1
2
3
4
5
6
7
8
9
10
% 创建一个随机 RGB 值的 49×49×3 数组。
A = rand(49,49);
A(:,:,2) = rand(49,49);
A(:,:,3) = rand(49,49);

% 将图像数据写入 JPEG 文件,并用 'jpg' 指定输出格式。使用 'Comment' 参数添加文件注释。
imwrite(A,'newImage.jpg','jpg','Comment','My JPEG file')

% 查看有关新文件的信息
imfinfo('newImage.jpg')
  1. 将多个图像写入 TIFF 文件

将多个图像写入一个多页 TIFF 文件。

1
2
3
4
5
6
7
% 创建两个随机图像数据集 im1 和 im2。
im1 = rand(50,40,3);
im2 = rand(50,50,3);

% 将第一个图像写入新的 TIFF 文件。然后将第二个图像添加至同一文件。
imwrite(im1,'myMultipageFile.tif')
imwrite(im2,'myMultipageFile.tif','WriteMode','append')
  1. 写入 GIF 动画

绘制一系列图、将它们捕获为图像,然后写入 GIF 动画文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
% 绘制y=y^x,其中n=3
x = 0:0.01:1;
n = 3;
y = x.^n;
plot(x,y,'LineWidth',3)
title(['y = x^n, n = ' num2str(n) ])

% 捕获 $n$ 值递增时的一系列绘图。
n = 1:0.5:5;
nImages = length(n);

fig = figure;
for idx = 1:nImages
y = x.^n(idx);
plot(x,y,'LineWidth',3)
title(['y = x^n, n = ' num2str( n(idx)) ])
drawnow
frame = getframe(fig);
im{idx} = frame2im(frame);
end
close;

% 将多个系列的图像显示在一个图窗中。
figure;
for idx = 1:nImages
subplot(3,3,idx)
imshow(im{idx});
end

% 将九个图像保存到一个 GIF 文件中。因为 GIF 文件不支持三维数据,所以应调用 rgb2ind,使用颜色图 map 将图像中的 RGB 数据转换为索引图像 A。要将多个图像添加到第一个图像中,使用参数 'WriteMode','append' 调用 imwrite。
filename = 'testAnimated.gif'; % Specify the output file name
for idx = 1:nImages
[A,map] = rgb2ind(im{idx},256);
if idx == 1
imwrite(A,map,filename,'gif','LoopCount',Inf,'DelayTime',1);
else
imwrite(A,map,filename,'gif','WriteMode','append','DelayTime',1);
end
end

%imwrite 将 GIF 文件写入您的当前文件夹。参数 'LoopCount',Inf 使动画连续循环。'DelayTime',1 在每个动画图像显示之间指定了一秒的时滞。

三.视频

3.1 读入

  1. 创建 VideoReader 对象并读取视频
1
2
3
4
5
6
7
v = VideoReader('xylophone.mp4');
% 读取视频中的所有帧,一次一帧。
while hasFrame(v)
frame = readFrame(v);
end
% 显示 readFrame 返回的最后一帧的相关信息。
whos frame
  1. 从特定时间开始读取视频帧
1
2
3
4
5
6
7
8
9
10
11
12
13
% 创建一个视频读取器对象,并从特定时间开始读取视频帧。
v = VideoReader('xylophone.mp4');
% 指定在距视频开头 2.5 秒的位置开始读取。
v.CurrentTime = 2.5;
% 创建一个坐标区对象以显示帧。然后,继续读取和显示视频帧,直到没有可供读取的帧为止。
currAxes = axes;
while hasFrame(v)
vidFrame = readFrame(v);
image(vidFrame, 'Parent', currAxes);
currAxes.Visible = 'off';
pause(1/v.FrameRate);
end

  1. 使用帧索引读取视频帧
1
2
3
4
5
6
v = VideoReader('xylophone.mp4');
frame = read(v,1); % 只读取第一个视频帧。
frame = read(v,Inf); % 只读取最后一个视频帧。
frames = read(v,[5 10]); % 读取第 5 帧到第 10 帧。
frames = read(v,[50 Inf]); % 从第 50 帧开始读取到视频文件结束。

  1. 使用帧索引和时间交替读取视频
1
2
3
4
5
6
7
8
9
10
11
12
13
14
vidObj = VideoReader('xylophone.mp4');
vidObj.CurrentTime

% 通过指定帧索引从视频中读取第 20 帧。然后显示 CurrentTime 属性的值。read 方法会自动更新 CurrentTime 属性,以反映已读到第 20 帧。在此步骤,调用 readFrame 函数将返回第 21 帧。
frame20 = read(vidObj,20);
vidObj.CurrentTime

% 使用 readFrame 方法读取视频的其余帧。readFrame 方法返回对应于 CurrentTime 属性中时间的帧。例如,以下代码读取并显示从第 21 帧开始的帧,并持续到没有更多帧可读取为止
while(hasFrame(vidObj))
frame = readFrame(vidObj);
imshow(frame);
title(sprintf('Current Time = %.3f sec', vidObj.CurrentTime));
pause(2/vidObj.FrameRate);
end

3.2 读出

  1. 创建 VideoWriter 对象并写入视频
1
2
3
4
5
6
7
% 创建一个随机数据数组,为输出文件创建 VideoWriter 对象,然后将该数组写入视频。
A = rand(300);
% 创建一个 VideoWriter 对象以写入名为 newfile.avi 的 Motion JPEG AVI 文件,然后打开该文件以进行写入。
v = VideoWriter('newfile.avi');
open(v)
writeVideo(v,A) % 将数据矩阵 A 写入视频文件。
close(v) % 关闭文件。
  1. 为未压缩的 AVI 指定描述文件并写入视频
1
2
3
4
5
6
7
8
% 使用指定的描述文件创建一个视频对象,创建包含一个 RGB 图像的数组,然后将该数组写入视频文件。
v = VideoWriter('newfile.avi','Uncompressed AVI');
open(v)
% 创建一个包含来自示例静态图像 peppers.png 的数据的数组。将 A 中的图像写入视频文件。
A = imread('peppers.png');
writeVideo(v,A)
close(v)

  1. 从动画创建 AVI 文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
% 按以下步骤将一组帧写入压缩的 AVI 文件:生成一组帧,为要写入的文件创建视频对象,然后将帧写入视频文件。设置坐标区和图窗属性,以生成视频帧。
Z = peaks;
surf(Z);
axis tight manual
set(gca,'nextplot','replacechildren');
% 为输出视频文件创建 VideoWriter 对象并打开该对象以进行写入。
v = VideoWriter('peaks.avi');
open(v);
% 生成一组帧,从图窗中获取帧,然后将每一帧写入文件。
for k = 1:20
surf(sin(2*pi*k/20)*Z,Z)
frame = getframe(gcf);
writeVideo(v,frame);
end

close(v);