Opencv:Mat 和VDMA數據位數以及VGA數據位數的關係

September 8, 2016
作者:dengshuai_super
出處:http://blog.csdn.net/dengshuai_super/article/details/52468505
聲明:轉載請註明作者及出處。


1.Mat的各項屬性


A.total() //元素的個數
A.elemSize() //元素的大小,如果是8UC3的話,返回3*sizeof(uchar)
A.elemSize1() //如果是8UC3的話,返回sizeof(uchar)
A.type() //元素的數據類型
A.depth()//元素的位數
A.channels()//矩陣的通道數
A.step1() //矩陣的每一行元素的個數,A.step/A.elemSize1
A.size() //矩陣的尺寸
//注意以下是成員變量不是成員函數
A.step //矩陣的一行的字節數
A.rows //矩陣的行數,即高
A.cols //矩陣的列數,即寬

A.isContinuous(); // 返回bool類型表示是否連續存儲
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 CV8UC4
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. 
C1C2C3C4則表示通道是1,2,3,4 
type一般是在創建Mat對象時設定,如果要取得Mat的元素類型,則無需使用type,使用下面的depth

depth 
矩陣中元素的一個通道的數據類型,這個值和type是相關的。例如 typeCV_16SC2,一個2通道的16位的有符號整數。那麼,depth則是CV_16S。depth也是一系列的預定義值, type的預定義值去掉通道信息就是depth值: 
CV_8U CV_8S CV_16U CV_16S CV_32S CV_32F CV_64F

elemSize 
矩陣一個元素佔用的字節數,例如:typeCV_16SC3,那麼elemSize = 3 * 16 / 8 = 6 bytes

elemSize1 
矩陣元素一個通道佔用的字節數,例如:typeCV_16CS3,那麼elemSize1 = 16  / 8 = 2 bytes = elemSize / channels
一般的圖像文件格式使用的是 Unsigned 8bits吧,CvMat矩陣對應的參數類型就是
CV_8UC1,CV_8UC2,CV_8UC3。
(最後的123表示通道數,譬如RGB3通道就用CV_8UC3)

而float32位的,對應CvMat數據結構參數就是:CV_32FC1,CV_32FC2,CV_32FC3...
double64bits,對應CvMat數據結構參數:CV_64FC1,CV_64FC2,CV_64FC3等。

變換這種矩陣單位類型,Mat裏有一個函數convertTo可以辦到:
C++:void Mat::convertTo(OutputArray m, int rtype, double alpha=1, double beta=0 )
rtype 參數就是上述單位類型。

OpenCV中存儲像素的方法,如下,灰度圖(單通道)存儲按行列存儲,

這裏寫圖片描述

三通道RGB存儲方式如下,每列含有三個通道,

這裏寫圖片描述

爲了加快訪問的速度,openCV往往會在內存中將像素數據連續地存儲成一行,isContinus()函數的作用就是用於判斷是否連續存儲成一行。存儲成一行有什麼好處呢?給定這行的頭指針p,則只要使用p++操作就能逐個訪問數據。

因此當判斷存放在一行的時候,可以通過數據指針++很容易遍歷圖像像素:

long nRows = M.rows * M.channels();  // channels()也是Mat中一個常用的函數,用於獲取通道數(RGB=3,灰度=1)
long nCols = M.cols;
uchar *p = M.data;  // 數據指針
if(M.isContinuous())
{
    nCols *= nRows;
    for (long i=0; i < nCols; i++) {
        *p++ = ...; // 像素賦值或讀取操作
    }       
}

2.VDMA、VGA位數設置

這裏寫圖片描述

這裏寫圖片描述

這裏寫圖片描述


3.VDMA位數與Mat的關係

這裏寫圖片描述

-- OV7670 : Expand 16-bit RGB (5:6:5) to 32-bit RGBA (8:8:8:8)
m_axis_tdata <="11111111"  & d_latch(4 downto 0) & d_latch(0) & d_latch(0) & d_latch(0) & d_latch(10 downto 5) & d_latch(5) & d_latch(5) & d_latch(15 downto 11) & d_latch(11) & d_latch(11) & d_latch(11);

--VGA OUTPUT :  24-bit RGB (8:8:8) to 16-bit RGB (5:6:5)
rgb_reg[4:0] <= s00_axis_vga_tdata[7:3];//RED Channel
rgb_reg[10:5] <= s00_axis_vga_tdata[15:10]; //GREEN Channel
rgb_reg[15:11] <= s00_axis_vga_tdata[23:19]; //BLUE Channel

--create a new 640x480 image
Mat dst_rgb(480, 640, CV_8UC4);//RGBA4通道
IplImage dst = dst_rgb;
memcpy((uchar *)dst.imageData,(uchar *)vdmaflVirtualAddressout , 640 * 480 * 4);
imwrite("output_640x480.bmp", dst_rgb); 

--Mat_<uchar>對應的是CV_8U,Mat_<uchar>對應的是CV_8U,Mat_<char>對應的是CV_8S,Mat_<int>對應的是CV_32S,Mat_<float>對應的是CV_32F,Mat_<double>對應的是CV_64F,對應的數據深度如下:

• CV_8U - 8-bit unsigned integers ( 0..255 )

• CV_8S - 8-bit signed integers ( -128..127 )

• CV_16U - 16-bit unsigned integers ( 0..65535 )

• CV_16S - 16-bit signed integers ( -32768..32767 )

• CV_32S - 32-bit signed integers ( -2147483648..2147483647 )

• CV_32F - 32-bit floating-point numbers ( -FLT_MAX..FLT_MAX, INF, NAN )

• CV_64F - 64-bit floating-point numbers ( -DBL_MAX..DBL_MAX, INF, NAN )
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章