天天看點

java opencv bytearray轉mat_OpenCV中Mat資料類型及互相轉換

java opencv bytearray轉mat_OpenCV中Mat資料類型及互相轉換

前言

很多人不重視Mat的資料類型,其實,資料類型不對往往會導緻溢出、截斷等各種問題,使得計算結果看起來不對,讓人陷入迷茫。這篇文章我們來深入聊聊Mat的資料類型以及他們之間的轉換。

Mat有的資料類型

OpenCV的文檔中列出來的資料類型一共有30種,如下表對應。

java opencv bytearray轉mat_OpenCV中Mat資料類型及互相轉換

但實際上,大于30的,比如CV_8UC5,這種是可以自己定義的。在程式的開頭用一句宏來定義即可。

#define CV_8UC4 CV_MAKETYPE(CV_8U,4)
#define CV_8UC(n) CV_MAKETYPE(CV_8U,(n))
           

隻要認識到,最關鍵的資料類型其實隻有0~6,其他的,都是從0~6擴充通道而已,至于擴充幾維,按照你的實際情況來就好。這裡再解釋一下,0~6的資料類型對應的資料範圍:

無符号8bit整型(最常用):Unsigned 8bits uchar 0~255

IplImage: IPL_DEPTH_8U

Mat: CV_8UC1, CV_8UC2, CV_8UC3, CV_8UC4

有符号8bit整型:Signed 8bits char -128~127

IplImage: IPL_DEPTH_8S

Mat: CV_8SC1,CV_8SC2,CV_8SC3,CV_8SC4

無符号16bit整型:Unsigned 16bits ushort 0~65535

IplImage: IPL_DEPTH_16U

Mat: CV_16UC1,CV_16UC2,CV_16UC3,CV_16UC4

有符号16bit整型:Signed 16bits short -32768~32767

IplImage: IPL_DEPTH_16S

Mat: CV_16SC1,CV_16SC2,CV_16SC3,CV_16SC4

有符号32bit整型:Signed 32bits int -2147483648~2147483647

IplImage: IPL_DEPTH_32S

Mat: CV_32SC1,CV_32SC2,CV_32SC3,CV_32SC4

32bit浮點數:Float 32bits float -1.18*10-38~3.40*10-38

IplImage: IPL_DEPTH_32F

Mat: CV_32FC1,CV_32FC2,CV_32FC3,CV_32FC4

64bit浮點數:Double 64bits double

Mat: CV_64FC1,CV_64FC2,CV_64FC3,CV_64FC4

幾種類型之間轉換

要遵循幾個原則:

  • 在從小的資料範圍轉向大的資料範圍時,必須先改變類型:

以 CV_8U轉為CV_16U為例~

mat.convertTo(mat,2); //代表的是16U,注意,轉類型的時候不需要考慮通道
mat = mat * 257; //8bit的資料乘以257就轉為了16bit
           

從大範圍轉小範圍,要先轉再改變類型。還是以16U轉8U為例:

out = mat / 257;
out.convertTo(out, CV_8U);
           
  • 整數類型轉小數類型。

先轉類型再轉資料,遵循這個原則~

Mat img = imread("before.png",IMREAD_UNCHANGED);
cout<<img.type()<<endl;
//先轉為32F
img.convertTo(img, 5);
//再轉為小數
img = img / 65535;
           

平常我們對Mat做一些比較複雜的運算,都需要搞清楚參數的範圍,最好轉為32F的來進行複雜計算,否則可能會因為溢出和截斷而産生莫名其妙的BUG。

結語

以上就是關于OpenCV Mat類型的相關知識。