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. WPF的MVVM模式

    Model->數據模型View->視圖View-Model->連接數據模型和視圖

  2. php数组相加 两个数组键名相同 后者不能覆盖前者

    array(“a”)+array(“b”)结果还是array(“a”) array(“a”)+array(“b”)的结果是 array(“a”) 因为,它们等效于array(“0″=>”a”)+ ...

  3. 写入目录 /tmp/OraInstall2015-05-20_03-35-53PM 时出错

    做足准备工作之后进行安装oracle,运行runInstall的时候别的时候输出如下错误 写入目录 /tmp/OraInstall2015-05-20_03-35-53PM 时出错.请确保此目录是可写 ...

  4. ros和Android(一)

    ros和Android :first-child { margin-top: 0; } blockquote > :last-child { margin-bottom: 0; } img { ...

  5. 关于css中z-index 的应用

    我想很多人在应用中的会碰到这个问题,设置 z-index无效:无论设置为多高的数字都没有效果: 原因是在设置z-index之前必须满足一下两个条件: 1,给设置z-index的元素设置相应的定位值,p ...

  6. dubbox开发rest+json指南【转】

    http://dangdangdotcom.github.io/dubbox/rest.html 目录 概述 REST的优点 应用场景 快速入门 标准Java REST API:JAX-RS简介 RE ...

  7. java list&lt;string&gt;组 传递到值js排列

    方法一 后台:     String sql = "select * from tree";     list = this.treeService.getTreeList(sql ...

  8. android94 样式和主题

    style.xml <resources xmlns:android="http://schemas.android.com/apk/res/android"> < ...

  9. 一个App带你学会Retrofit2.0,麻麻再也不用担心我的网络请求了!

    Retrofit.Retrofit.Retrofit,越来越多的人在玩这个网络请求框架,这个由squareup公司开源的网络请求框架确实挺好用,今天我们就来看一下这个东东怎么玩! Retrofit作为 ...

  10. oralce表空间自增长占满磁盘

    取消表空间自动增长 SELECT FILE_NAME,TABLESPACE_NAME,AUTOEXTENSIBLE,bytes/1024/1024/1024 FROM dba_data_files; ...