手寫數字識別問題(4)——圖像處理時常見問題之uint8與double類型詳解

今天,在處理mnist數據集時,遇到一個十分棘手的問題,讀取到test最後一張圖像時,出現了一個很神奇的問題。
原始圖像應該是這樣的:
在這裏插入圖片描述
但是調用函數從’t10k-images.idx3-ubyte’讀取出來卻是這樣的,
在這裏插入圖片描述
剛開始,我以爲二值化閾值過大,但是,利用將原始圖像灰度化得到後的圖像如下圖所示,與上圖大相徑庭。

n=graythresh(I);
I=im2bw(I,n);%利用灰度閾值二值化

在這裏插入圖片描述
經過多方查閱資料後才得知,是uint8與double沒弄清楚。

matlab中讀取圖片後保存的數據是uint8類型(8位無符號整數,即1個字節),以此方式存儲的圖像稱作8位圖像,相比較matlab默認數據類型雙精度浮點double(64位,8個字節)可以節省存儲空間。圖像矩陣運算時的數據類型是double類型。這麼做一是爲了保證精度,二是如不轉換,在對uint8進行加減時會溢出。
本案例中,

A=imread('1.bmp');

讀取灰度圖像後,圖像以uint8類型存在。
在這裏插入圖片描述
而從’train-images.idx3-ubyte’中讀取出來的矩陣卻是double型,
在這裏插入圖片描述
在這裏插入圖片描述
因此發生了錯誤。如果直接對double之間的數據矩陣I運行imshow(I),我們會發現有時候顯示圖像部分失真或完全失真。
這是因爲imshow()顯示圖像時對double型是認爲在0-1範圍內,即大於1時都是顯示爲白色,而imshow顯示uint8型時是0-255範圍。所以對double類型的圖像顯示的時候,要歸一化到0-1之間。
對double類型的圖像顯示的時候,除了歸一化到0-1之間,也可以將double類型的0-255數據轉爲uint8類型

將double型轉換成uint8型即可。

d=uint8(c);

總結:

由於matlab讀入圖像的數據是uint8,而matlab中數值一般採用double型(64位)存儲和運算。要運算時,所以要先將圖像轉爲double格式的才能運算。

double(I)/255;   %uint轉換成double

如果不轉換,計算會產生溢出。

意思也就是顯示的時候用uint8 ,運算的時候用double

im2uint8uint8 :都是將圖像數據轉化爲uint8 ,前者要求被轉化的數據必須是符合圖像數據標準(如:double [0 1]) ,而uint8則不必,它會自動截斷數據。

im2double 和double
double就是將一個數據的類型轉化爲double ,但是數值不變;
im2double將輸入的uint8或uint16歸一化到[0 1]區間 ,如果輸入是double,則不做任何數值類型和數值大小的處理。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章