原文:http://blog.csdn.net/yang_xian521/article/details/7107786

我记得开始接触OpenCV就是因为一个算法里面需要2维动态数组,那时候看core这部分也算是走马观花吧,随着使用的增多,对Mat这个结构越来越喜爱,也觉得有必要温故而知新,于是这次再看看Mat。

Mat最大的优势跟STL很相似,都是对内存进行动态的管理,不需要之前用户手动的管理内存,对于一些大型的开发,有时候投入的lpImage内存管理的时间甚至比关注算法实现的时间还要多,这显然是不合适的。除了有些嵌入式场合必须使用c语言,我任何时候都强烈像大家推荐Mat。

Mat这个类有两部分数据。一个是matrix header,这部分的大小是固定的,包含矩阵的大小,存储的方式,矩阵存储的地址等等。另一个部分是一个指向矩阵包含像素值的指针。

  1. Mat A, C; // creates just the header parts
  2. A = imread(argv[1], CV_LOAD_IMAGE_COLOR); // here we’ll know the method used (allocate matrix)
  3. Mat B(A); // Use the copy constructor
  4. C = A; // Assignment operator

需要注意的是,copy这样的操作只是copy了矩阵的matrix header和那个指针,而不是矩阵的本身,也就意味着两个矩阵的数据指针指向的是同一个地址,需要开发者格外注意。比如上面这段程序,A、B、C指向的是同一块数据,他们的header不同,但对于A的操作同样也影响着B、C的结果。刚刚提高了内存自动释放的问题,那么当我不再使用A的时候就把内存释放了,那时候再操作B和C岂不是很危险。不用担心,OpenCV的大神为我们已经考虑了这个问题,是在最后一个Mat不再使用的时候才会释放内存,咱们就放心用就行了。

如果想建立互不影响的Mat,是真正的复制操作,需要使用函数clone()或者copyTo()。

说到数据的存储,这一直就是一个值得关注的问题,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 )

这里还需要注意一个问题,很多OpenCV的函数支持的数据深度只有8位和32位的,所以要少使用CV_64F,但是vs的编译器又会把float数据自动变成double型,有些不太爽。

还有个需要注意的问题,就是流操作符<<对于Mat的操作,仅限于Mat是2维的情况。

还有必要说一下Mat的存储是逐行的存储的。

再说说Mat的创建,方式有两种,罗列一下:1.调用create(行,列,类型)2.Mat(行,列,类型(值))。例如:

  1. // make a 7x7 complex matrix filled with 1+3j.
  2. Mat M(7,7,CV_32FC2,Scalar(1,3));
  3. // and now turn M to a 100x60 15-channel 8-bit matrix.
  4. // The old content will be deallocated
  5. M.create(100,60,CV_8UC(15));

要是想创建更高维的矩阵,要写成下面的方式

  1. // create a 100x100x100 8-bit array
  2. int sz[] = {100, 100, 100};
  3. Mat bigCube(3, sz, CV_8U, Scalar::all(0));

对于矩阵的行操作或者列操作,方式如下:(注意对列操作时要新建一个Mat,我想应该跟列地址不连续有关)

  1. // add the 5-th row, multiplied by 3 to the 3rd row
  2. M.row(3) = M.row(3) + M.row(5)*3;
  3. // now copy the 7-th column to the 1-st column
  4. // M.col(1) = M.col(7); // this will not work
  5. Mat M1 = M.col(1);
  6. M.col(7).copyTo(M1);

下面的东西就比较狂暴了,对于外来的数据,比如你从别的地方接受了一幅图片,但可以不是Mat结构的,而只有一个数据的指针,看看接下来的代码是如何应付的,重点哦,亲

  1. void process_video_frame(const unsigned char* pixels,
  2. int width, int height, int step)
  3. {
  4. Mat img(height, width, CV_8UC3, pixels, step);
  5. GaussianBlur(img, img, Size(7,7), 1.5, 1.5);
  6. }

亲,有木有很简单!!!

还有一种快速初始化数据的办法,如下:

  1. double m[3][3] = {{a, b, c}, {d, e, f}, {g, h, i}};
  2. Mat M = Mat(3, 3, CV_64F, m).inv();

也可以把原来的IplImage格式的图片直接用Mat(IplImage)的方式转成Mat结构,也可以像Matlab一样调用zeros()、ones()、eye()这样的函数进行初始化。

如果你需要提前释放数据的指针和内存,可以调用release()。

对于数据的获取,当然还是调用at<float>(3, 3)这样的格式为最佳。其他的方法我甚少尝试,就不敢介绍了。

最后要提的一点是关于Mat的表达式,这个也非常多,加减乘除,转置求逆,我怎么记得我以前介绍过呢。那就不多说啦~

OpenCV学习笔记(四十)——再谈OpenCV数据结构Mat详解的更多相关文章

  1. qml学习笔记(二):可视化元素基类Item详解(上半场anchors等等)

    原博主博客地址:http://blog.csdn.net/qq21497936本文章博客地址:http://blog.csdn.net/qq21497936/article/details/78516 ...

  2. 【Ext.Net学习笔记】03:Ext.Net DirectEvents用法详解、DirectMethods用法详解

    Ext.Net通过DirectEvents进行服务器端异步的事件处理.[Ext.Net学习笔记]02:Ext.Net用法概览.Ext.Net MessageBus用法.Ext.Net布局 中已经简单的 ...

  3. <转>ASP.NET学习笔记之MVC 3 数据验证 Model Validation 详解

    MVC 3 数据验证 Model Validation 详解  再附加一些比较好的验证详解:(以下均为引用) 1.asp.net mvc3 的数据验证(一) - zhangkai2237 - 博客园 ...

  4. [原创]java WEB学习笔记43:jstl 介绍,core库详解:表达式操作,流程控制,迭代操作,url操作

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  5. 【opencv学习笔记四】opencv3.4.0图形用户接口highgui函数解析

    在笔记二中我们已经知道了,在highgui文件夹下的正是opencv图形用户接口功能结构,我们这篇博客所说的便是D:\Program Files\opencv340\opencv\build\incl ...

  6. OpenCV学习笔记(十) 直方图操作

    直方图计算 直方图可以统计的不仅仅是颜色灰度, 它可以统计任何图像特征 (如 梯度, 方向等等).直方图的一些具体细节: dims: 需要统计的特征的数目, 在上例中, dims = 1 因为我们仅仅 ...

  7. OpenCV学习笔记二十:opencv_ts模块

    一,简介: OpenCV测试库,用于单元测试.

  8. OpenCV学习笔记四:ImgProc模块

    一,简介 这个模块包含一系列的常用图像处理算法. 二,分析 此模块包含的文件如下图: 其导出算法包括如下: /*********************** Background statistics ...

  9. opencv学习笔记(四)--图像平滑处理

    图像平滑处理的几种常用方法: 均值滤波 归一化滤波 高斯模糊 中值滤波 平滑处理(模糊)的主要目的是去燥声: 不同的处理方式适合不同的噪声图像,其中高斯模糊最常用. 其实最重要的是对图像卷积的核的理解 ...

随机推荐

  1. react篇章-React 组件-ES6 class 来定义一个组件

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title&g ...

  2. axio post 请求后端接收不到参数的解决办法

    原因是没有对参数进行序列化 默认情况下,axios将JavaScript对象序列化为JSON. 要以应用程序/ x-www-form-urlencoded格式发送数据. 在拦截器前修改 方法一,用原生 ...

  3. android studio 汉化 美化 个性化 修改 安卓工作室 2.3.3 最新版

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha 先看一下效果. 建议全屏看图,或者新标签看图.

  4. bzoj1116 [POI2008]CLO 边双联通分量

    只需对每个联通块的$dfs$树检查有没有返租边即可 复杂度$O(n + m)$ #include <cstdio> #include <cstring> using names ...

  5. Week Four

    2018.12.18 1.[USACO Platinum C] 2.[Gym 102028H] 3.[BZOJ 2750] 4.[BZOJ 3238] 5.[BZOJ 4310] 6.[BZOJ 38 ...

  6. Android为什么需要广播Broadcast

       在Android系统中,为什么需要广播机制呢?广播机制,本质上它就是一种组件间的通信方式,如果是两个组件位于不同的进程当中,那么可以用Binder机制来实现,如果两个组件是在同一个进程中,那么它 ...

  7. 1.7(SQL学习笔记)游标

    一.游标简介 SELECT语句得到的是一个结果集,有时我们需要对结果集中的单条数据进行处理. 这时就需要使用游标,游标定义时和一个SELECT语句的结果集关联在一起. 游标执行这个结果集,可以在结果集 ...

  8. bzoj 4780: [Usaco2017 Open]Modern Art 2

    4780: [Usaco2017 Open]Modern Art 2 Time Limit: 10 Sec  Memory Limit: 128 MB Description Having becom ...

  9. 发现一个可以搜索常用rpm包的地址(http://www.rpmfind.net/)

    http://www.rpmfind.net/ 虽然资源不多,但也够用.

  10. C# 7.0中可能出现的语法

    今天在MSDN上看到的微软关于微软关于C# 7.0特性的Work List,主要特性如下: Tuple增强 Tuple的可读性一直不是很好, 很多时候宁愿新写一个类也不使用Item1, Item2这种 ...