OPENCV的MAT类详解.doc

上传人:小** 文档编号:576200 上传时间:2018-10-31 格式:DOC 页数:16 大小:42.54KB
返回 下载 相关 举报
OPENCV的MAT类详解.doc_第1页
第1页 / 共16页
OPENCV的MAT类详解.doc_第2页
第2页 / 共16页
点击查看更多>>
资源描述

《OPENCV的MAT类详解.doc》由会员分享,可在线阅读,更多相关《OPENCV的MAT类详解.doc(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 类表

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

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

4、cvCreateMat 方法中的type 参数具有相同的含义。例如, 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

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

6、,几个列,矩形区域(代数中称为较小值) 的数组或对角线。这种操作也是复杂度为 O(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) ;/ / 选择 RO

7、I(region of interest)Mat roi(img,Rect(10,10,100,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(

8、1,3 ) ;/ / 提取 B 的 5 (含)到 9 (不包含)行。/ /即 C A(Range(5,9 ),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 处理“外来“的数据(例如,当您执行 Dir

9、ectShow *lter 或 gstreamer的 pro-cessing 模块,等等)。例如:void process_video_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

10、,m).inv() ;|本例中用户分配数据的一些很常见情况是从 CvMat 和 IplImage 转换到 Mat。为达到此目的,有些特殊的构造函数以指向 CvMat 或 IplImage 和 ag可选参数指示是否数据复制。从 Mat 到 CvMat 或 IplImage 的后台转换是通过类型转换运算符 Mat:operator CvMat() const 和 Mat:operator IplImage()实现的。operators 不要复制数据。IplImage * img = cvLoadImage(“greatwave.jpg“,1) ;Mat mtx(img) ;/ / IplImage

11、 *- MatCvMat oldmat = mtx ;/ / Mat- CvMatCV_Assert (oldmat.cols = = img- width使用 MATLAB 样式数组初始值设定项 zeros()、 ones()、 eye(),例如:/ / 创建具双精度标识矩阵并将其添加到 M。M + = Mat:eye (M.rows,M.cols,CV_64F);使用逗号分隔的初始值设定项:/ / 创建 3 x 3 双精度恒等矩阵Mat M = (Mat_ (3,3) (3,3)(i,j) + = 1.f ;假定 M 一个双精度浮点型数组。有几个变体的不同方法来针对不同的维度数进行处理。如

12、果您要处理整行的二维数组,最有效的方式是获取该行的头指针然后只需使用普通的 C运算符:/ / 正矩阵元素之和计算/ / (假定 M 是一个双精度矩阵)double sum = 0;for (int i = 0 ;i (i) ;|for (int j = 0; j (i) ;for (int j = 0; j it =M.begin (),it_end = M.end () ;for(; it! = it_end ; +it)sum+ = std:max (*it,0.);矩阵迭代器是随机存取的迭代器,所以他们可以被传递给任何 STL 算法,包括 std:sort()。矩阵表达式这是已经实现的可

13、以组合在任意复杂的表达式中的矩阵运算操作, (此处 A 、B 的表示矩阵 (Mat)、 s 表示标量(Scalar),alpha 为实数标量 (双精度型):加法、减法、求反: A + B + A-B、 A + s、 A-s、 s + A、 s-A、-A;|缩放: A * 阿尔法每个元素乘法和除法: A.mul (B)、 A / B,alpha/A矩阵相乘: A * B大动脉转位: A.t() (指在)矩阵反演和伪反演,求解线性系统和最小二乘问题:A.inv(method) ( A-1) , A.inv(method)*B ( X: AX=B)比较: cmpop B、 cmpop alpha、

14、alpha cmpop A,其中 cmpop 是以下几种运算符之一: , =,= =,! =, () 构造函数将结果强制转换为适当的类型。Note:有些逗号分隔初始值设定项和一些其他的运算符可能需要显示调用 Mat();或Mat_();的构造函数来解决可能产生的歧义。以下是一些矩阵表达式的例子:/计算矩阵 A 的伪反演等价于 A.inv(DECOMP_SVD)SVD svd(A);Mat pinvA =svd.vt.t()*Mat:diag(1./svd.w)*svd.u.t();/计算莱文伯格-马夸特算法中的参数的新向量x -= (A.t()*A +lambda*Mat:eye(A.cols

15、,A.cols,A.type().inv(DECOMP_CHOLESKY)*(A.t()*err);/用“Unsharp Mask”算法锐化图像Mat blurred; double sigma = 1, threshold =5, amount = 1;GaussianBlur(img, blurred, Size(), sigma,sigma);Mat lowConstrastMask = abs(img - blurred)explicit Mat:Mat(const VecNote:在当前实现中,下面的代码不会无法按预期的效果工作:Mat A ;.A.row(i) = A.row(j)

16、 ;/ /不起作用发生这种情况是因为 A.row(i) 形成临时矩阵头进一步分配给另一个矩阵头。请记住,每个操作复杂度为 O(1),即没有复制任何数据。因此,如果你预期第 j 行被复制到第 i 行,那么上述赋值不成立。要做到这一点,应该把这种简单的赋值转换到表达式中或使用 Mat:copyTo() 方法:Mat A ;./ / 可行,但看上去有点目的不明确。A.row(i) = A.row(j) + 0;/ / 这是有点儿长,但这是推荐的方法。A.row(j).copyTo(A.row(i) ;Mat:col创建一个具有指定了矩阵头中列数这个参数的矩阵C+: Mat Mat:col(int j) const参数:j 一个 0 基(从 0 开始)的列索引该方法创建一个具有指定了矩阵头中列数这个参数的新矩阵并作为函数返回值。这是一种复杂度为 O(1)的操作,不用考虑矩阵的尺寸大小。新矩阵和原始矩阵共享一份基础数据。参看 Mat:row()说明信息。Mat:rowRange为指定的行 span 创建一个新的矩阵头。C+: Mat Mat:rowRange(int startrow, int endrow) constC+: Mat Mat:rowRange(const Range& r) const

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育专区 > 教案示例

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知得利文库网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号-8 |  经营许可证:黑B2-20190332号 |   黑公网安备:91230400333293403D

© 2020-2023 www.deliwenku.com 得利文库. All Rights Reserved 黑龙江转换宝科技有限公司 

黑龙江省互联网违法和不良信息举报
举报电话:0468-3380021 邮箱:hgswwxb@163.com