
今天的推文,我们主要来介绍matlab中几种绘制动态图像的方法。首先,以之前介绍过的心形图为例,来说明在matlab中如何将绘图过程保存为gif动态图像。
1. Matlab绘制GIF图像
Step1:生成三维心形线坐标 ,三维空间下的心形线方程为:
为了求解满足该方程所有点坐标,首先定义了在xyz坐标轴上[-3,3]范围内分别取101个点,用meshgrid得到101*101*101的三维网格点数据,计算每个网格点上函数
的取值 val ,所有 val 为 0 的点即为心形线坐标点。 Step2:在YOZ平行平面上绘制心形线 ,令X取定值,提取该平面上所有val取值为0的网格点(Y,Z)坐标,绘制心形线。在这里,提取val为0的点,通过提取等值线来实现,(Y,Z)=contourc(val(:,X,:),[0,0]),具体这部分matlab代码为:
for X = 35:67 %提取不同X取值下,与YOZ平行的平面上,f(y,z)取值 plane = reshape(val(:,X,:),101,101); %提取val为0的等值线,即满足f(y,z)=0的坐标点 c_data = contourc(plane,[0,0]); x_data = X*ones(1,c_data(2,1)); %绘制在YOZ平行平面上的心形线 plot3(x_data,c_data(2,2:end),c_data(1,2:end),'r'); axis([30,80,30,80,30,80])axis offEnd
Step3:将图像保存为gif文件 ,在matlab可以使用imwrite将图像保存为gif,但需要将图像数据保存为索引图像。其中,保存第一张图像时,需要创建gif文件,之后的图像全部采用append的方式进行添加即可。保存gif文件的基本框架为: 其中,getframe是为了抓取当前绘制的图像,frame2im函数将当前图形保存为rgb图像,rgb2ind函数将rgb图像保存为索引图像。 所谓索引图像是指一个数据矩阵A,一个颜色映像矩阵Map。其中Map是一个包含三列、若干行的数据阵列,其中每个元素的值均为[0, 1]之间的双精度浮点型数据。Map矩阵的每一行分别表示红色、绿色和蓝色的颜色值。 在MATLAB中,索引图像是从像素值到颜色映射表值的“直接映射”。像素颜色由数据矩阵X作为索引指向矩阵Map进行索引,例如,值1指向矩阵Map中的第一行,值2指向第二行,以此类推。 索引图像的使用解决了图像数据矩阵消耗内存过大的问题,rgb图像需要一个三维数据矩阵才可以表示,索引图像只需要一维数据矩阵和一个map就可以表示了。 Setp4:同理,绘制XOY平行平面和XOZ平面的心形线,并继续保存到gif文件中即可。 完整代码在公众号后台回复“ 动态心形线 ”即可获取。
2. Matlab创建动画线条
我们在绘制动态图像的目的一般是为了展示图像的绘制过程,或者是为了在串行获取数据时,实时展示图像。
为了实现实时绘图的动画,我们需要借助于matlab中的animatedline函数(注意:这是matlab在2014a版本之后才才更新的一个函数,2014a包括2014a之前版本的matlab都不能实现这个功能)。
- an = animatedline 创建一根没有任何数据的动画线条并将其添加到当前坐标区中;
- an = animatedline(x,y) 创建一根包含由 x 和 y 定义的初始数据点的动画线条;
- an = animatedline(x,y,z) 创建一根包含由 x、y 和 z 定义的初始数据点的三维动画线条;
- an = animatedline(___,Name,Value) 使用一个或多个名称-值对组参数指定动画线条属性。例如,'Color','r' 将线条颜色设置为红色。
当然,animatedline创建了一个动画线条,为了让这个线条动起来,我们需要给它继续添加坐标点,这里就需要用到addpoints函数。
- addpoints(an,x,y) 向动画线条an中,添加二维点;
- addpoints(an,x,y,z) 向动画线条an中,添加三维点。
由此,我们写一下,实现动态线条的基本框架:
h = animatedline('Color','r','LineWidth',3);for k = 1:length(x) addpoints(h,x(k),y(k)); end
基于这两个函数,就可以完成上图的动态绘图效果了,结合第一节中介绍的gif文件保存方式,我们还可以将绘图过程输出为gif文件。
t = 0:0.1:2*pi;x = 16*(sin(t)).^3;y = 13*cos(t)-5*cos(2*t)-2*cos(3*t)-cos(4*t);axis off;set(gcf,'color',[1 1 1]);[A,map] = rgb2ind(frame2im(getframe),256);imwrite(A,map,'xin2.gif','LoopCount',65535,'DelayTime',0.1);h = animatedline('Color','r','LineWidth',3);for k = 1:length(x) addpoints(h,x(k),y(k)); axis([-20,20,-20,20]) [A,map] = rgb2ind(frame2im(getframe),256); imwrite(A,map,'xin2.gif','WriteMode','append','DelayTime',0.1);end
3. Matlab动画循环播放
Movie函数可以实现电影动画,一次运行结果可以保存起来进行多次播放,同时可以生成avi视频文件,独立于matlab进行使用。 在进行movie函数创建动画之前,需要用moviein函数保存绘制的图形数据,创建一个足够大的矩阵,使之能够容纳基于当前绘制的图形(此处称为帧)。 当创建了一系列的动画帧后,可以利用movie函数按照指定的速度和次数运行该电影动画。 m ovie函数的调用格式为:
- movie(M) 将矩阵M中的动画帧播放一次;
- movie(M,n) 将矩阵M中的动画帧播放n次;
- movie(M,n,fps) 将矩阵M中的动画帧以每秒fps帧的速度播放n次。
接下来,我们以三维曲面的动态变化为例,展示一下movie函数效果。
本文介绍了几种关于matlab绘制动画的基本函数,在这些基本的函数基础上,可以结合图像处理技术还可以做出更多丰富的动画特效,这些内容可以在之后的推文中慢慢了解。