弄明白OpenCV中的CvType各種參數意義以及相關方法
1. 前言
本篇內容基于java環境下,介紹OpenCV 4.6.0v 中創建 Mat 對象時傳遞的 CvType 參數。
如果你不太能理解CvType.CV_8UCX,CvType.CV_8SCX,CvType.CV_16UCX,CvType.CV_16SCX等
等參數的作用和意義。
那么,這篇文章 一文弄明白 OpenCV Mat 中通道channels的作用 可以幫你解惑。
以下內容基于OpenCV SDK 4.6.0v
2. CvType
這個類型主要是用來定義Mat中的數據類型的。常見使用場景就是在創建Mat的時候,進行定義。
那么CvType這個類型會定義哪些參數呢?很簡單它決定了Mat中的圖片數據的兩個基本指標:
- 通道channels:也就是mat.channels() 返回的值只能是1~4 這三個參數。
- 深度depth:也就是mat中每個像素參數的儲值范圍。該值存儲在每個通道中的byte[]數組中,每個數組中的數值的范圍就是由深度進行決定的。
關于通道的概念,我前面有篇文章介紹過https://zinyan.com/?p=493。如果不太了解通道的概念可以閱讀上篇內容。
2.1 深度-depth
我們通過CvType源碼可以看到,OpenCV已經定義好了8種深度參數:
上面名稱中的8U,8S,16U,16S,32S,64F,16F等等前面的數字代表了比特數
也就是說:8bite,16bite,32bite,64bite。用來定義取值范圍,后面的字母U,S,F代表了符號和精度。
- U : unsigned int , 無符號整形,也就正整數
- S : signed int , 有符號整形,包括負數和正數,但是都是整數
- F : float , 單精度浮點型,也就是帶小數點。(PS:Float類型本身是支持負數的)
所以結合定義我們就能理解:
- CV_8U:是一個8位正整數,代表參數的取值范圍 0~255
- CV_8S:是一個8位正負數,代表參數的取值范圍 -128~127
- CV_16U:是一個16位正整數,代表參數的取值范圍 0~65535
- CV_16S:是一個16位正負數,代表參數的取值范圍 -32768~32767
- CV_16F:是一個16位浮點數,代表參數的取值范圍 -65504 ~ 65504
- CV_32S:是一個32位正整數,代表參數的取值范圍 2147483648~2147483647
- CV_32F:是一個32位浮點數,代表參數的取值范圍 1.18x10^-38^~3.40x10^38^
- CV_64F:是一個64位浮點數,代表參數的取值范圍 2.23x10^-308^~1.79x10^308^
PS:關于浮點數的精度問題和范圍問題,大家可以搜索更詳細的。上面的參數范圍通過網絡匯總得到的。
2.2 通道-channels
在OpenCV定義中,通道數最大為4,最小為1.體現在代碼中,也就是CvType類中定義的C1,C2,C3,C4了。
- C1:代表單通道
- C2:代表雙通道
- C3:代表三通到
- C4:代表四通道
在OpenCV中,一個像素點的顏色值采用duble[] 雙精度浮點數組存儲。
而通道就定義了這個double[] 數組的長度。
例如圖片是一個RGB格式的彩色圖片,那么圖片中的一個像素就需要R,G,B三個值混合才能確定具體顏色。
我們就需要一個double[3]的數組來記錄下分別記錄下該像素點下面的R,G,B的值分別是多少。
所以這張圖片采用的就是C3三通道。
而RGB通常是0~255范圍的整數。
OpenCV就通過我們上面介紹的深度來表示顏色的取值范圍。
兩者結合起來就是:
CvType.CV_8UC3 :表示三通道,每個通道內參數的取值范圍為8位正整數,也就是0~255
最后,我們結合Mat創建時的參數來理解就是:
歸納一下,CvType定義的都是Mat中的數據存儲的類型。
定義了Mat存儲的像素值是由多少個,每個像素值的取值范圍是多少。
因為針對Mat的各種算法都是處理的每個像素點的數值。處理數值進行計算,就需要告訴算法每個數值的取值范圍是多少。
3. 其他
假如Mat是通過外部傳入過來的。我們如何確定Mat的通道數和每個數值的取值范圍呢?
CvType中提供了相關的查詢方法,可以讓我們通過type類型進行轉換為相應的類型值。
示例如下:
除此之外還可以進行通道數查詢。
3.1 廢棄 CV_USRTYPE1
關于CvType.CV_USRTYPE1? 的值已經等同于CV_16F?了。所以該參數也被打上了@deprecated注解。代表已經被廢棄
建議大家不要使用。
3.2 ELEM_SIZE 方法
CvType中的其他方法都比較好理解。最后就有一個public static final int ELEM_SIZE(int type) 方法
該方法傳遞type值。也就是所謂的CvType.CV_8UC1等參數值。
然后返回的是一個int變量。
該方法返回的變量是為了表示每個通道中的參數的字節數。1字節表示8bit,也就是8位。
所以我們如果是CV_8U,CV_8S,直接返回通道數就可以了。
如果是16位的數據,就需要返回2*channels?,32位就需要4*channels?,64位需要8*channels。
4.小結
到這里關于OpenCV中的CvType的介紹就結束了。
我們如果在使用過程中出現了有關于CvType的錯誤。那么大部分情況下都在于我們對于CvType的陌生造成的。
或者使用了對于通道和深度有要求的算法造成錯誤。