作者:liuz_notes
來源:CSDN
原文:https://blog.csdn.net/liuz_notes/article/details/83690508
版權聲明:本文為部落客原創文章,轉載請附上博文連結!
MATLAB灰階圖像生成gif
前言
問題來源于我想要制作一個三維圖像的某一個次元的所有切片圖組合而成的gif。首先在網上查閱資料發現現有的方法是用
getframe
函數來實作,但是這樣出來的gif會有白色邊框,我隻想要純圖像的gif,經過簡單的思考,得到了一種新的方法。現将兩種方法總結如下:
getframe截屏法(Reference)
這種方法的思想就是利用一個幀數循環,将每一幀的圖像在figure界面中不斷地更新,同時用
getframe
函數截取目前figure視窗的圖像,類似于QQ截屏(Ctrl+Alt+A)。然後利用
frame2im
函數将截屏轉化為圖像,最後用
rgb2ind
将其轉化為索引圖,逐幀儲存即可。索引圖即為gif的幀圖,想了解更多可以自行百度,這裡不多贅述。
遺憾的是這個函數的截屏會額外截取figure視窗的空白部分,也就是說你的圖像矩陣會比原來的大,且維數不相等。當然,因為我是做純圖像處理,引入了空白部分對我有很大影響。但是如果你是想動态繪制函數圖形,并儲存為gif,大可随便使用。
下面給出灰階圖像gif執行個體:
for pic_num = 1:128
figure(1);
imshow(I(:,:,pic_num));
drawnow;
F = getframe(gcf);
Gif = frame2im(F);
[Gif,map]=rgb2ind(Gif,256);
if pic_num == 1
imwrite(Gif,map,'C:\Users\DELL\Desktop\test.gif','gif', 'Loopcount',inf,'DelayTime',0.05);
else
imwrite(Gif,map,'C:\Users\DELL\Desktop\test.gif','gif','WriteMode','append','DelayTime',0.05);
end
end
然後是我用以上方法生成的gif:

可以看到,正方形圖像周圍有灰色邊框,這就是
getframe
函數所截取的視窗大小。
圖像矩陣處理法(My Method)
因為我要處理的是灰階圖像,不像RGB圖像能直接調用
rgb2ind
函數,生成gif幀圖。是以我查遍了網絡,發現并沒有從灰階圖轉RGB的方法,這是因為RGB圖像有三原色通道,也就是說如果是一副二維圖像,灰階圖隻是一個二維矩陣,而RGB圖是一個三維矩陣,第三維則記錄了R、G、B三色通道資訊。
rgb2ind
函數的輸入參數要求是三維的uint8類型資料,而我隻有二維灰階圖,這怎麼辦呢?
一個思路是用三個變量分别複制灰階圖資訊,然後再将其合并為一個變量,這樣就得到了三維資料。然後将此三維資料用
uint8()
強制轉換為uint8類型。至此,我們就得到了
rgb2ind
函數的參量,可以生成gif了。
此外,可以用任意的一系列二維矩陣生成gif,隻需要對二維矩陣調用
mat2gray()
,将矩陣歸一化生成灰階圖,然後按照上述處理即可。
一個插曲:我原本的資料類型是double,強制轉換為uint8類型後圖像資料丢失,像素值全變成了0,gif漆黑一片。然後我把沒有強制類型轉換的變量作為 rgb2ind
參量,程式并沒有報錯,而且正常生成了gif。是以根據自己的需要強制類型轉換。
代碼如下:
for pic_num = 1:128
[rows,cols]=size(I(:,:,pic_num));
r = zeros(rows,cols);
g = zeros(rows,cols);
b = zeros(rows,cols);
r = double(I(:,:,pic_num));
g = double(I(:,:,pic_num));
b = double(I(:,:,pic_num));
rgb = cat(3,r,g,b);
% rgb = uint8(cat(3,r,g,b));
[Gif,map]=rgb2ind(rgb,256);
if pic_num == 1
imwrite(Gif,map,'C:\Users\DELL\Desktop\test.gif','gif', 'Loopcount',inf,'DelayTime',0.05);
else
imwrite(Gif,map,'C:\Users\DELL\Desktop\test.gif','gif','WriteMode','append','DelayTime',0.05);
end
end
這樣就得到了我想要的無邊框圖像的gif了。
另
關于gif的delay時間,我最小隻設定到了0.005s,如果再小圖像的更新時間會突然變得很長。delay時間的極限還有待探讨。
結語
至此,整篇部落格就結束了,這是我的第一篇部落格,以後我會将我的學習經驗體會以部落格的形式展示出來,用以見證我的成長。Linux之父Linus Torvalds說過一句非常經典的話:
“Talk is cheap. Show me the code.”
參考資料
- https://blog.csdn.net/lusongno1/article/details/78632457
- https://blog.csdn.net/u012260117/article/details/70624764