内容简介:Mat是opencv2.0版本开始替换原来指针的一个数据结构,以前opencv1.0时代储存图像的变量都是以指针的形式,这样存在着一个弊端,每次定义图像变量流程便是,以传统c语言的方式去申请内存,使用完毕之后要记得手动释放,假如忘记了就会造成内存泄漏。而opencv2.0版本以后开始全面支持c++,同时也把mat作为图像数据变量的容器,它本质上是一个类,最大的优点是不需要像指针那样每次使用完都要手动释放内存,其内存管理是自动的。不需要花费精力去担心内存的管理问题,其实现的原理大致和c++新标准的智能指针类
Mat
Mat是opencv2.0版本开始替换原来指针的一个数据结构,以前opencv1.0时代储存图像的变量都是以指针的形式,这样存在着一个弊端,每次定义图像变量流程便是,以传统 c语言 的方式去申请内存,使用完毕之后要记得手动释放,假如忘记了就会造成内存泄漏。而opencv2.0版本以后开始全面支持c++,同时也把mat作为图像数据变量的容器,它本质上是一个类,最大的优点是不需要像指针那样每次使用完都要手动释放内存,其内存管理是自动的。不需要花费精力去担心内存的管理问题,其实现的原理大致和c++新标准的智能指针类似,是采用一种引用计数的方式去记录mat变量的使用,mat变量被使用或者赋值到一个新的变量名(浅拷贝),计数器就会自动加一,变量名被销毁了计数器就自动减一,当计数器值减到0时就会自动调用析构函数释放内存。
查看文档了解一下mat类
先看看mat类的继承派生关系图
常见的构造函数
Mat () Mat (int rows, int cols, int type) Mat (Size size, int type) Mat (int rows, int cols, int type, const Scalar &s) Mat (Size size, int type, const Scalar &s) Mat (int ndims, const int *sizes, int type) Mat (const std::vector< int > &sizes, int type) Mat (int ndims, const int *sizes, int type, const Scalar &s) Mat (const std::vector< int > &sizes, int type, const Scalar &s) Mat (const Mat &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=0) Mat (const std::vector< int > &sizes, int type, void *data, const size_t *steps=0) 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) Mat (const Mat &m, const std::vector< Range > &ranges)
模板的构造函数
template<typename _Tp > Mat (const std::vector< _Tp > &vec, bool copyData=false) template<typename _Tp , int n> Mat (const Vec< _Tp, n > &vec, bool copyData=true) template<typename _Tp , int m, int n> Mat (const Matx< _Tp, m, n > &mtx, bool copyData=true) template<typename _Tp > Mat (const Point_< _Tp > &pt, bool copyData=true) template<typename _Tp > Mat (const Point3_< _Tp > &pt, bool copyData=true) template<typename _Tp > Mat (const MatCommaInitializer_< _Tp > &commaInitializer) Mat (const cuda::GpuMat &m)
下面直接贴上代码解释,源代码为opencv samples里面的mat_the_basic_image_container.cpp文件
/* For description look into the help() function. */ //头文件 #include "opencv2/core.hpp" #include <iostream> //命名空间,建议显示使用,如cv::imshow using namespace std; using namespace cv; //帮助信息函数 static void help() { cout << "\n---------------------------------------------------------------------------" << endl << "This program shows how to create matrices(cv::Mat) in OpenCV and its serial" << " out capabilities" << endl << "That is, cv::Mat M(...); M.create and cout << M. " << endl << "Shows how output can be formatted to OpenCV, python, numpy, csv and C styles." << endl << "Usage:" << endl << "./mat_the_basic_image_container" << endl << "-----------------------------------------------------------------------------" << endl << endl; } int main(int,char**) { //输出帮助信息 help(); // create by using the constructor //! [constructor] Mat M(2,2, CV_8UC3, Scalar(0,0,255));//使用构造函数创建mat容器, 2x2大小、8位无符号3通道,初始化为红色(opencv默认bgr) cout << "M = " << endl << " " << M << endl << endl; //! [constructor] // create by using the create function() //! [create] M.create(4,4, CV_8UC(2));//使用create函数创建mat容器,4x4大小、8位无符号2通道 cout << "M = "<< endl << " " << M << endl << endl; //! [create] // create multidimensional matrices //! [init] int sz[3] = {2,2,2}; Mat L(3,sz, CV_8UC(1), Scalar::all(0));//创建多维矩阵、3维、每一维度为一个数组,8位无符号1通道、灰度初始化为0,三维的矩阵无法打印显示 //! [init] // Cannot print via operator << // Create using MATLAB style eye, ones or zero matrix //创建像matlab风格那样的单位矩阵、数值都为1或0的矩阵 //! [matlab] Mat E = Mat::eye(4, 4, CV_64F); //单位矩阵 cout << "E = " << endl << " " << E << endl << endl; Mat O = Mat::ones(2, 2, CV_32F);//数值全为1矩阵 cout << "O = " << endl << " " << O << endl << endl; Mat Z = Mat::zeros(3,3, CV_8UC1);//数值全为0矩阵 cout << "Z = " << endl << " " << Z << endl << endl; //! [matlab] // create a 3x3 double-precision identity matrix //! [comma] Mat C = (Mat_<double>(3,3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);//逗号分隔符方式,用到<<运算符 cout << "C = " << endl << " " << C << endl << endl; //! [comma] // do the same with initializer_list #ifdef CV_CXX11 //! [list] C = (Mat_<double>({0, -1, 0, -1, 5, -1, 0, -1, 0})).reshape(3);//使用初始化列表的方式创建 cout << "C = " << endl << " " << C << endl << endl; //! [list] #endif //! [clone] Mat RowClone = C.row(1).clone(); cout << "RowClone = " << endl << " " << RowClone << endl << endl;//使用clone函数方式 //! [clone] // Fill a matrix with random values //! [random] Mat R = Mat(3, 2, CV_8UC3); randu(R, Scalar::all(0), Scalar::all(255));//创建包含随机数的矩阵 //! [random] // Demonstrate the output formatting options //! [out-default] //格式化打印这些数据 cout << "R (default) = " << endl << R << endl << endl;//默认格式 //! [out-default] //! [out-python] cout << "R (python) = " << endl << format(R, Formatter::FMT_PYTHON) << endl << endl;//python风格 //! [out-python] //! [out-numpy] cout << "R (numpy) = " << endl << format(R, Formatter::FMT_NUMPY ) << endl << endl;//numpy风格 //! [out-numpy] //! [out-csv] cout << "R (csv) = " << endl << format(R, Formatter::FMT_CSV ) << endl << endl;//csv风格、即逗号分隔值风格 //! [out-csv] //! [out-c] cout << "R (c) = " << endl << format(R, Formatter::FMT_C ) << endl << endl;//c语言风格 //! [out-c] //! [out-point2] Point2f P(5, 1);//浮点型2维点 cout << "Point (2D) = " << P << endl << endl; //! [out-point2] //! [out-point3] Point3f P3f(2, 6, 7);//浮点型3维点 cout << "Point (3D) = " << P3f << endl << endl; //! [out-point3] //! [out-vector] vector<float> v; v.push_back( (float)CV_PI); v.push_back(2); v.push_back(3.01f); cout << "Vector of floats via Mat = " << Mat(v) << endl << endl;//向量转为mat类 //! [out-vector] //! [out-vector-points] vector<Point2f> vPoints(20);//浮点型2维点集合 for (size_t i = 0; i < vPoints.size(); ++i) vPoints[i] = Point2f((float)(i * 5), (float)(i % 7)); cout << "A vector of 2D Points = " << vPoints << endl << endl; //! [out-vector-points] return 0; }
代码知识点
1.使用构造函数创建mat容器
Mat M(2,2, CV_8UC3, Scalar(0,0,255));//使用构造函数创建mat容器, 2x2大小、8位无符号3通道,初始化为红色(opencv默认bgr) cout << "M = " << endl << " " << M << endl << endl;
2.使用create函数创建mat容器
M.create(4,4, CV_8UC(2));//使用create函数创建mat容器,4x4大小、8位无符号2通道 cout << "M = "<< endl << " " << M << endl << endl;
3.创建多维矩阵
int sz[3] = {2,2,2}; Mat L(3,sz, CV_8UC(1), Scalar::all(0));//创建多维矩阵、3维、每一维度为一个数组,8位无符号1通道、灰度初始化为0,三维的矩阵无法打印显示
4.创建像matlab风格那样的单位矩阵、数值都为1或0的矩阵
//! [matlab] Mat E = Mat::eye(4, 4, CV_64F); //单位矩阵 cout << "E = " << endl << " " << E << endl << endl; Mat O = Mat::ones(2, 2, CV_32F);//数值全为1矩阵 cout << "O = " << endl << " " << O << endl << endl; Mat Z = Mat::zeros(3,3, CV_8UC1);//数值全为0矩阵 cout << "Z = " << endl << " " << Z << endl << endl; //! [matlab]
5.其他方式创建矩阵
// create a 3x3 double-precision identity matrix //! [comma] Mat C = (Mat_<double>(3,3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);//逗号分隔符方式,用到<<运算符 cout << "C = " << endl << " " << C << endl << endl; //! [comma] // do the same with initializer_list #ifdef CV_CXX11 //! [list] C = (Mat_<double>({0, -1, 0, -1, 5, -1, 0, -1, 0})).reshape(3);//使用初始化列表的方式创建 cout << "C = " << endl << " " << C << endl << endl; //! [list] #endif //! [clone] Mat RowClone = C.row(1).clone(); cout << "RowClone = " << endl << " " << RowClone << endl << endl;//使用clone函数方式 //! [clone] // Fill a matrix with random values //! [random] Mat R = Mat(3, 2, CV_8UC3); randu(R, Scalar::all(0), Scalar::all(255));//创建包含随机数的矩阵 //! [random]
6.格式化打印输出Mat类数据
cout << "R (default) = " << endl << R << endl << endl;//默认格式 //! [out-default] //! [out-python] cout << "R (python) = " << endl << format(R, Formatter::FMT_PYTHON) << endl << endl;//python风格 //! [out-python] //! [out-numpy] cout << "R (numpy) = " << endl << format(R, Formatter::FMT_NUMPY ) << endl << endl;//numpy风格 //! [out-numpy] //! [out-csv] cout << "R (csv) = " << endl << format(R, Formatter::FMT_CSV ) << endl << endl;//csv风格、即逗号分隔值风格 //! [out-csv] //! [out-c] cout << "R (c) = " << endl << format(R, Formatter::FMT_C ) << endl << endl;//c语言风格 //! [out-c]
输出的格式布置程序中的五种,查看文档可以看到Formatter有一个枚举变量,定义如下
enum { FMT_DEFAULT = 0, FMT_MATLAB = 1, FMT_CSV = 2, FMT_PYTHON = 3, FMT_NUMPY = 4, FMT_C = 5 }
7. 2D、3D和vector的使用方法
//! [out-point2] Point2f P(5, 1);//浮点型2维点 cout << "Point (2D) = " << P << endl << endl; //! [out-point2] //! [out-point3] Point3f P3f(2, 6, 7);//浮点型3维点 cout << "Point (3D) = " << P3f << endl << endl; //! [out-point3] //! [out-vector] vector<float> v; v.push_back( (float)CV_PI); v.push_back(2); v.push_back(3.01f); cout << "Vector of floats via Mat = " << Mat(v) << endl << endl;//向量转为mat类 //! [out-vector] //! [out-vector-points] vector<Point2f> vPoints(20);//浮点型2维点集合 for (size_t i = 0; i < vPoints.size(); ++i) vPoints[i] = Point2f((float)(i * 5), (float)(i % 7)); cout << "A vector of 2D Points = " << vPoints << endl << endl; //! [out-vector-points]
8.运行截图
回顾总结
这个例程的知识点包含了mat类的实例化方法,包含构造函数、create函数、和克隆拷贝、初始化列表等,接着时特殊矩阵的创建,格式化输出mat类数据,最后时2D、3D和vector的使用方法。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- laravel自带用户认证
- Mac自带apache配置
- opencv自带例子学习-图像混合
- Golang中自带的强大命令工具
- Android调用系统自带的分享功能
- 使用oracle自带的命令进行导入导出
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
程序员修炼之道(影印版)
Andrew Hunt、David Thomas / 中国电力出版社 / 2003-8-1 / 39.00
本书直击编程陈地,穿过了软件开发中日益增长的规范和技术藩篱,对核心过程进行了审视——即根据需求,创建用户乐于接受的、可工作和易维护的代码。本书包含的内容从个人责任到职业发展,直至保持代码灵活和易于改编重用的架构技术。从本书中将学到防止软件变质、消除复制知识的陷阱、编写灵活、动态和易适应的代码、避免出现相同的设计、用契约、断言和异常对代码进行防护等内容。一起来看看 《程序员修炼之道(影印版)》 这本书的介绍吧!
图片转BASE64编码
在线图片转Base64编码工具
MD5 加密
MD5 加密工具