1. 程式人生 > 其它 >matlab gif動圖的製作

matlab gif動圖的製作

matlab gif動圖的製作

參考資料:

https://zhuanlan.zhihu.com/p/81860696

https://ww2.mathworks.cn/matlabcentral/answers/94495-how-can-i-create-animated-gif-images-in-matlab

https://ww2.mathworks.cn/help/matlab/ref/imwrite.html?s_tid=srchtitle

https://ww2.mathworks.cn/help/matlab/animation-1.html?s_tid=CRUX_lftnav

https://ww2.mathworks.cn/help/matlab/ref/getframe.html

核心函式

  1. imwrite 將影象寫入圖形檔案

    imwrite(A,filename) 將影象資料 A 寫入 filename 指定的檔案,並從副檔名推斷出檔案格式。imwrite 在當前資料夾中建立新檔案。輸出影象的位深取決於 A 的資料型別和檔案格式。對於大多數格式來說:

    • 如果 A 屬於資料型別 uint8,則 imwrite 輸出 8 位值。

    • 如果 A 屬於資料型別 uint16 且輸出檔案格式支援 16 位資料(JPEG、PNG 和 TIFF),則 imwrite 將輸出 16 位的值。如果輸出檔案格式不支援 16 位資料,則 imwrite 返回錯誤。

    • 如果 A 是灰度影象或者屬於資料型別 double

      single 的 RGB 彩色影象,則 imwrite 假設動態範圍是 [0,1],並在將其作為 8 位值寫入檔案之前自動按 255 縮放資料。如果 A 中的資料是 single,則在將其寫入 GIF 或 TIFF 檔案之前將 A 轉換為 double

    • 如果 A 屬於 logical 資料型別,則 imwrite 會假定資料為二值影象並將資料寫入位深為 1 的檔案(如果格式允許)。BMP、PNG 或 TIFF 格式以輸入陣列形式接受二值影象。

      如果 A 包含索引影象資料,則應另外指定 map 輸入引數。

imwrite(A,map,filename)A 中的索引影象及其關聯的顏色圖寫入由 map

filename 指定的檔案。

  • ​ 如果 A 是屬於資料型別 doublesingle 的索引圖片,則 imwrite 通過從每個元素中減去 1 來將索引轉換為從 0 開始的索引,然後以 uint8 形式寫入資料。如果 A 中的資料是 single,則在將其寫入 GIF 或 TIFF 檔案之前將 A 轉換為 double

    imwrite(___,fmt)fmt 指定的格式寫入影象,無論 filename 中的副檔名如何。您可以在任何先前語法的輸入引數之後指定 fmt

    imwrite(___,Name,Value) 使用一個或多個名稱-值對組引數,以指定 GIF、HDF、JPEG、PBM、PGM、PNG、PPM 和 TIFF 檔案輸出的其他引數。您可以在任何先前語法的輸入引數之後指定 Name,Value

  1. getframe

    F = getframe

    F = getframe 捕獲顯示在螢幕上的當前座標區作為影片幀。F 是一個包含影象資料的結構體。getframe 按照螢幕上顯示的大小捕獲這些座標區。它並不捕獲座標區輪廓外部的刻度標籤或其他內容。

    F = getframe(ax)

    F = getframe(ax) 捕獲 ax 標識的座標區而非當前座標區。

    F = getframe(fig)

    F = getframe(fig) 捕獲由 fig 標識的圖窗。如果您需要捕獲圖窗視窗的整個內部區域(包括座標區標題、標籤和刻度線),則指定一個圖窗。捕獲的影片幀不包括圖窗選單和工具欄。

    F = getframe(___,rect)

    F = getframe(___,rect) 捕獲 rect 定義的矩形內的區域。指定 rect 作為 [left bottom width height] 形式的四元素向量。將此選項用於上一語法中的 axfig 輸入引數。

  2. frame2im:該函式功能是”返回與影片幀關聯的影象資料“

    函式語法:[X,map]=frame2im(F),X是索引影象資料,map為關聯的顏色圖。

  3. ind2rgb()

    RGB = ind2rgb(X,map) 將索引影象 X 和對應的顏色圖 map 轉換為 RGB(真彩色)格式

螺旋圖

%畫螺旋圖,製作gif
clear 
close all  %關閉所有圖形視窗
t=0:0.1:6*pi;
x=sin(t);
y=cos(t);
z =2*t;
hh=plot3(x,y,z,'b','linewidth',2);
h = animatedline('color','r','linewidth',1,'marker','>');

filename='dongtu_4.gif';  %圖片名稱

for k = 1:length(t)
% 畫動圖
   addpoints(h,x(k),y(k),z(k))
   drawnow
   pause(0.1)
   
   F = getframe(gcf);    %捕獲顯示在螢幕上的當前座標區作為影片幀
   im = frame2im(F);     %返回與影片幀關聯的影象資料
   [I,map] = rgb2ind(im,256);  % 將資料轉換為rgb格式
   if k == 1
       imwrite(I,map, filename,'GIF', 'Loopcount',inf,'DelayTime',0.1);
   else
       imwrite(I,map,filename,'WriteMode','append','DelayTime',0.1);
   end
end
%imwrite 將 GIF 檔案寫入您的當前資料夾。名稱-值對組 'LoopCount',Inf 使動畫連續迴圈。'DelayTime',1 在每個動畫影象顯示之間指定了0.1秒的時滯

平面簡諧電磁波的傳播

  1. 理論

    參考資料:《大學物理》(任意版本)、《matlab視覺化大學物理學》周群益等著

    根據麥克斯韋方程組,可以推導並將電磁波表示為:

    \(E = E_msin(k*x-w*t)\)

    \(B = B_msin(k*x-w*t)\)

    注意到 1)光速 \(c =\frac{E}{B}\) , 所以只需計算其一即可,可是光速為1

    ​ 2) E與B相互垂直,且 \(\frac{1}{\mu_0}\vec E\times\vec B=\mathbf{\vec S}\) 波印亭向量波的傳播方向和能量傳輸方向

%平面電磁波的傳播
%沿x正方向傳播
%為了方便,設定光速為c=1,則E=B,電場等於磁場
%設電場最大值Em=2
% 設k =1,w=1
clear
close all
Em=2;       %電場強度最大值
x =0:0.05:6*pi;    

tem=zeros(size(x));    %備用,電場與磁場相互垂直,分別在一座標軸上分量為0
E =zeros(size(x));     %初始化空間電場強度數值,全為零

axis([0 ,20 -2 ,2 -2, 2])   %設定座標軸大小
xlabel('傳播方向'),ylabel('電場'),zlabel('磁場')
hold on

% 空間初始電磁場影象
H_E=plot3(x,E,tem,'linewidth',1.5);
H_B=plot3(x,tem,E,'linewidth',1.5);

tem2=~mod(x,0.5);
S_E=stem(x(tem2),E(tem2),'r.');
S_B=stem3(x(tem2),tem(tem2),E(tem2),'b.');

pause  %暫停一下,按空格鍵可繼續,可以停下來用滑鼠調整觀察影象角度
k=1;
filename='dongtu_7.gif';
%製作gif動圖
while k<=length(x)
    
    E= [Em*sin(x(k)),E(1:end-1)];

    set(H_E,'YData',E);
    set(S_E,'YData',E(tem2))  %更新電場影象
    set(H_B,'ZData',E);
    set(S_B,'zData',E(tem2))  %更新磁場影象
    drawnow limitrate
    
    F = getframe(gcf);    %捕獲顯示在螢幕上的當前座標區作為影片幀
   im = frame2im(F);      %返回與影片幀關聯的影象資料
   [I,map] = rgb2ind(im,256);  % 將資料轉換為rgb格式
   if k == 1
       imwrite(I,map, filename,'GIF', 'Loopcount',inf,'DelayTime',0.05);
   else
       imwrite(I,map,filename,'WriteMode','append','DelayTime',0.05);
   end
    k=k+1;
end
drawnow

預設角度:

調整一下觀察角度: