Opencv:Mat 和VDMA数据位数以及VGA数据位数的关系

来源:互联网 发布:dsc分析软件 编辑:程序博客网 时间:2024/06/06 02:36

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.elemSize1A.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,使用下面的depthdepth 矩阵中元素的一个通道的数据类型,这个值和type是相关的。例如 typeCV_16SC2,一个2通道的16位的有符号整数。那么,depth则是CV_16S。depth也是一系列的预定义值, type的预定义值去掉通道信息就是depth值: CV_8U CV_8S CV_16U CV_16S CV_32S CV_32F CV_64FelemSize 矩阵一个元素占用的字节数,例如:typeCV_16SC3,那么elemSize = 3 * 16 / 8 = 6 byteselemSize1 矩阵元素一个通道占用的字节数,例如: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 Channelrgb_reg[10:5] <= s00_axis_vga_tdata[15:10]; //GREEN Channelrgb_reg[15:11] <= s00_axis_vga_tdata[23:19]; //BLUE Channel--create a new 640x480 imageMat 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 )
0 0
原创粉丝点击