OPENCVMAT类详解

上传人:mg****2 文档编号:122125404 上传时间:2020-03-01 格式:DOCX 页数:16 大小:42.40KB
返回 下载 相关 举报
OPENCVMAT类详解_第1页
第1页 / 共16页
OPENCVMAT类详解_第2页
第2页 / 共16页
OPENCVMAT类详解_第3页
第3页 / 共16页
OPENCVMAT类详解_第4页
第4页 / 共16页
OPENCVMAT类详解_第5页
第5页 / 共16页
点击查看更多>>
资源描述

《OPENCVMAT类详解》由会员分享,可在线阅读,更多相关《OPENCVMAT类详解(16页珍藏版)》请在金锄头文库上搜索。

1、类 Mat导言OpenCV c + + n 维稠密数组类类 CV_EXPORTS Matpublic:/ / 很多的方法./*!包括几位字段:-神奇的签名-连续性标志-深度(Note:应该是位深)-通道数*/int flags;(Note :目前还不知道flags做什么用的)/!数组的维数, = 2int dims ;/!行和列的数量或 (-1,-1) 此时数组已超过 2 维int rows,cols;/!指向数据的指针uchar *data ;/!指针的引用计数器 ;/ / 阵列指向用户分配的数据时,当指针为 NULLint * refcount ;/ / 其他成员.;Mat类表示一个 n

2、维的密集数值单通道或多通道数组。它可以用于存储实数或复数值的向量和矩阵、灰度或彩色图像、体素、向量场、点云、张量、直方图 (尽管较高维的直方图存储在SparseMat可能更好)。M 数组的数据布局是由阵列 M.step定义的,使元素的地址(i0,。iM.dims-1),其中 0= ik =M.stepi+1 (事实上,M.stepi =M.stepi+1*M.sizei+1)。这意味着2维矩阵是按行存储的,3 维矩阵是由平面存储,以此类推。M.stepM.dims-1 是最小的而且总是等于元素大小M.elemSize()。因此,Mat中的数据布局完全兼容OpenCV 1.x 中CvMat、 I

3、plImage、 CvMatND类型。它也和标准工具包和SDK,如Numpy(ndarray),Win32(独立设备位图)等主流的密集数组类型相兼容,也就是说,与任何使用步进(或步长)来计算像素位置的阵列相兼容。由于这种兼容性,使用户分配的数据创建Mat头以及用OpenCV函数实时处理该头成为可能。有很多不同的方法,创建一个Mat的对象。下面列出了最常见的选项:使用 create(nrows,ncols,type)方法或类似的Mat(nrows,ncols,type ,fillValue)构造函数。一个新的指定了大小和类型的数组被分配。type和cvCreateMat 方法中的type参数具有

4、相同的含义。例如,CV_8UC1 是指一个 8 位单通道阵列,CV_32FC2 指 2 通道(复)浮点阵列,以此类推。/创建一个用1+3j填充的 7 x 7 复矩阵。Mat M(7,7,CV_32FC2,Scalar(1,3) ;/ /现在将 M转换为100 x 60的CV_8UC(15)的矩阵。/ / 旧内容将会被释放M.create(100,60,CV_8UC(15) ;这一章导言中指出,当当前的数组与指定的数组的形状或类型create() 分配唯一的新数组时的形状或类型。创建多维数组:/ / 创建 100 x 100 x 100 8 位数组int sz = 100, 100, 100;M

5、at. bigCube (3,sz,CV_8U,Scalar:all(0) ;它将维度数(= 1)传递给Mat的构造函数,但列数设置为 1时,创建数组将是 2 维的。因此,Mat:dims 始终是=2的(该数组为空时,也可以是 0)。使用的复制构造函数或赋值运算符可以是一个数组或右侧的表达式(请参阅下图)。正像在导言中指出的,数组赋值运算复杂度是O(1)因为当你需要它的时候,它仅复制头和增加引用计数。Mat:clone() 方法可用于获取全(深)的副本数组。为另一个数组的一部分构建头。它可以是单个行、 单个列,几个行,几个列,矩形区域(代数中称为较小值) 的数组或对角线。这种操作也是复杂度为O

6、(1),因为,新头引用相同的数据。实际上,您可以使用此特性修改该数组的一部分例如:/ /第 5行,乘以 3,加到第 3 行,M.row(3) = M.row(3) + M.row (5) * 3 ;/ / 现在将第7列复制到第1列/ / M.col(1) = M.col(7) ;/ / 这个不能实现。Mat M1= M.col(1) ;M.col(7).copyTo(M1) ;/ / 创建一种新的 320 x 240 图像Mat img(Size(320,240),CV_8UC3) ;/ / 选择ROI(region of interest)Mat roi(img,Rect(10,10,100

7、,100) ;/ / 填充 (0,255,0) 的ROI (这是RGB 空间中的绿色);/ / 320 x 240 原始图像将被修改。roi = Scalar(0,255,0) ;由于额外的 datastart 和 dataend 的成员,它们使得用locateROI() 计算子数组在主容器数组中的相对的位置成为可能:Mat A = Mat:eye ( 10, 10, CV_32S);/ / 提取 A 的1 (含)到 3 (不包含)列。Mat B = A(Range:all(),Range(1,3) ;/ / 提取 B 的5 (含)到 9 (不包含)行。/ /即 C A(Range(5,9),

8、Range (1,3)Mat C = B(Range(5,9),Range:all() ;Size size;Point ofs;C.locateROI (size,ofs);/ / size将变为 (width= 10,height= 10),ofs会变为 (x = 1,y = 5)考虑到整个矩阵,如果您需要深层副本,使用子矩阵的sclone() 方法的提取。为用户分配数据创建矩阵头。有利于执行下列操作:1. 使用 OpenCV处理外来的数据(例如,当您执行 DirectShow *lter 或 gstreamer的pro-cessing 模块,等等)。例如:void process_vid

9、eo_frame (const unsignedchar * pixels,int width,int height,int step)Mat img (width,height, CV_8UC3,pixels,step);GaussianBlur (img,img ,Size(7,7),1.5,1.5) ;2.快速初始化小矩阵和/或获取超快的元素的访问。double m3 3 = a,b,c,d,e,f g, h, i;Mat M = Mat(3,3,CV_64F,m).inv() ;本例中用户分配数据的一些很常见情况是从CvMat 和 IplImage 转换到Mat。为达到此目的,有些特殊

10、的构造函数以指向CvMat 或 IplImage 和ag可选参数指示是否数据复制。从Mat到 CvMat 或 IplImage 的后台转换是通过类型转换运算符 Mat:operator CvMat() const 和 Mat:operator IplImage()实现的。operators不要复制数据。IplImage * img = cvLoadImage(greatwave.jpg,1) ;Mat mtx(img) ;/ / IplImage *- MatCvMat oldmat = mtx ;/ / Mat- CvMatCV_Assert (oldmat.cols = = img- wi

11、dth& oldmat.rows = = img- height & &oldmat.data.ptr = = (uchar *) img-imageData & & oldmat.step = = img- widthStep);使用 MATLAB 样式数组初始值设定项zeros()、 ones()、 eye(),例如:/ / 创建具双精度标识矩阵并将其添加到M。M + = Mat:eye (M.rows,M.cols,CV_64F);使用逗号分隔的初始值设定项:/ / 创建 3 x 3 双精度恒等矩阵Mat M = (Mat_ (3,3) 1,0,0,0,1,0,0,0,1) ;使用此方法

12、,您首先调用具有适当的参数的 Mat_类构造函数,然后只要把 运算符后面的值用逗号分隔,这些值可以是常量、变量、 表达式,等等。此外请注意所需的额外的圆括号((Mat_ (3,3) 1,0,0,0,1,0,0,0,1)以免出现编译错误。数组一旦创建起来,它可以自动通过引用计数的机制被管理。如果数组头是在用户分配的数据的基础上构建的,您应该自己处理这些数据。当没有指向它的引用时,数组中的数据将被释放。如果在数组的析构函被调用之前要释放一个由矩阵头指向的数据,请使用Mat:release()。掌握Array类的另一个重要的环节是元素的访问。本手册已经描述了如何计算每个数组元素的地址。通常情况下,不

13、需要在代码中直接使用的公式。如果你知道数组元素类型(它可以使用 Mat:type() 方法检索得到),您可以用以下方式访问二维数组的元素Mij:M.at (i,j) + = 1.f ;假定 M 一个双精度浮点型数组。有几个变体的不同方法来针对不同的维度数进行处理。如果您要处理整行的二维数组,最有效的方式是获取该行的头指针然后只需使用普通的 C运算符:/ / 正矩阵元素之和计算/ / (假定M 是一个双精度矩阵)double sum = 0;for (int i = 0 ;i M.rows ; i + +)const double *Mi = M.ptr (i) ; for (int j = 0

14、; j M.cols ; j + +)sum + = std:max(Mi j,0.) ;以上的操作中,某些操作实际上不依赖该数组的形状。他们只是一个接一个(或多个具有相同的坐标的多个数组中的元素,例如,数组相加)地处理数组元素。这种操作称为 元素指向(element-wise)。检查是否所有的输入/输出阵列是连续的,即有没有间断在每行的结尾,是有意义的。如果是的话,将它们(这些数组)作为单独的一个长行来处理:/ / 计算正矩阵元素,优化的变量的总和double sum = 0;int cols =M.cols,rows = M.rows ;if(M.isContinuous() cols * = rows ; rows = 1 ;for (int i = 0 ;i rows; i + +)const double * Mi = M.ptr (i) ;for (int j = 0; j cols ; j +)sum + = std:max (Mi j,0.) ;对于连续的矩阵来说,外部循环体只需一次执行。所以,开销

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 办公文档 > 教学/培训

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号