opencv自带例子学习-图像基本容器mat

栏目: 编程工具 · 发布时间: 6年前

内容简介: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类的继承派生关系图

opencv自带例子学习-图像基本容器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.运行截图

opencv自带例子学习-图像基本容器mat

opencv自带例子学习-图像基本容器mat

opencv自带例子学习-图像基本容器mat

opencv自带例子学习-图像基本容器mat

回顾总结

这个例程的知识点包含了mat类的实例化方法,包含构造函数、create函数、和克隆拷贝、初始化列表等,接着时特殊矩阵的创建,格式化输出mat类数据,最后时2D、3D和vector的使用方法。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

大转换

大转换

尼古拉斯·卡尔 / 闫鲜宁、张付国 / 中信 / 2016-2 / 49

1、我们这个时代最清醒的思考者之一尼古拉斯·卡尔继《浅薄》《玻璃笼子》之后又一重磅力作。 2、在这部跨越历史、经济和技术领域的著作中,作者从廉价的电力运营方式对社会变革的深刻影响延伸到互联网对我们生活的这个世界的重构性影响。 3、《快公司》《金融时报》《华尔街日报》联袂推荐 简介 早在2003年,尼古拉斯·卡尔先生发表在《哈佛商业评论》上的一篇文章——IT Doesn't ......一起来看看 《大转换》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

html转js在线工具
html转js在线工具

html转js在线工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具