1. 程式人生 > >opencv Mat 資料型別總結

opencv Mat 資料型別總結

      做影象資訊統計的時候,用到了Mat,剛開始預設設定了 CV_8UC1 ,但程式執行後,統計的資訊是在是過於小了,經過除錯檢視,發現總是在255這斷了,重新來過,所以,想到了是不是Mat中定義資料型別出現了問題。果然,在查詢網上的文章後,發現型別定義錯誤,導致資料的重0性。看了博主們的的文章,特做以下歸納。

Mat的常見屬性

  • data  uchar型的指標。Mat類分為了兩個部分:矩陣頭和指向矩陣資料部分的指標,data就是指向矩陣資料的指標。
  • dims 矩陣的維度,例如5*6矩陣是二維矩陣,則dims=2,三維矩陣dims=3.
  • rows  矩陣的行數
  • cols   矩陣的列數
  • size
     矩陣的大小,size(cols,rows),如果矩陣的維數大於2,則是size(-1,-1)
  • channels 矩陣元素擁有的通道數,例如常見的彩色影象,每一個畫素由RGB三部分組成,則channels = 3

下面的幾個屬性是和Mat中元素的資料型別相關的。

  • type 
    表示了矩陣中元素的型別以及矩陣的通道個數,它是一系列的預定義的常量,其命名規則為CV_(位數)+(資料型別)+(通道數)。具體的有以下值: 
    CV_8UC1 CV_8UC2 CV_8UC3 CV_8UC4
    CV_8SC1 CV_8SC2 CV_8SC3 CV_8SC4
    CV_16UC1 CV_16UC2 CV_16UC3
    CV_16UC4
    CV_16SC1 CV_16SC2 CV_16SC3 CV_16SC4
    CV_32SC1 CV_32SC2 CV_32SC3 CV_32SC4
    CV_32FC1 CV_32FC2 CV_32FC3 CV_32FC4
    CV_64FC1 CV_64FC2 CV_64FC3 CV_64FC4

    這裡U(unsigned integer)表示的是無符號整數,S(signed integer)是有符號整數,F(float)是浮點數。 
    例如:CV_16UC2,表示的是元素型別是一個16位的無符號整數,通道為2. 
    C1,C2,C3,C4則表示通道是1,2,3,4 
    type一般是在建立Mat物件時設定,如果要取得Mat的元素型別,則無需使用type,使用下面的depth
  • depth 
    矩陣中元素的一個通道的資料型別,這個值和type是相關的。例如 type為 CV_16SC2,一個2通道的16位的有符號整數。那麼,depth則是CV_16S。depth也是一系列的預定義值, 
    將type的預定義值去掉通道資訊就是depth值: 
    CV_8U CV_8S CV_16U CV_16S CV_32S CV_32F CV_64F
  • elemSize 
    矩陣一個元素佔用的位元組數,例如:type是CV_16SC3,那麼elemSize = 3 * 16 / 8 = 6 bytes
  • elemSize1 
    矩陣元素一個通道佔用的位元組數,例如:type是CV_16CS3,那麼elemSize1 = 16  / 8 = 2 bytes = elemSize / channels

OpenCV Mat資料型別及位數總結


float: 4位元組,6-7位有效數字 -3.4E-38 到 3.4E38
double: 8位元組,15~16位有效數字 -1.7E-308 到 1.7E308

     在OpenCV裡面,許多資料結構為了達到記憶體使用的最優化,通常都會用它最小上限的空間來分配變數,有的資料結構也會因為影象檔案格式的關係而給予適當的變數,因此需要知道它們宣告的空間大小來配置適當的變數。一 般標準的圖片,為RGB格式它們的大小為8bits格式,範圍為0~255,對一個int空間的型別來說實在是太小,整整浪費了24bits的空間,假設有個640*480的BMP檔案空間儲存記憶體,那整整浪費了640*480*3*(32-8)bits的記憶體空間,總共浪費了2.6MB!,也就是那 2.6MB內什麼東西都沒儲存,如果今天以8bits的格式來儲存則只使用到0.6MB的記憶體而已(640*480*3*(8)+54 bits),因此,對於檔案格式的對應是一件很重要的事。
在這邊除了要考慮bits的空間大小外,還要考慮使用型別的正負號的問題,一般的影象檔案是不存在負號的,如果今天即使選則正確的空間大小,可是出現的結果卻是負的,那就功虧一簣了。這裡除了Float及double型別,char,int,short int都是用二的補數表示法,它們不具正負號bit,而Float,double則是用IEEE 754,在第32bit,64bit上有一個正負號bit.


TIPS: A Mapping of Type to Numbers in OpenCV
C1 C2 C3 C4
CV_8U 0 8 16 24
CV_8S 1 9 17 25
CV_16U 2 10 18 26
CV_16S 3 11 19 27
CV_32S 4 12 20 28
CV_32F 5 13 21 29
CV_64F 6 14 22 30

Unsigned 8bits uchar 0~255
IplImage: IPL_DEPTH_8U
Mat: CV_8UC1, CV_8UC2, CV_8UC3, CV_8UC4

Signed 8bits char -128~127
IplImage: IPL_DEPTH_8S
Mat: CV_8SC1,CV_8SC2,CV_8SC3,CV_8SC4

Unsigned 16bits ushort 0~65535
IplImage: IPL_DEPTH_16U
Mat: CV_16UC1,CV_16UC2,CV_16UC3,CV_16UC4

Signed 16bits short -32768~32767
IplImage: IPL_DEPTH_16S
Mat: CV_16SC1,CV_16SC2,CV_16SC3,CV_16SC4

Signed 32bits int -2147483648~2147483647
IplImage: IPL_DEPTH_32S
Mat: CV_32SC1,CV_32SC2,CV_32SC3,CV_32SC4

Float 32bits float -1.18*10-38~3.40*10-38 
IplImage: IPL_DEPTH_32F
Mat: CV_32FC1,CV_32FC2,CV_32FC3,CV_32FC4

Double 64bits double 
Mat: CV_64FC1,CV_64FC2,CV_64FC3,CV_64FC4

Unsigned 1bit bool
IplImage: IPL_DEPTH_1U