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. 为Vell001家族使用过的图标

    vell001小海报 最早设计的Vell001图标,根据我偶像Vettel的个人主页上的图片修改而成 由于本人很喜欢jobs,苹果的logo一直是我的最爱 上两个图标已在多个地方使用了,但个人感觉气氛 ...

  2. 【Java基础】基本类型的包装类作为参数传递是值传递还是引用传递

    突然想到这个问题,然后做了下实验,下面以Integer来讲解,其他的忽略: import java.util.Iterator; /** * Created by lili on 15/9/24. * ...

  3. Android camera采集视频 X264编码

    参考 http://blog.csdn.net/zblue78/article/details/6058147 感谢 ExperiencesOfCode 硬件平台:CPU Intel G630 @2. ...

  4. ios:Failed to instantiate the default view controller for UIMainStoryboardFile 'Main' - perhaps the designated entry point is not set?

    - (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)laun ...

  5. Open Dynamics Engine for Linux 安装笔记

    下载 在Bitbucket上可以下载到最新的版本(截止目前为0.14版) 或者直接用wget下载 wget "https://bitbucket.org/odedevs/ode/downlo ...

  6. HTML几类标签的应用总结

    打开DREAMWEAVER,新建HTML,如下图: body的属性: bgcolor 页面背景色 background  背景壁纸.图片 text  文字颜色 topmargin  上边距 leftm ...

  7. Xcode6为什么干掉pch(Precompile Prefix Header)&如何添加pch文件

    转载:  http://blog.csdn.net/iosdevtip/article/details/40918353 一直在用xcode6开发,但项目都是在xcode5上创建的,所以一直没注意到, ...

  8. winform button设计(一)

    对于winform的button设计来说,vs真心没有给太多的样式布局.为了能给予用户更加人性化的界面.我们在做程序时往往会设计美观的button. 比方,我今天在设计一个项目button时,我想将b ...

  9. 【转】最新基于adt-bundle-windows-x86的android开发环境搭建

    http://blog.csdn.net/wangqiuyun/article/details/8731240 某系统要配套做一个android客户端,来一次android开发环境快速搭建,系统Win ...

  10. 多媒体应用-swift

    照片选择主要是通过UIImagePickerController控制器实例化一个对象,然后通过self.PresentViewController方法推出界面显示.需要实现代理UIImagePicke ...