基于windows10、vs2015、OpenCv4.1.0。

目录

1、Mat类简介

2、Mat类的构造与赋值

2.1、Mat类的构造

2.2、Mat类的赋值

3、Mat类支持的运算

3.1Mat类的加减乘除运算:

3.2两个Mat类矩阵的乘法运算

4、Mat类元素的读取

4.1多通道数据的存储

4.2Mat类常用属性和成员方法

4.3通过at读取Mat类单通道矩阵的元素

4.4通过at读取Mat类多通道矩阵的元素

4.5通过指针ptr读取Mat矩阵种的元素

4.6通过迭代器访问Mat类矩阵中的元素


1、Mat类简介

OpenCv提供了Mat类用来存储矩阵类型数据,包括向量、矩阵、图像等数据。Mat类分为分为矩阵头和指向存储数据的矩阵指针两部分。矩阵头包含矩阵的尺寸、存储方法、地址和引用次数。矩阵头是一个常数,绝大数情况下,矩阵头的大小远小于矩阵数据量的大小。

#include <opencv2\opencv.hpp>
#include <iostream>using namespace std;
using namespace cv;int main()
{Mat a;a = imread("D:\\lena.jpg"); //向a中赋值图像数据Mat b = a;//只是复制了矩阵头和指向存储数据的指针(指向的是同一个矩阵数据)waitKey();return 0;
}

声明一个指定类型的Mat类:

Mat b = Mat_<double>(3, 3);//创建一个3*3的矩阵存放double类型数据

通过OpenCv数据类型创建Mat类

Mat a(640, 480, CV_8UC3)//创建一个640*480的3通道矩阵用于存放彩色图像
Mat a(3, 3, CV_8UC1);//创建一个3*3的8位无符号整数的单通道矩阵
Mat a(3, 3, CV_8U);//创建单通道矩阵,C1标识可以省略

2、Mat类的构造与赋值

2.1、Mat类的构造

默认构造函数

cv::Mat::Mat();

这种构造方式,不需要传递任何参数,在后续给变量赋值的时候会自动判断矩阵的类型与大小,实现灵活的存储,常用于存储读取的图像数据和某个函数运算的输出结果。

根据输入矩阵尺寸和类型构造

cv::Mat::Mat(int rows,int cols,int type)

其中rows:构造矩阵的行数;cols:矩阵的列数;type:矩阵存储的数据类型,例如CV_8UC1之类。

用Size()结构构造Mat类。

cv::Mat::Mat(Size size(), int type);

其中size:为二位数组变量尺寸,通过Size(cols,rows)进行赋值(列在前,行在后);type:矩阵存储的数据类型,例如CV_8UC1之类。

示例:

cv::Mat a(Size(480,580), CV_8UC1);//构造一个行580,列480的单通道矩阵

利用已有矩阵构造Mat类

cv::Mat::Mat(const Mat & a);

这种构造方式只是复制了Mat类的矩阵头,矩阵指针指向是同一个地址。(浅复制)

若要深复制,可用

b = a.clone();

构造已有Mat的子类

cv::Mat::Mat(const Mat & a,const Range & rowRange, const Range & colRange=Range::all);

其中,m:已经构建完成的Mat;rowRange:在已有的矩阵中需要获取的行数范围,是一个Range变量,例如从第二行到第五行表示为Range(2,5);colRange也是一样,在已有的矩阵中需要获取的列数范围,是一个Range变量,例如从第二列到第五列表示为Range(2,5)省略时,所有的列都会被截取。(注意:这种方式构造的类与已有Mat类共享数据。)

例如:

cv::Mat b(a, Range(2, 5), Range(1, 4));//从a中截取第二行到第五行,第一列到第四列的内容
cv::Mat b(a, Range(2, 5));//从a中截取第二行到第五行的内容

2.2、Mat类的赋值

在构造时赋值

cv::Mat::Mat(int rows, int cols, int type, const Scalar & s)

其中rows:矩阵的行数; cols:矩阵的列数;type:存储数据的类型;s:给矩阵中每个橡树赋值的参数变量,例如Scalar(0,0,255)

例如:

cv::Mat a(2, 2, CV_8UC3, cv::Scalar(0, 0, 255));//创建一个3通道矩阵,每个像素都是0,0,255
cv::Mat a(2, 2, CV_8UC2, cv::Scalar(0, 255));//创建一个2通道矩阵,每个像素都是0,255
cv::Mat a(2, 2, CV_8UC1, cv::Scalar(255));//创建一个单通道矩阵,每个像素都是255

 枚举法赋值

cv::Mat a= (cv::Mat_<int>(3,3)<<1,2,3,4,5,6,7,8,9);
cv::Mat a = (cv::Mat_<double>(2, 3) << 1.0, 2.0, 3.0, 4.0, 5.0, 6.0);

第一行创建一个3*3的  矩阵,数据类型为int型,一行一行的存入。

循环法赋值:

cv::Mat a = (cv::Mat_<int>(3, 3));//定义一个3*3的矩阵
for(int i = 0; i < a.cols;i++) //矩阵行数循环
{for (int j; j < a.cols; j++) //矩阵列数循环{a.at<int>(i, j) = i + j;}
}

利用类方法赋值示例:

 cv::Mat a = cv::Mat::eye(3, 3, CV_8UC1);cv::Mat b = (cv::Mat_<int>(1, 3) << 1, 2, 3);cv::Mat c = cv::Mat::diag(b);cv::Mat d = cv::Mat::ones(3, 3, CV_8UC1);cv::Mat e = cv::Mat::zeros(3, 2, CV_8UC3);

利用数组进行赋值:

3、Mat类支持的运算

3.1Mat类的加减乘除运算:

cv::Mat a = (cv::Mat_<int>(3, 3) << 1, 2, 3, 4, 5, 6, 7, 8, 9);
cv::Mat b = (cv::Mat_<int>(3, 3) << 1, 2, 3, 4, 5, 6, 7, 8, 9);
cv::Mat c = (cv::Mat_<double>(3, 3) << 1.0, 2.0, 3.0, 4.0,5.0, 6.0, 7.0, 8.0, 9.0);
cv::Mat d = (cv::Mat_<double>(3, 3) << 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0);
cv::Mat e, f, g, h,i;
e = a + b;
f = c - d;
g = 2 * a;
h = d / 2.0;
i = a - 1;

当两个类进行加减运算时,需保证数据要一致,比如int和double类型数据的两个类不能进行加减运算。常数与Mat类变量运算,结果的数据类型保留Mat类变量的数据类型。

3.2两个Mat类矩阵的乘法运算

cv::Mat a = (cv::Mat_<int>(3, 3) << 1, 2, 3, 4, 5, 6, 7, 8, 9);
cv::Mat b = (cv::Mat_<int>(3, 3) << 1, 2, 3, 4, 5, 6, 7, 8, 9);
cv::Mat c = (cv::Mat_<double>(3, 3) << 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0);
cv::Mat d = (cv::Mat_<double>(3, 3) << 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0);
cv::Mat e, f;
double k;
e = c*d;//数学乘积
k = a.dot(b);//内积
f=a.mul(b)//对应位乘积

4、Mat类元素的读取

4.1多通道数据的存储

3通道3*3矩阵存储方式

先存储第一个元素的三个通道数据,再存储第二个元素三个通道数据。

 4.2Mat类常用属性和成员方法

属性 作用
cols 矩阵的列数
rows 矩阵的行数
steps 以字节为单位的有效宽度
dims 矩阵的维度
成员方法
elemSize() 每个元素的字节数
total() 矩阵中元素的个数
channels() 矩阵的通道数

4.3通过at读取Mat类通道矩阵的元素

 cv::Mat a = (cv::Mat_<int>(3, 3) << 1, 2, 3, 4, 5, 6, 7, 8, 9);int b = a.at<int>(0, 0);

通过at读取元素需要跟上“<数据类型>”,类型不匹配则会报错。该方法以坐标的形式给出需要读取的元素坐标(行数,列数)。

4.4通过at读取Mat类多通道矩阵的元素

因为单通道图像是一个二维矩阵,所以 a t方法的最后给出二维坐标即可访问对应位置元素。在OpenCv中,针对三通道,定义了,cv::Vec3b、cv::Vec3s、cv::Vec3w、cv::Vec3d、cv::Vec3f、cv::Vec3i共6种类型,其中数字表示通道数,最后一位是类型的缩写,b是uchar的缩写,s是short类型的缩写,w是ushort类型的缩写,d是double类型的缩写,f是float类型的缩写,i是int类型的缩写。

举例说明:

 cv::Mat a(3,4,CV_8UC3,Scalar(2,0,255));cv::Vec3b b = a.at<Vec3b>(0, 0);int first = b[0];  //值为2int second = b.val[1];//值为0int third = b.val[2];//值为255

4.5通过指针ptr读取Mat矩阵种的元素

矩阵中每一行的每个元素都是挨着放的,如果能找到每一行元素的起始地址位置,那么读取矩阵中每一行不同位置的元素时将指针在起始位置向后移动若干位即可。

 cv::Mat a(3,4,CV_8UC3,Scalar(2,0,255));for (int i = 0; i < a.rows;i++){uchar *ptr = a.ptr<uchar>(i);for (int j = 0; j < a.cols*a.channels(); j++){cout << (int)ptr[j] << endl;}}

当读取第2行数据中第3个数据时,可直接用a.ptr<uchar>(1)[2]直接访问

4.6通过迭代器访问Mat类矩阵中的元素

Mat类变量也是一个容器变量,故Mat类变量拥有迭代器,用于访问Mat变量中的数据,通过迭代器可以实现对矩阵中每一个元素的遍历。

 cv::Mat a = (cv::Mat_<uchar>(3, 3) << 3, 4, 5, 1, 6, 7, 8, 0, 1);cv::MatIterator_<uchar> it = a.begin < uchar > ();cv::MatIterator_<uchar> it_end = a.end < uchar >();for (int i = 0;it!=it_end;it++){cout << (int)(*it) << " ";if (++i%a.channels()==0){cout << endl;}}

Mat类的迭代器变量类型是cv::MatIterator_< >,在定义时同样需要在括号中声明数据的变量类型。Mat类迭代器的起始是Mat.begin< >(),结束是Mat.end< >(),与其他迭代器用法相同,通过“++”运算实现指针位置向下迭代,数据的读取方式是先读取第一个元素的每一个通道,之后再读取第二个元素的每一个通道,直到最后一个元素的最后一个通道。

Opencv中Mat类详细解读(学习笔记)相关推荐

  1. c++ python opencv_ubuntu下C++与Python混编,opencv中mat类转换

    C++ 与 Python 混编 因为赶项目进度,需要使用到深度学习的内容,不过现有的深度学习框架大多使用python代码,对于不会改写C++的朋友来说,需要耗费大量的时间去改写,因此,使用python ...

  2. OpenCV中Mat类的重载运算符operator()的用法

    图像处理开发需求.图像处理接私活挣零花钱,请加微信/QQ 2487872782 图像处理开发资料.图像处理技术交流请加QQ群,群号 271891601 定义如下: inline Mat Mat::op ...

  3. OpenCV中Mat类的图像如何设置ROI

    Mat类表示的图像进行ROI操作有两种方法 (1)使用拷贝构造函数Mat(constMat& m, const Rect& roi ),矩形roi指定了兴趣区 例如: [cpp] vi ...

  4. 在ROS下利用OpenCV的Mat类,将激光点云展开为深度图像(从零开始,超详细)

    激光雷达3D目标检测任务需要将地面滤除,滤除地面的方法多种多样:基于深度学习.基于栅格.基于平面拟合.基于条件随机场.基于深度图像等等.关于将点云转化为深度图像,PCL库中有相关函数,但使用起来有一定 ...

  5. OpenCV中Mat,图像二维指针和CxImage类的转换

    在做图像处理中,常用的函数接口有OpenCV中的Mat图像类,有时候需要直接用二维指针开辟内存直接存储图像数据,有时候需要用到CxImage类存储图像.本文主要是总结下这三类存储方式之间的图像数据的转 ...

  6. OpenCV中Mat的属性

    OpenCV中Mat的属性 最近在做一OpenCV的图像轮廓检验,但当用到霍夫变换时才发现对Mat的属性了解不足.Mat在OpenCV中的地位是及其重要的,因此有必要做一个总结. 大体上来说,Mat是 ...

  7. php return直接输出,PHP中return用法详细解读

    原标题:PHP中return用法详细解读 在大部分编程语言中,return关键字可以将函数的执行结果返回,PHP中return的用法也大同小异,对初学者来说,掌握PHP中return的用法也是学习PH ...

  8. Opencv中Mat的data数据只定义为uchar*类型,

    opencv中Mat的数据定义为指向uchar 的指针,而构造函数又提供了许多其他类型. 其实数据在内存中是一维存储的,而图像基本结构是二维的,3D图像还会是三维的:同时,彩色图像还有多个channe ...

  9. Java OpenCV之Mat类的概述、常用构造方法、常用函数

    Java OpenCV之Mat类 概述 头部信息 数据类型 数据部分 Mat对象的构造方法 Mat() Mat(long addr) Mat(int row,int cols,int type) Ma ...

最新文章

  1. 渐统江湖的项目原型生成工具 -- Maven Archetype
  2. pat 乙级 1021 个位数统计(C++)
  3. HTML学习笔记4之第五章第六章
  4. Pandas 中文文档
  5. cursor -- 定义鼠标样式
  6. Java基础学习总结(55)——java8新特性:stream
  7. python常用包有哪些品牌_python 常用包总结
  8. gerber文件怎么导贴片坐标_SMT贴片加工有哪些常用的名词
  9. python海龟作图好看图案_python海龟绘图,其实python也很强大,这些技能你知道吗?...
  10. 我搭的神经网络不work该怎么办!看看这11条新手最容易犯的错误
  11. html5 自动连线,基于html5二个div 连线
  12. Linux 下安装和配置 MinDoc
  13. 渐变背景和背景图片并存
  14. oob袋外估计matlab,机器学习:随机森林RF-OOB袋外错误率
  15. 一度智信|关于拼多多店铺数据分析细节
  16. Eclips IDE安装Python
  17. 如何去除图片水印不留痕迹_去水印工具
  18. Firefox 实用插件
  19. 日常食物生克关系与营养价值分析 (Tableau Public)
  20. vif诊断多重共线性

热门文章

  1. 做好自动化运维平台需要哪些技能?
  2. ggplot2 | R语言绘制世界地图choropleth
  3. 大数据识别“爱”的羊毛党,拒绝那些它“恨”的羊毛党
  4. 修复打开Excel提示
  5. Python open函数用法
  6. thegraph subgraph 踩坑之入门青铜
  7. 14-Time/Watermarker
  8. 5V降压1.8V芯片,稳压电路设计建议PW2059
  9. 外包模式下的精益敏捷开发 (人员能力篇)
  10. NOIP学习之函数与过程抽象:91.质数的和与积