1. matlab圖像保存說明
matlab中讀取圖片后保存的數據是uint8類型(8位無符號整數,即1個字節),以此方式存儲的圖像稱作8位圖像,好處相比較默認matlab數據類型雙精度浮點double(64位,8個字節),自然可以節省很大一部分存儲空間。
詳細來說imread把灰度圖像存入一個8位矩陣,當為RGB圖像時,就存入8位RGB矩陣中。例如,彩色圖像像素大小是400*300( 高 * 寬 ),則保存的數據矩陣為400*300*3,其中每個顏色通道值是處於0~255之間。
但是雖然matlab中讀入圖像的數據類型是uint8,而在圖像矩陣運算的時候,使用的數據類型卻是double類型。一是為了保證精度,二是因為如果不轉換,在對uint8進行加減時會產生溢出,可能提示的錯誤為:
Function ‘*’ is not defined for values of class ‘uint8’
1個字節無符號整型最大只能存儲數據為255,對圖片的操作所以很容易溢出。
2. matlab圖像類型轉換
matlab讀入圖像的數據是uint8,而matlab中數值一般采用double型(64位)存儲和運算。所以要先將圖像轉為double格式的才能運算,區別如下:
img = imread('./1.jpg'); % 讀入是unit8型(0~255)數據 I1 = im2double(img); % 把圖像轉換成double精度類型(0~1) I2 = double(img)/255; % uint8轉換成double,作用同im2double
- 1
- 2
- 3
這里補充說明一下,im2double( )和double( )的區別。double( img)就是簡單的數據類型轉換,將無符號整型轉換為雙精度浮點型double,但是數據大小沒有變化,原本數據是0~255之間,轉化后還是0~255。例如原來是255,那么轉換后為255.0,小數位0個數是由double數據長度決定,實際數據大小還是255,只不過這個255已經是double類型空間存儲了,再增加不會發生溢出情況。而im2double(img)則不僅僅是將uint8轉換到double類型,而且把數據大小從0~255映射到0~1區間。
另外需要補充說明下面這種情況:
img = imread('./1.jpg'); I1 = double(img); I2 = im2double(I2); % I2數據依然是0~255,並不是0~1,即I1=I2
- 1
- 2
- 3
因為I1已經是double類型,imdouble不會對double類型數據0~255映射到區間0~1,所以上面im2double操作沒有任何作用,I1和I2相等。
總結如下:函數im2double將輸入轉換成double類型。如果輸入是uint8、unit16 或者是二值的logical類型,則函數im2double 將其值歸一化到0~1之間,當然就是double類型的了。如果輸入本身就是double類型,輸出還是double類型,並不進行映射。
如果已經是double類型的數據需要映射,則進行下面操作即可:
I2 = I1/255;
- 1
3. matlab圖像顯示imshow類型問題
在matlab處理完數據好,我們希望顯示或者imwrite寫入圖片時候,需要注意。如果直接對double之間的數據矩陣I運行imshow(I),我們會發現有時候顯示的是一個白色的圖像。
這是因為imshow()顯示圖像時對double型是認為在0~1范圍內,即大於1時都是顯示為白色,而imshow顯示uint8型時是0~255范圍。所以對double類型的圖像顯示的時候,要么歸一化到0~1之間,要么將double類型的0~255數據轉為uint8類型。解決方法如下:
imshow(I/255); % 將圖像矩陣轉化到0-1之間 imshow(I,[]); % 自動調整數據的范圍以便於顯示 inshow(uint8(I)); % 轉成uint8
- 1
- 2
- 3
4. uint和double數據轉換的深入說明
double和uint8、uint16之間數據轉換有下面的函數:
im2double(); % 將圖像數組轉換成double精度類型 im2uint8(); % 將圖像數組轉換成unit8類型 im2uint16(); % 將圖像數組轉換成unit16類型
- 1
- 2
- 3
當然,當圖像數據是double類型的0~1之間,下面兩者操作是等價的:
I1=im2uint8(I); I2=uint8(round(I*255));
- 1
- 2
但是matlab默認double類型圖片數據是位於0~1之間的,而uint8是位於0~255。所以如果矩陣數據圖像是double類型(0~1之間)可直接im2uint8,這樣不僅完成數據類型轉換,而且將0~1之間映射為了0~255之間的數據。
但是如果圖像矩陣數據是double類型的0~255,直接im2uint8轉換的話,matlab會將大於1的數據都轉換為255,0~1之間的數據才會映射到0~255之間整型的數據。例如下面程序:
img64 = [1,2,3,4]; I8 = im2uint8(img64); % I8結果為[255 255 255 255]
- 1
- 2
5. mat2gray()和im2double()區別
這兩個如果都是對uint8數據操作,區別就在於前者是歸一化操作,歸一化后也在0~1之間,自然結果也是double類型,后者是將數據從0~255映射到0~1。例如:
I = uint8([1,1,2,3]); I1 = mat2gray(I); % 歸一化,I1結果是double型[0,0,0.5,1] I2 = im2double(I); % 映射化,I2結果是double型[0.0039,0.0039,0.0078,0.0118]
- 1
- 2
- 3
可以看出,雖然兩者都是一種歸一化,im2double只不過最大值永遠是常數255,最小值永遠是0,如下:
而mat2gray最大值和最小值都是當前矩陣中最大最小的值,如下:
另外補充一個函數,mat2str()是將數型轉換為字符串類型,一般在批量處理圖片,給保存圖片格式的名稱中有作用,這樣就不需要格式化sprintf操作了,非常方便。