IplImage 与 Mat

IplImage是OpenCV1中的图像存储结构体,基于C接口创建。在退出之前必须release,否则就会造成内存泄露。在一些只能使用C语言的嵌入式系统中,不得不使用。

IplImage* img = cvLoadImage("imagename.jpg",);

Mat类内存分配是自动完成的,不必手动开辟空间(非必须),不必在不需要时释放空间。

Mat类的构成

Mat由矩阵头和一个指向存储图像矩阵的指针组成。为应该尽量避免图像的复制,加快程序运行速度,Mat的拷贝构造函数只复制信息头和矩阵指针,不复制矩阵。因此通过任何一个对象所做的改变也会影响其他对象。如果想要创建一个感兴趣的区域(Region of Interest (ROI))只需要创建包含边界信息的信息头:

Mat ROI1(matrix, Rect(x,y,width,height)); // use rectangle to set the boundary
Mat ROI2 = matrix(Range:all(), Range(,)); // use rows and cols

Mat通过对象计数机制来实现最后一个使用它的对象自动负责清理存储空间。如果想要复制矩阵本身,可以使用:

Mat duplicate1 = matrix.clone();
Mat duplicate2;
matrix.copyTo(duplicate2);

改变duplicate1和duplicate2不会影响matrix指向的矩阵。

构造函数

Mat()
Mat(int rows, int cols, int type, const Scalar & s)
  • rows:矩阵行数
  • cols:矩阵列数
  • type:规定存储元素的数据类型和每个矩阵点的通道数
    • CV_[the number of bits per item: 8/16/32/64] [Signed, Unsigned, or Float: S/U/F] C [The channel number: 1/2/3/4]
    • CV_8UC3:三通道8位的unsigned char型
  • s:可以省去,Scalar是short型的向量,用来初始化矩阵  
Mat(Size size, int type, const Scalar & s)
  • size: 二位矩阵尺寸,Size(cols, rows),注意维数尺寸跟前面的构造函数是相反的
  • type和s:同上
Mat(int ndims, const int* sizes, type, const Scalar & s)
  • ndims: 第二个参数,size矩阵,的维数
  • sizes: 整型矩阵,规定Mat的尺寸
  • type和s:同上
Mat (const Mat &m)
Mat (const Mat &m, const Range &rowRange, const Range &colRange=Range::all())
Mat (const Mat &m, const Rect &roi)
Mat (const Mat &m, const Range *ranges)
  • m: 赋值矩阵,它的部分或者全部值将以指针传递给构造出的矩阵,注意数据不会被拷贝给新矩阵
  • 其他参数:规定赋值部分的范围
Mat (int rows, int cols, int type, void *data, size_t step=AUTO_STEP)
Mat (Size size, int type, void *data, size_t step=AUTO_STEP)
Mat (int ndims, const int *sizes, int type, void *data, const size_t *steps=)
  • data:指向用户数据的指针,构造的矩阵将指向这些用户数据,没有进行数据拷贝
  • step:矩阵更新到下一行需要跨过的字节数,如果矩阵每行的尾部包含无用的填充数据,需要把这部分计算进去,自动计算时设为cols*elemSize()
  • 其他参数:设置矩阵的大小和类型 
Mat::Mat(const IplImage* img, bool copyData=false)
  • img: IplImage类型的图,利用它来创建信息头
  Mat (const std::vector< _Tp > &vec, bool copyData=false)
  • vec:STL vector,矩阵行数等于vec的元素数,矩阵的数据类型与vec相同,因此vec必须为单一类型的数据结构。默认情况下,不会进行数据拷贝,这种情况下在矩阵被释放之前,不能再向vec内加入新数据(这样会造成存储空间重新分配,之前的指针可能会失效)或进行其他可能改变vec内存空间的操作。

  

其他构造函数可以参见OpenCV Documentation:

OpenCV3

OpenCV2

其他初始化方法

void    create (int rows, int cols, int type)
void create (Size size, int type)
void create (int ndims, const int *sizes, int type)

分配新内存,但不能为矩阵设置初值。大部分需要分配空间的OpenCV函数都会从内部调用这个函数,所以在调用他们之前不用手动分配内存空间

  • 如果现在矩阵的形状数据类型与目标相同,直接返回。否则释放原来的内存空间。
  • 初始化新矩阵头
  • 分配total()*elemSize()字节内存
  • 设置新的对象计数值,并设为1
static MatExpr eye (int rows, int cols, int type)
static MatExpr eye (Size size, int type)
static MatExpr ones (int rows, int cols, int type)
static MatExpr ones (Size size, int type)
static MatExpr ones (int ndims, const int *sz, int type)
static MatExpr zeros (int rows, int cols, int type)
static MatExpr zeros (Size size, int type)
static MatExpr zeros (int ndims, const int *sz, int type)

Matlab形式的初始化方式。MatExpr是Matrix expression representation,可以进行各种矩阵运算操作。用法如下,

Mat E = Mat::eye(,,CV_64F);
Mat O = Mat::ones(,,CV_32F)*0.1;

逗号分隔式初始化

Mat C = (Mat_<double>(,) << ,-,, -,,-, ,-,);
Mat     clone () const
void copyTo (OutputArray m) const
void copyTo (OutputArray m, InputArray mask) const

拷贝矩阵,回先调用create函数分配内存空间,

  • mask:非零数据代表了需要拷贝的数据,如果传递了这个参数那么分配完内存空间后,矩阵先被初始化为0,mask是CV_8U类型可以包含一个或多个通道

格式化输出方法

5种输出风格:OpenCV默认,Python,逗号分隔,Numpy, C语言风格。事例程序和运行结果如下:

#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
// main
int main( int argc, char** argv )
{
cv::Mat r = cv::Mat(,,CV_8UC3);
cv::randu(r, cv::Scalar::all(), cv::Scalar::all()); // [1] OpenCV default style
std::cout << "r (OpenCV default style) = \n" << r << ";" << std::endl << std::endl; // [2] Python style
// OpenCV2
// std::cout << "r (Python style) = " << format(r,"python") << ";" << std::endl << std::endl;
// OpenCV3
std::cout << "r (Python style) = \n" << format(r,cv::Formatter::FMT_PYTHON) << ";" << std::endl << std::endl; // [3] Comma separated values (CSV)
// OpenCV2
// std::cout << "r (CSV style) = " << format(r,"csv") << ";" << std::endl << std::endl;
// OpenCV3
std::cout << "r (CSV style) = \n" << format(r,cv::Formatter::FMT_CSV) << ";" << std::endl << std::endl; // [4] Numpy style
// OpenCV2
// std::cout << "r (Numpy style) = " << format(r,"numpy") << ";" << std::endl << std::endl;
// OpenCV3
std::cout << "r (Numpy style) = \n" << format(r,cv::Formatter::FMT_NUMPY) << ";" << std::endl << std::endl; // [3] C style
// OpenCV2
// std::cout << "r (C style) = " << format(r,"C") << ";" << std::endl << std::endl;
// OpenCV3
std::cout << "r (C style) = \n" << format(r,cv::Formatter::FMT_C) << ";" << std::endl << std::endl; return ;
}
r (OpenCV default style) =
[ , , , , , , , , ;
, , , , , , , , ;
, , , , , , , , ;
, , , , , , , , ;
, , , , , , , , ;
, , , , , , , , ;
, , , , , , , , ;
, , , , , , , , ;
, , , , , , , , ;
, , , , , , , , ]; r (Python style) =
[[[ , , ], [, , ], [, , ]],
[[, , ], [, , ], [, , ]],
[[, , ], [ , , ], [, , ]],
[[, , ], [, , ], [ , , ]],
[[ , , ], [, , ], [, , ]],
[[ , , ], [, , ], [, , ]],
[[, , ], [ , , ], [ , , ]],
[[, , ], [, , ], [ , , ]],
[[, , ], [ , , ], [ , , ]],
[[, , ], [, , ], [ , , ]]]; r (CSV style) =
, , , , , , , ,
, , , , , , , ,
, , , , , , , ,
, , , , , , , ,
, , , , , , , ,
, , , , , , , ,
, , , , , , , ,
, , , , , , , ,
, , , , , , , ,
, , , , , , , ,
; r (Numpy style) =
array([[[ , , ], [, , ], [, , ]],
[[, , ], [, , ], [, , ]],
[[, , ], [ , , ], [, , ]],
[[, , ], [, , ], [ , , ]],
[[ , , ], [, , ], [, , ]],
[[ , , ], [, , ], [, , ]],
[[, , ], [ , , ], [ , , ]],
[[, , ], [, , ], [ , , ]],
[[, , ], [ , , ], [ , , ]],
[[, , ], [, , ], [ , , ]]], dtype='uint8'); r (C style) =
{ , , , , , , , , ,
, , , , , , , , ,
, , , , , , , , ,
, , , , , , , , ,
, , , , , , , , ,
, , , , , , , , ,
, , , , , , , , ,
, , , , , , , , ,
, , , , , , , , ,
, , , , , , , , };

图像储存容器Mat[OpenCV 笔记11]的更多相关文章

  1. 图像载入 imread()[OpenCV 笔记4]

    Mat imread( ); filename 载入的图像名: flags 指定加载图像的颜色类型,默认载入三通道彩色图像, 如果取枚举类型 (OpenCV3中暂时失效),则定义如下 enum{ CV ...

  2. 图像显示 imshow()[OpenCV 笔记5]

    void imshow(const string& winname InputArray mat); winname 窗口表识名称 mat 需要显示的图像.InputArray类型,声明如下 ...

  3. 访问图像中的像素[OpenCV 笔记16]

    再更一发好久没更过的OpenCV,不过其实写到这个部分对计算机视觉算法有所了解的应该可以做到用什么查什么了,所以后面可能会更的慢一点吧,既然开了新坑,还是机器学习更有研究价值吧... 图像在内存中的存 ...

  4. 实例:图像载入、显示、混合与输出[OpenCV 笔记8]

    是的是的,忍着尿意努力更新,就是为了更到wuli男神的部分,当然要把男神放在前面镇楼,欢迎下载配图,具体操作见code wuliEddie.jpg logo.png results.jpg LoadS ...

  5. 查找并绘制轮廓[OpenCV 笔记XX]

    好久没有更新了,原谅自己放了个假最近又在赶进度,所以...更新的内容是很靠后的第八章,因为最近工作要用就先跳了,后面会更新笔记编号...加油加油! 在二值图像中寻找轮廓 void cv::findCo ...

  6. OpenCV基本架构[OpenCV 笔记0]

    最近正在系统学习OpenCV,将不定期发布笔记,主要按照毛星云的<OpenCV3编程入门>的顺序学习,会参考官方教程和文档.学习工具是Xcode+CMake,会对书中一部分内容更正,并加入 ...

  7. 颜色空间转换 cvtColor()[OpenCV 笔记13]

    void cvtColor(InputArray src, OutputArray dst, ) src: 输入图像 dst: 输出图像 code: 颜色空间转换标识符 OpenCV2的CV_前缀宏命 ...

  8. 鼠标操作[OpenCV 笔记10]

    ) winname 窗口名字 onMouse 指定窗口每次鼠标事件发生的时候,被调用的函数指针.函数的原型应为void Foo(int event, int x, int y, int flags, ...

  9. 输出图像到文件 imwrite()[OpenCV 笔记7]

    bool imwrite(const string& filename, InputArray img, const vector<int>& params=vector& ...

随机推荐

  1. Grails教程之--我的理解

    最近工作中接触到了Grails,对于这门技术,网上的资料不算太多,有的基本也是大同小异.我打算边学边写一些东西,毕竟是一个学习的过程,写的东西如果有错误或者理解不正确的地方,还希望大家能指出来.帮助我 ...

  2. HTML的id,name,class

    HTML中的id是给JavaScript用的(document.getElementById()) HTML中的name是给JavaScript用的(formUploadFile.submit()) ...

  3. 【三支火把】---C语言面试问题总结

    看了一份关于HR在面试一名C程序员可能提问的问题手册,学到了很多,很多都是一些琐碎的知识点,总是你写过很多大型的C程序,但是我敢说,里面也有你没掌握的东西. 1.全局变量和局部变量有何区别? 答:全局 ...

  4. Java多重if....else if

    public class HelloWorld { public static void main(String[] args) { int age=25; if(age>60){ System ...

  5. GridLookUpEdit 简单应用

    在属性列表中 Properties  -> view  即可打开设计器进行编辑 后台代码: DataTable dtt = stu.StuGetFind(sxml, 1, 50).Tables[ ...

  6. "用wow64exts调试64位任务管理器抓取的32位程序的dump"

    博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:"用wow64exts调试64位任务管理器抓取的32位程序的dump".

  7. iOS 极光推送

    1.关于推送的几个证书.http://www.mobile-open.com/2016/931624.html 进入开发者中心:https://developer.apple.com/account/ ...

  8. SQL Server将一列的多行内容拼接成一行的问题讨论

    转自http://blog.csdn.net/rolamao/article/details/7745972 昨天遇到一个SQL Server的问题:需要写一个储存过程来处理几个表中的数据,最后问题出 ...

  9. 【DB】HBase的基本概念

    一 Hbase是个啥东东?  在说Hase是个啥家伙之前,首先我们来看看两个概念.面向行存储和面向列存储.面向行存储.我相信大伙儿应该都清楚,我们熟悉的RDBMS就是此种类型的.面向行存储的数据库主要 ...

  10. Android-ViewPagerIndicator

    https://github.com/JakeWharton/Android-ViewPagerIndicator