三、大型数组类

OpenCV3对大型数据的存储,具有代表性的是 cv::Mat和cv::SparseMat 类型。 cv::Mat针对的是密集连续性的存储,大多数的图像数据被存储为这种类,即使数据为空,预留的存储空间仍然存在;而cv::SparseMat针对的是稀疏的存储方式,只有数据不为0才保留空间,否则不会预留。显然cv::SparseMat存储更为节省空间,典型使用cv::SparseMat的例如直方图数据的存储。

1 创建与初始化cv::Mat

cv::Mat用于密集连续型的n维数据存储。成员变量:

flags: 数据内容标识;
dims: 数据维数;
rows和cols: 数据行列数;
data: 指向存储的数据;
refcount: 用于智能指针的引用计数。
cv::Mat分为头部和数据部分,不拷贝数据的操作为“浅拷贝”,只是复制了头部;如果拷贝了数据则叫“深拷贝”,这种操作会创建空间并拷贝对方的数据。

m.row(j)返回一个Mat类型,m.row(j).copyTo(m.row(i)),可以用于讲一个Mat 拷贝到另一个Mat 中。

我们可以通过载入图像来创建Mat类型矩阵,当然也可以直接手动创建矩阵,基本方法是指定矩阵尺寸和数据类型:

// 先声明,再创建数据
cv::Mat m;
// Create data area for 3 rows and 10 columns of 3-channel 32-bit floats
m.create( 30, 20, CV_32FC3 );
// Set the values in the 1st channel to 1.0, the 2nd to 0.0, and the 3rd to 1.0
m.setTo( cv::Scalar( 255.0f, 0.0f, 255.0f ) );// 同时创建
cv::Mat m( 3, 10, CV_32FC3, cv::Scalar( 255.0f, 0.0f, 255.0f ) );// cv::Mat a(cv::Size(5,5),CV_8UC1); // 单通道cv::Mat b = cv::Mat(cv::Size(5,5),CV_8UC3); //3通道每个矩阵元素包含3个uchar值// 初始化方法cv::Mat mz = cv::Mat::zeros(cv::Size(5,5),CV_8UC1); // 全零矩阵cv::Mat mo = cv::Mat::ones(cv::Size(5,5),CV_8UC1);  // 全1矩阵cv::Mat me = cv::Mat::eye(cv::Size(5,5),CV_32FC1);  // 对角线为1的对角矩阵

结果:

其中,type的组成方式为:CV_{8U,16S,16U,32S,32F,64F}C{1,2,3} 。例如:CV_32FC3 代表32bit浮点类型的三通道数据。图像处理中常用的几种数据类型如下:

CV_8UC1// 8位无符号单通道
CV_8UC3// 8位无符号3通道
CV_8UC4
CV_32FC1// 32位浮点型单通道
CV_32FC3// 32位浮点型3通道
CV_32FC4

包括数据位深度8位、32位,数据类型U:uchar、F:float型以及通道数C1:单通道、C3:三通道、C4:四通道。

type函数

opencv中Mat存在各种类型,其中mat有一个type()的函数可以返回该Mat的类型。类型表示了矩阵中元素的类型以及矩阵的通道个数,它是一系列的预定义的常量,其命名规则为CV_(位数)+(数据类型)+(通道数)。具体的有以下值:

2 元素访问

cv::Mat元素的方式:位置访问、迭代器访问和块访问。

2.1 位置访问

最直接的位置访问方式是使用 at<>() 

cv::Mat m = cv::Mat::eye( 10, 10, 32FC1 );//创建单位阵
printf("Element (3,3) is %f\n",m.at<float>(3,3));cv::Mat m = cv::Mat::eye( 10, 10, 32FC2 );
printf("Element (3,3) is (%f,%f)\n",m.at<cv::Vec2f>(3,3)[0],m.at<cv::Vec2f>(3,3)[1]);

2.2 迭代器访问

使用 cv::MatIterator<> 和cv::MatConstIterator<> 迭代器可以对cv::Mat元素进行访问:

int sz[3] = { 4, 4, 4 };
cv::Mat m( 3, sz, CV_32FC3 ); // A three-dimensional array of size 4-by-4-by-4
cv::randu( m, -1.0f, 1.0f ); // fill with random numbers from -1.0 to 1.0
float max = 0.0f; // minimum possible value of L2 normcv::MatConstIterator<cv::Vec3f> it = m.begin();
while( it != m.end() )
{len2 = (*it)[0]*(*it)[0]+(*it)[1]*(*it)[1]+(*it)[2]*(*it)[2];if( len2 > max ) max = len2;it++;
}

2.3 块访问

块访问提供对cv::Mat子数组的访问方式。这种访问方式返回的往往是个数组或范围,而不是单个元素。

m.row( i );    //Array corresponding to row i of m
m.col( j );    //Array corresponding to column j of m

m.rowRange( i0, i1 );                         //Array corresponding to rows i0 through i1-1 of matrix m
m.rowRange( cv::Range( i0, i1 ) );    //Array corresponding to rows i0 through i1-1 of matrix m
m.colRange( j0, j1 );                         //Array corresponding to columns j0 through j1-1 of matrix m
m.colRange( cv::Range( j0, j1 ) );    //Array corresponding to columns j0 through j1-1 of matrix m

函数原型:Mat cv::Mat::colRange(int startcol, int endcol) const

功能:该方法为矩阵的指定列跨度创建一个矩阵头。 类似于Mat :: row和Mat :: col,这是一个O(1)操作

参数:(分别表示我们想取的Mat的第几列到第几列)

  • startcol:一个包含0的起始索引的列跨度。
  • endcol:一个除0以外的结束索引的列跨度。

m.diag( d );//Array corresponding to the d-offset diagonal of matrix m

m( cv::Rect(i0,i1,w,h) );    //Array corresponding to the subrectangle of matrix m with one cornerat i0, j0 and the opposite corner at (i0+w-1, j0+h-1)

3、矩阵运算

矩阵加减法

我们可以使用"+"和"-"符号进行矩阵加减运算。

cv::Mat a= Mat::eye(Size(3,2), CV_32F);
cv::Mat b= Mat::ones(Size(3,2), CV_32F);
cv::Mat c= a+b;
cv::Mat d= a-b;

矩阵乘法

使用"*"号计算矩阵与标量相乘,矩阵与矩阵相乘(必须满足矩阵相乘的行列数对应规则)

 Mat m1= Mat::eye(2,3, CV_32F); //使用cv命名空间可省略cv::前缀,下同Mat m2= Mat::ones(3,2, CV_32F);cout<<"m1  = "<<endl<<m1<<endl<<endl;cout<<"m2  = "<<endl<<m2<<endl<<endl;// Scalar by matrixcout << "\nm1.*2 = \n" << m1*2 << endl;// matrix per element multiplicationcout << "\n(m1+2).*(m1+3) = \n" << (m1+1).mul(m1+3) << endl;// Matrix multiplicationcout << "\nm1*m2 = \n" << m1*m2 << endl;

矩阵转置

矩阵转置是将矩阵的行与列顺序对调(第i行转变为第i列)形成一个新的矩阵。OpenCV通过Mat类的t()函数实现。

// 转置Mat m1= Mat::eye(2,3, CV_32F); Mat m1t = m1.t();cout<<"m1  = "<<endl<<m1<<endl<<endl;cout<<"m1t  = "<<endl<<m1t<<endl<<endl;system("pause");

求逆矩阵

逆矩阵在某些算法中经常出现,在OpenCV中通过Mat类的inv()方法实现

// 求逆Mat meinv = me.inv();cout<<"me  = "<<endl<<me<<endl<<endl;cout<<"meinv = "<<endl<<meinv<<endl<<endl;system("pause");

计算矩阵非零元素个数

计算物体的像素或面积常需要用到计算矩阵中的非零元素个数,OpenCV中使用countNonZero()函数实现。

// 非零元素个数int nonZerosNum = countNonZero(me); // me为输入矩阵或图像cout<<"me  = "<<endl<<me<<endl;cout<<"me中非零元素个数 = "<<nonZerosNum<<endl<<endl;system("pause");

均值和标准差

OpenCV提供了矩阵均值和标准差计算功能,可以使用meanStdDev(src,mean,stddev)函数实现。

参数

  • src – 输入矩阵或图像
  • mean – 均值,OutputArray
  • stddev – 标准差,OutputArray
// 均值方差Mat mean;Mat stddev;meanStdDev(me, mean, stddev); //me为前文定义的5×5对角阵cout<<"mean = "<<mean<<endl;cout<<"stddev = "<<stddev<<endl;system("pause");

需要说明的是,如果src是多通道图像或多维矩阵,则函数分别计算不同通道的均值与标准差,因此返回值mean和stddev为对应维度的向量

 Mat mean3;Mat stddev3;Mat m3(cv::Size(5,5),CV_8UC3,Scalar(255,200,100));cout<<"m3  = "<<endl<<m3<<endl<<endl;meanStdDev(m3, mean3, stddev3);cout<<"mean3 = "<<mean3<<endl;cout<<"stddev3 = "<<stddev3<<endl;system("pause");

求最大最小值

求输入矩阵的全局最大最小值及其位置,可使用函数minMaxLoc();

void minMaxLoc(InputArray src, CV_OUT double* minVal,CV_OUT double* maxVal=0, CV_OUT Point* minLoc=0,CV_OUT Point* maxLoc=0, InputArray mask=noArray());

参数:

src – 输入单通道矩阵(图像).
minVal – 指向最小值的指针, 如果未指定则使用NULL
maxVal – 指向最大值的指针, 如果未指定则使用NULL
minLoc – 指向最小值位置(2维情况)的指针, 如果未指定则使用NULL
maxLoc – 指向最大值位置(2维情况)的指针, 如果未指定则使用NULL
mask – 可选的蒙版,用于选择待处理子区域
from:https://blog.csdn.net/iracer/article/details/51296631

cv::Mat支持的其他操作:

m1 = m0.clone();    //(深拷贝)Make a complete copy of m0, copying all data elements as well; cloned array willbe continuous
m0.copyTo( m1 );    //equivalent to m1=m0.clone()
m0.copyTo( m1, mask );  //Same as m0.copyTo(m1), except only entries indicated in the array mask arecopied
m0.convertTo(m1, type, scale, offset);  //在缩放或不缩放的情况下转换为另一种数据类型。m0.setTo( s, mask );    //将阵列中所有的或部分的元素设置为指定的值; if mask is present, set only those valuescorresponding to nonzero elements in mask
m0.reshape( chan, rows );   //在无需复制数据的前提下改变2D矩阵的形状和通道数或其中之一。m0.push_back( s );  //Extend an m × 1 matrix and insert the singleton s at the end
m0.push_back( m1 ); //Extend an m × n by k rows and copy m1 into those rows; m1 must be k × n
m0.pop_back( n );   Remove n rows from the end of an m × n (default value of n is 1)m0.locateROI( size, offset );   Write whole size of m0 to cv::Size size; if m0 is a “view” of a larger matrix,write location of starting corner to Point& offset
m0.adjustROI( t, b, l, r ); Increase the size of a view by t pixels above, b pixels below, l pixels to the left,and r pixels to the right
m0.total(); Compute the total number of array elements (does not include channels)
m0.isContinuous();  Return true only if the rows in m0 are packed without space between them inmemorym0.elemSize(); //Return the size of the elements of m0 in bytes (e.g., a three-channel float matrixwould return 12 bytes)
m0.elemSize1(); //Return the size of the subelements of m0 in bytes (e.g., a three-channel floatmatrix would return 4 bytes)m0.type();  //Return a valid type identifier for the elements of m0 (e.g., CV_32FC3)
m0.depth(); //Return a valid type identifier for the individial channels of m0 (e.g., CV_32F)
m0.channels();  //Return the number of channels in the elements of m0
m0.size();  //Return the size of the m0 as a cv::Size object
m0.empty(); //Return true only if the array has no elements (i.e., m0.total==0 orm0.data==NULL)

推荐一个写的很好的Mat矩阵的博客:https://blog.csdn.net/giantchen547792075/article/details/7169255

from:http://blog.sina.com.cn/s/blog_7908e1290101i97z.htm

OpenCV3学习(2.2)——图像Mat矩阵操作与常用函数相关推荐

  1. Opencv Mat矩阵操作

    Opencv Mat矩阵操作 1.生成矩阵: Mat image(240, 320, CV8UC3); 第一个参数是rows,该矩阵的行数:第二个参数是cols,该矩阵的列数:第三个参数是该矩阵元素的 ...

  2. tensorFlow基础操作及常用函数

    tensorFlow基础操作及常用函数 1. 安装Tensorflow 2. TensorFlow基本操作 3. TensorFlow常用函数 3.1 常用矩阵创建方式 3.2 高斯初始化及洗牌操作 ...

  3. (_cai_) opencv学习笔记(1):图像形态学计算的方式 morphology函数的应用

    1.腐蚀 概述:腐蚀掉图像的细节.若图像有很多毛刺,通过腐蚀操作,可以将毛刺消除. 下面所说的"值"可以简单理解为RGB三个通道[0,255],值越小,亮度越低,值越大,亮度越高. ...

  4. python文件函数_Python之文件操作及常用函数

    常见全局函数: 1.dir(nameStr): 常见系统变量: 1.sys.path:一个包含Python自动搜索文件的路径或目录的列表.可使用列表的操作方法修改.增加默认搜索路径. 一.模块 1.创 ...

  5. Mat矩阵操作,C++

    本文章转自https://blog.csdn.net/guoming0000/article/details/8629885 一.矩阵 Mat I,img,I1,I2,dst,A,B; double ...

  6. 【opencv学习】【图像的数值计算操作】

    import cv2# 展示图像,封装成函数 def cv_show_image(name, img):cv2.imshow(name, img)cv2.waitKey(0) # 等待时间,单位是毫秒 ...

  7. python学习-列表的操作(常用函数均会介绍)

    列表的操作 基本操作 进阶 附加内容 基本操作 本文中的基本操作有:获取最大,最小值,获取某个元素在列表中出现的次数. 列表的append,insert,remove,以及下标取值,赋值. 列表的扩展 ...

  8. 读书笔记之 数据框操作与常用函数

    如何把列表转化为整齐的矩阵? mylist<-as.list(iris[,1:4]) result<-sapply(mylist,mean) result<-lapply(mylis ...

  9. Python OS 文件操作模块常用函数

    我们经常会与文件和目录打交道,对于这些操作python提供了一个os模块,里面包含了很多操作文件和目录的函数.全部函数可以用help(os)或是dir(os)查看其用法. 常用的函数如下: 1.重命名 ...

最新文章

  1. boost::phoenix::function相关的测试程序
  2. InetAddressSocket使用总结
  3. 强化学习 求解迷宫问题_使用天真强化学习的迷宫求解器
  4. debug和release的区别
  5. ubuntu Django项目后台不挂断运行之screen命令
  6. qt stylesheet 隐藏_Qt QDockWidget实现鼠标移出自动隐藏
  7. CV之Haar特征描述算子-人脸检测
  8. 蓝桥杯 ALGO-21算法训练 装箱问题 java版
  9. Android课设电台论文,基于Android的超短波电台多媒体传输系统
  10. python超简单语音识别
  11. linux查看服务器时间,Linux 查看当前时间
  12. 【渝粤教育】电大中专药物化学基础 (2)作业 题库
  13. SBX(Simulated binary crossover)模拟二进制交叉算子和DE(differential evolution)差分进化算子...
  14. 原创|我常用的3款脑图工具
  15. 基于STM32F103c8t6的智能垃圾桶项目
  16. Oracle exp导出
  17. html h5 php 语音录入,html5在输入框添加语音输入功能
  18. 微博话题下的数据爬取
  19. 华为和小米共推中国制造,增强国产手机产业链的自主研发实力
  20. 淘宝自动刷喵币!靠这一个脚本就够了

热门文章

  1. c语言判断回文字符串递归,用递归实现判断一个字符串是否为回文串
  2. css上传图片中等待不可点击效果
  3. 记一次修改redis需要外部访问
  4. css编写规则BEM
  5. leetcode 203. Remove Linked List Elements(链表)
  6. 读《编程之美》读后感3
  7. atitit。获取表格的字段注释metadata的原理以及AND 字段表格描述文档方案
  8. DWR2学习笔记(一)
  9. 50个最有价值的数据可视化图表
  10. Centos7安装并配置mysql5.6