弄清楚OpenCV中的CvType各種參數意義以及相關方法

WBOY
發布: 2023-04-14 13:13:03
轉載
1641 人瀏覽過

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中的圖片資料的兩個基本指標:

  1. 通道channels:也就是mat.channels() 傳回的值只能是1~4 這三個參數。
  2. 深度depth:也就是mat中每個像素參數的儲值範圍。該值儲存在每個通道中的byte[]數組中,每個數組中的數值的範圍就是由深度決定的。

關於通道的概念,我前面有篇文章介紹過https://zinyan.com/?p=493。如果不太了解通道的概念可以閱讀上篇內容。

2.1 深度-depth

我們透過CvType原始碼可以看到,OpenCV已經定義好了8種深度參數:

public static final int
 CV_8U = 0,
 CV_8S = 1,
 CV_16U = 2,
 CV_16S = 3,
 CV_32S = 4,
 CV_32F = 5,
 CV_64F = 6,
 CV_16F = 7;
登入後複製

上面名稱中的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創建時的參數來理解就是:

#
//zinyan:创建了一个4*4尺寸的图片。每个像素点存储了一个double[1]的数组,该数组中值的范围为0~255
Mat mat = new Mat(4, 4, CvType.CV_8UC1); //通常用来表示灰度图或黑白图

//zinyan:创建了一个5*5尺寸的图片。每个像素点存储了一个double[3]的数组,该数组中值的范围为0~255
Mat mat1 = new Mat(5, 5, CvType.CV_8UC3); //通常用来表示彩色图

//zinyan:创建了一个6*6尺寸的图片。每个像素点存储了一个double[3]的数组,该数组中值的范围为0~65535
Mat mat1 = new Mat(6, 6, CvType.CV_16UC3); //通常用来表示彩色图,颜色值范围更广。
登入後複製

##歸納一下,CvType定義的都是Mat中的資料儲存的類型。

定義了Mat儲存的像素值是由多少個,每個像素值的取值範圍是多少。

因為針對Mat的各種演算法都是處理的每個像素點的數值。處理數值進行計算,就需要告訴演算法每個數值的取值範圍是多少。

3. 其他

假如Mat是透過外部傳入過來的。我們如何確定Mat的通道數和每個數值的值範圍呢?

CvType中提供了相關的查詢方法,可以讓我們透過type類型轉換為對應的類型值。

範例如下:

Mat mat = new Mat(4, 4, CvType.CV_8UC3);
int depth = CvType.depth(mat.type()); //输出结果值为 0 == CvType.CV_8U

Mat mat1 = new Mat(4, 4, CvType.CV_16SC1);
depth = CvType.depth(mat1.type()); //输出结果值为 3 == CvType.CV_16S
登入後複製

除此之外還可以進行通道數查詢。

Mat mat1 = new Mat(4, 4, CvType.CV_16SC1);
int channels = CvType.channels(mat1.type());//该值为1
登入後複製

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的陌生所造成的。

或使用了對於通道和深度有要求的演算法造成錯誤。

以上是弄清楚OpenCV中的CvType各種參數意義以及相關方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:51cto.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板