OpenCV Mat常用操作

来源:互联网 发布:软件项目报价表 编辑:程序博客网 时间:2024/06/05 08:51

0 简述

       Mat对象是自opencv2.0之后设计的,专用于存储图像信息的类,包括头部与数据部分。在opencv2.0之前使用的是IplImage结构体,两者的区别在于,Mat对象自动分配内存,不存在内存泄漏的问题,是面向对象的数据结构。IplImage需要开发者自己分配与管理内存,所以容易造成内存泄漏的问题。

1 常用操作

void copyTo(Mat mat)

void convertTo(Mat dst, int type)

Mat clone()

int channels()

int depth()

bool empty();

uchar* ptr(i=0)

       cv::Size(m,n) : 构建m行n列的矩阵;

       cv::Scalar(a1,a2…an):初始化矩阵数值,其中a1,a2…an的个数,需要与之前定义的图像的通道数保持一致。

2 注意事项

       深拷贝与浅拷贝。

       Mat浅拷贝:只会复制Mat对象的头和指针部分,不会复制数据部分。

       Mat深拷贝:头和数据部分都需要进行拷贝。如下所示。

//浅拷贝,数据共享(更改a,b,c的任意一个都会对另外2个产生同样的作用)

Mat a;

Mat b = a; //a "copy" to b

Mat c(a); //a "copy" to c

//深拷贝

Mat a;

Mat b = a.clone(); //a copy to b

Mat c;

a.copyTo(c); //a copy to c

       对于小矩阵如2*2或3*3等情况,可以直接初始化,如下。

//对小矩阵使用逗号分隔式初始化函数 

#include<iostream> 

#include<opencv2/opencv.hpp> 

 

using namespace std;

using namespace cv;

 

int main()

{

  Mat array = (Mat_<double>(3, 3) << 0, -1, 5, -1, 5, -1, 0, -1, 0);

  return 0;

}

 

3 代码

#include <iostream>

#include <opencv2/opencv.hpp>

                   

//opencv 常用矩阵操作

 

int main(int argc,char* argv[])

{

  //-----------------------------------------

  //0. MAT 定义

  //-----------------------------------------

  //初始化时指定尺寸和数据类型

  //尺寸:CvSize (int w=0, int h=0)

  //数据类型命名方式:CV_位宽|类型|通道数

  //位宽:8、16、32、64

  //类型:U S、 整数有无符号 F 浮点数

  //通道数:Cxx表示通道数目,如果没有,则是默认的单通道

  cv::Mata(cv::Size(6, 5),CV_8U);

  std::cout<< "a = " << std::endl<< a << std::endl;

  //初始化时有时也会跟上Scalar参数,表示给不同通道的赋值,取值依赖于之前定义的通道数

  cv::Matb(cv::Size(2, 2),CV_8UC2, cv::Scalar(100,200));

  std::cout<< "b = " << std::endl<< b << std::endl;

  cv::Matc(cv::Size(3,3),CV_8UC3, cv::Scalar(10,20,30));

  std::cout<< "c = " << std::endl<< c << std::endl;

 

  //-----------------------------------------

  //1. MAT API 初始化

  //-----------------------------------------

  cv::Matmz = cv::Mat::zeros(cv::Size(5, 5), CV_8U);  //全零

  std::cout<< "mz = " << std::endl<< mz << std::endl;

  cv::Matmo = cv::Mat::ones(cv::Size(5, 5), CV_8U);   //全1矩阵

  std::cout<< "mo = " << std::endl<< mo << std::endl;

  cv::Matme = cv::Mat::eye(cv::Size(5, 5), CV_8U); //对角线为1的矩阵

  std::cout<< "me = " << std::endl<< me << std::endl;

 

  //-----------------------------------------

  //3. MAT 矩阵加减运算

  //-----------------------------------------

  cv::Matmsum = mo + me;

  std::cout<< "msum =" << std::endl<< msum << std::endl;

  cv::Matmsub = mo - me;

  std::cout<< "msub = " << std::endl<< msub << std::endl;

 

  //-----------------------------------------

  //4. MAT 矩阵乘法运算

  //-----------------------------------------

  //-----------------------------------------

  //5. MAT 矩阵转置\求逆

  //-----------------------------------------

  cv::Matmt(cv::Size(4, 5),CV_8U, cv::Scalar(20));

  cv::Matmtt = mt.t();

  std::cout<< " mtt = " << std::endl<< mtt << std::endl;

  cv::Matme2 = cv::Mat::eye(cv::Size(5, 5), CV_32F);

  cv::Matminv = me2.inv();

  std::cout<< "minv = " << std::endl<< minv << std::endl;

  //-----------------------------------------

  //6. MAT 矩阵 均值 和 方差

  //-----------------------------------------

  cv::Matmean;

  cv::Matstddev;

  meanStdDev(a,mean, stddev);

  std::cout<< "mean : " << mean <<std::endl;

  std::cout<< "stddev : "<< stddev << std::endl;

  //需要说明的是,如果src是多通道图像或多维矩阵,

  //则函数分别计算不同通道的均值与标准差,

  //因此返回值mean和stddev为对应维度的向量

  meanStdDev(b,mean, stddev);

  std::cout<< "mean : " << mean <<std::endl;

  std::cout<< "stddev : "<< stddev << std::endl;

 

  //-----------------------------------------

  //7. MAT 设置单元矩阵

  //-----------------------------------------

  cv::Matmi(cv::Size(4,4),CV_8U);

  cv::setIdentity(mi,cv::Scalar::all(20));

  std::cout<< "mi = " << std::endl<< mi << std::endl;

 

  getchar();

}

4 其它

       Mat初始化代码,参考这篇blog。http://blog.csdn.net/qq_23880193/article/details/47903143。