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

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

内容简介: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的使用方法。


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

查看所有标签

猜你喜欢:

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

网络素养

网络素养

[美]霍华德·莱茵戈德 / 张子凌、老卡 / 译言·东西文库/电子工业出版社 / 2013-8-1 / 49.80元

有人说Google让我们变得更笨,有人说Facebook出卖了我们的隐私,有人说Twitter将我们的注意力碎片化。在你担忧这些社会化媒体让我们变得“浅薄”的时候,有没问过自己,是否真正地掌握了使用社会化媒体的方式? 这本书将介绍五种正在改变我 们这个世界的素养:注意力、 对垃圾信息的识别能力、参与力、协作力和联网智慧。当有足够多的人学会并且能够熟练的使用这些技术,成为真正的数字公民后。健康......一起来看看 《网络素养》 这本书的介绍吧!

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

SHA 加密
SHA 加密

SHA 加密工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器