MATLAB高级图形处理与动画制作
1. 图像保存
在MATLAB中,我们可以使用
imwrite
函数将图像数据保存到文件中。具体的语法格式如下:
imwrite(arrayname, 'filename.format')
其中:
-
arrayname
:存储图像数据的MATLAB数组名称。
-
filename
:用于存储数据的文件名。
-
format
:文件扩展名,如
jpg
或
tif
。
例如,要将RGB图像保存为名为
flowers.jpg
的文件,可以使用以下命令:
imwrite(X, 'flowers.jpg')
如果是索引图像(带有自定义颜色映射的图像),则需要同时保存数组和颜色映射:
imwrite(arrayname, colormap_name, 'filename.format')
以Mandelbrot集为例,保存数组和用于选择图像颜色的颜色映射的代码如下:
imwrite(map, jet, 'my_mandelbrot.jpg')
2. 图形对象
MATLAB使用分层系统来创建图形,基本的绘图对象是图形窗口(Figure),图形窗口可以包含多个不同的对象,如坐标轴(Axes),而坐标轴又可以包含多个不同的对象,如绘图(Plot)。以下是MATLAB图形对象的分层结构:
graph LR
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
A(Root):::process --> B(Figure):::process
B --> C(Annotation Objects):::process
B --> D(Axes):::process
B --> E(Illustration Objects):::process
B --> F(Ul Objects):::process
B --> G(Group Objects):::process
B --> H(Chart and Primitive Objects):::process
D --> I(Plot):::process
2.1 绘图句柄
为绘图分配一个名称(称为句柄)可以方便地让MATLAB列出绘图对象的属性。以下是一个简单的示例:
clear, clc, clf
x = linspace(-10, 10);
y = cos(x);
h = plot(x, y)
title('Trigonometric Function Plot')
xlabel('angle, radians')
ylabel('cos(x)')
在上述代码中,变量
h
是绘图的句柄。在工作区窗口中,它被列为
matlab.graphics.chart.primitive.Line
,并存储了该线条的所有属性。由于没有使用分号抑制输出,代码执行时会返回绘图属性列表。
在旧版本的MATLAB(2014b之前)中,需要使用
get
函数来获取绘图属性:
get(h)
返回的属性列表如下:
| 属性 | 值 |
| ---- | ---- |
| Color | [1x3 double] |
| EraseMode | ‘normal’ |
| LineStyle | ‘-’ |
| LineWidth | 0.5000 |
| Marker | ‘none’ |
| MarkerSize | 6 |
| MarkerEdgeColor | ‘auto’ |
| MarkerFaceColor | ‘none’ |
| XData | [1x100 double] |
| YData | [1x100 double] |
| ZData | [1x0 double] |
可以使用点符号或
set
函数来更改图形对象的属性。例如,将线条颜色更改为红色,可以使用以下两种方法之一:
set(h, 'Color', 'red')
h.Color = 'red'
点符号的一个优点是可以使用补全标签。例如,创建绘图句柄
h
后,输入
h.
并按下制表键,会出现可能的补全列表。
2.2 图形窗口句柄
可以为图形窗口指定一个对象名称(句柄)。假设在名为
Figure 1
的图形窗口中绘制图形,指定句柄的命令如下:
f_handle = figure(1)
使用
get
命令可以返回图形窗口的属性:
get(f_handle)
图形窗口的属性与绘制的线条属性不同。例如,图形窗口的背景颜色默认是
[0.9400, 0.9400, 0.9400]
,表示红、绿、蓝强度相等,结果是浅灰色背景。可以使用点符号或
set
函数更改背景颜色,例如:
f_handle.Color = [0.4, 0.4, 0.4]
set(f_handle, 'Color', [0.4, 0.4, 0.4])
同样,也可以更改图形窗口的名称:
f_handle.Name = 'My Graph'
set(f_handle, 'Name', 'My Graph')
如果没有指定句柄名称,可以使用
gcf
(获取当前图形)命令来确定当前图形,并返回其属性:
get(gcf)
使用
gcf
和
set
命令可以将背景颜色恢复为默认值:
set(gcf, 'Color', [0.94, 0.94, 0.94])
2.3 坐标轴句柄
可以使用
gca
(获取当前坐标轴)函数为坐标轴分配一个对象名称(句柄):
h_axes = gca
使用句柄和
get
命令可以查看坐标轴的属性:
get(h_axes)
坐标轴句柄可用于更改属性,特别是创建自定义坐标轴标签。以下是一个示例,将x轴表示的角度以π的倍数表示:
h_axes.XTick = [-3*pi, -2*pi, -pi, 0, pi, 2*pi, 3*pi];
h_axes.YTick = [-1, -0.5, 0, 0.5, 1];
h_axes.XTickLabel = {'-3\pi', '-2\pi', '-\pi', '0', '\pi', '2\pi', '3\pi'};
h_axes.YTickLabel = {'min = -1', '-0.5', '0', '0.5', 'max = 1'};
h_axes.XTickLabelRotation = 45;
h_axes.YTickLabelRotation = 45;
同样,也可以使用点符号或
set
函数来更改坐标轴属性。
再看另一个示例,假设要绘制一组学生的测试成绩条形图,并将x轴标签设置为学生姓名:
names = char('Holly', 'Steve', 'Fred', 'Olive', 'Mandy', 'John');
scores = [100; 98; 85; 79; 82; 62];
bar(scores);
ax = gca;
ax.XTickLabel = names;
ax.XTickLabelRotation = 45;
ax.FontSize = 14;
ax.FontWeight = 'bold';
title('Scores for Test #1');
xlabel('Students');
ylabel('Percent');
2.4 注释坐标轴
除了前面介绍的三个组件外,绘图中还会添加一个透明层,用于插入注释对象,如线条、图例和文本框。可以通过分配句柄来控制这些注释对象的属性,方法与图形、绘图和坐标轴类似。
2.5 属性编辑器
可以通过选择图形菜单栏中的
View
,然后选择
Property Editor
来交互式地调整属性。在属性编辑器弹出窗口中选择
Property Inspector
,可以访问所有属性。探索属性检查器窗口是了解每个图形对象可用属性的好方法。
3. 动画制作
在MATLAB中,有两种创建动画的技术:
- 重绘和擦除
- 创建电影
3.1 重绘和擦除
通过重绘和擦除来创建动画,需要先创建一个绘图,然后在每次循环中调整图形的属性。以下是一个绘制抛物线动画的示例:
clear, clc, clf
x = -10:0.01:10;
k = -1;
y = k * x.^2 - 2;
h = plot(x, y);
grid on;
axis([-10, 10, -100, 100]);
while k < 1
k = k + 0.01;
y = k * x.^2 - 2;
h.YData = y;
drawnow;
end
在这个示例中,每次循环只重绘图形,而不是每次都创建一个新的图形窗口。使用
YData
对象来分配要绘制的y数据点(x值保持不变)。每次调用
drawnow
函数时,使用
set
函数指定新的y值,从而创建不同的图形。
另一个更复杂的动画示例是模拟一个球在山上滚动。首先,创建一个正弦函数的绘图作为静态背景:
clear, clc
theta = linspace(-pi/2, pi/2, 1000);
x = linspace(0, 20, 1000);
y = 20 * cos(theta);
plot(x, y);
axis([-1, 21, -1, 21]);
hold on;
然后,使用
patch
函数创建一个圆形对象:
theta2 = linspace(-pi, pi);
xc = cos(theta2);
yc = -sin(theta2);
t = patch(xc, yc, 'red');
hold off;
最后,创建一个循环,每次循环重绘圆形:
for j = 1:length(theta)
xnew = xc + x(j);
ynew = yc + y(j);
t.XData = xnew;
t.YData = ynew;
drawnow;
end
运行这段代码时,红色圆形会在正弦函数表示的“山”上滚动。
3.2 电影动画
动画线条的运动计算量不大,容易实现平滑移动。但对于更复杂的曲面图动画,在较慢的计算机上可能会出现卡顿和暂停。为避免这个问题,可以创建一个程序来捕获每一帧,计算完成后将这些帧作为电影播放。
以下是一个产生更复杂曲面图动画的代码示例:
clear, clc
x = 0:pi/100:4*pi;
y = x;
[X, Y] = meshgrid(x, y);
z = 3*sin(X) + cos(Y);
h = surf(x, y, z);
axis([0, 4*pi, 0, 4*pi, -3, 3]);
shading interp;
colormap(jet);
for k = 0:pi/100:2*pi
z = (sin(X) + cos(Y)).*sin(k);
h.Zdata = z;
drawnow;
end
为了避免在较慢计算机上出现卡顿,可采用捕获帧并制作电影的方法,代码如下:
clear, clc
x = 0:pi/100:4*pi;
y = x;
[X, Y] = meshgrid(x, y);
z = 3*sin(X) + cos(Y);
h = surf(x, y, z);
axis([0, 4*pi, 0, 4*pi, -3, 3]);
shading interp;
colormap(jet);
m = 1;
for k = 0:pi/100:2*pi
z = (sin(X) + cos(Y)).*sin(k);
h.Zdata = z;
M(m) = getframe;
m = m + 1;
end
movie(M, 2);
运行这个程序时,实际上会看到电影播放三次:一次是创建时,另外两次是
movie
函数指定的播放次数。这种方法的一个优点是可以在不重新计算的情况下再次播放电影,因为信息存储在数组
M
中。
Mandelbrot集电影示例
创建Mandelbrot图像需要大量计算机资源,可能需要几分钟。如果要对Mandelbrot图像中的某个点进行缩放,可以先进行计算并创建一个电影,以便后续观看。以下是具体步骤:
1. 问题陈述
通过对Mandelbrot集进行缩放来创建一个电影。
2. 输入和输出
- 输入 :完整的Mandelbrot图像。
- 输出 :一个100帧的电影。
3. 简单测试程序
为了测试解决方案,可以先创建一个迭代次数和元素较少的程序:
%Example 14.2 Mandelbrot Image
% The first part of this program is the same as Example 14.1
clear, clc
iterations = 20; % Limit the number of iterations in
% this first pass
grid_size = 50; % Use a small grid to make the
% program run faster
X = linspace(-1.5, 1.0, grid_size);
Y = linspace(-1.5, 1.5, grid_size);
[x, y] = meshgrid(X, Y);
c = x + i*y;
z = zeros(size(x));
map = zeros(size(x));
for k = 1:iterations
z = z.^2 + c;
a = find(abs(z) > sqrt(5) & map == 0);
map(a) = k;
end
figure(1)
h = imagesc(map)
%%New code section
N(1) = getframe; %Get the first frame of the movie
disp('Now let''s zoom in')
disp('Move the cursor to a point where you"d like to zoom')
[y1, x1] = ginput(1) %Select the point to zoom in on
xx1 = x(round(x1), round(y1))
yy1 = y(round(x1), round(y1))
%%
for k = 2:100 %Calculate and display the new images
k %Send the iteration number to the command window
[x, y] = meshgrid(linspace(xx1 - 1/1.1^k, xx1 + 1/1.1^k, grid_size),
linspace(yy1 - 1/1.1^k, yy1 + 1/1.1^k, grid_size));
c = x + i*y;
z = zeros(size(x));
map = zeros(size(x));
for j = 1:iterations
z = z.^2 + c;
a = find(abs(z) > sqrt(5) & map == 0);
map(a) = j;
end
h.CData = map; % Retrieve the image data from the
% variable map
colormap(jet)
N(k) = getframe; % Capture the current frame
end
movie(N, 2) % Play the movie twice
这个版本的程序运行速度快,但返回的是低分辨率图像,可用于验证程序是否正常工作。
4. 最终程序
将迭代次数和网格大小增加,得到最终程序:
clear, clc
iterations = 80; % Increase the number of iterations
grid_size = 500; % Use a large grid to see more detail
X = linspace(-1.5, 1.0, grid_size);
Y = linspace(-1.5, 1.5, grid_size);
[x, y] = meshgrid(X, Y);
c = x + i*y;
z = zeros(size(x));
map = zeros(size(x));
for k = 1:iterations
z = z.^2 + c;
a = find(abs(z) > sqrt(5) & map == 0);
map(a) = k;
end
figure(1)
h = imagesc(map)
%%New code section
N(1) = getframe; %Get the first frame of the movie
disp('Now let''s zoom in')
disp('Move the cursor to a point where you"d like to zoom')
[y1, x1] = ginput(1) %Select the point to zoom in on
xx1 = x(round(x1), round(y1))
yy1 = y(round(x1), round(y1))
%%
for k = 2:100 %Calculate and display the new images
k %Send the iteration number to the command window
[x, y] = meshgrid(linspace(xx1 - 1/1.1^k, xx1 + 1/1.1^k, grid_size),
linspace(yy1 - 1/1.1^k, yy1 + 1/1.1^k, grid_size));
c = x + i*y;
z = zeros(size(x));
map = zeros(size(x));
for j = 1:iterations
z = z.^2 + c;
a = find(abs(z) > sqrt(5) & map == 0);
map(a) = j;
end
h.CData = map; % Retrieve the image data from the
% variable map
colormap(jet)
N(k) = getframe; % Capture the current frame
end
movie(N, 2) % Play the movie twice
这个“完整版”程序在3.0 GHz AMD双核处理器、2.0 GB RAM的计算机上大约需要40秒运行。生成的电影一个周期大约播放10秒。
总结
本文详细介绍了MATLAB中图像保存、图形对象操作以及动画制作的相关知识和方法,具体内容总结如下表:
| 类别 | 具体内容 | 操作方法 |
| ---- | ---- | ---- |
| 图像保存 | RGB图像、索引图像 | 使用
imwrite
函数,根据图像类型选择合适的参数 |
| 图形对象 | 绘图句柄、图形窗口句柄、坐标轴句柄、注释坐标轴、属性编辑器 | 分别使用相应的函数(如
plot
、
figure
、
gca
等)获取句柄,通过
get
查看属性,使用点符号或
set
函数修改属性;通过图形菜单栏的
View
选择
Property Editor
和
Property Inspector
调整属性 |
| 动画制作 | 重绘和擦除、电影动画 | 先创建绘图,在循环中调整图形属性;捕获每一帧,计算完成后作为电影播放 |
通过这些方法和技巧,可以在MATLAB中实现高级的图形处理和动画制作,满足不同的需求。无论是简单的图形绘制,还是复杂的动画展示,都可以借助MATLAB强大的功能来实现。希望读者通过本文的学习,能够更好地掌握MATLAB在图形和动画方面的应用。
graph LR
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
A(图像保存):::process --> B(imwrite函数):::process
C(图形对象):::process --> D(绘图句柄):::process
C --> E(图形窗口句柄):::process
C --> F(坐标轴句柄):::process
C --> G(注释坐标轴):::process
C --> H(属性编辑器):::process
I(动画制作):::process --> J(重绘和擦除):::process
I --> K(电影动画):::process
超级会员免费看
13

被折叠的 条评论
为什么被折叠?



