matlab圖像類型轉換以及uint8、double、im2double、im2uint8和mat2gray等說明


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(I1); % 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,如下:

I0.0255.00.0

  而mat2gray最大值和最小值都是當前矩陣中最大最小的值,如下:
Imin(I)max(I)min(I)

  另外補充一個函數,mat2str()是將數型轉換爲字符串類型,一般在批量處理圖片,給保存圖片格式的名稱中有作用,這樣就不需要格式化sprintf操作了,非常方便。


發佈了76 篇原創文章 · 獲贊 45 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章