1.Mat基础

在计算机内存中,数字图像是已矩阵的形式保存的。OpenCV2中,数据结构Mat是保存图像像素信息的矩阵,它主要包含两部分:矩阵头和一个指向像素数据的矩阵指针。
矩阵头主要包含,矩阵尺寸、存储方法、存储地址和引用次数等。
矩阵头的大小是一个常数,不会随着图像的大小而改变,但是保存图像像素数据的矩阵则会随着图像的大小而改变,通常数据量会很大,比矩阵头大几个数量级。这样,在图像复制和传递过程中,主要的开销是由存放图像像素的矩阵而引起的。因此,OpenCV使用了引用次数,当进行图像复制和传递时,不再复制整个Mat数据,而只是复制矩阵头和指向像素矩阵的指针。例如:
1
2
3
cv::Mat a ; //创建矩阵头
a = cv::imread( "f:\\psb.jpg" ); //读入图像
cv::Mat b = a ; //复制 

上面的a,b有各自的矩阵头,但是其矩阵指针指向同一个矩阵,也就是其中任何一个改变了矩阵数据都会影响另外一个。
那么,多个Mat共用一个矩阵数据,最后谁来释放矩阵数据呢?
这就是引用计数的作用,当Mat对象每被复制一次时,就会将引用计数加1,而每销毁一个Mat对象(共用同一个矩阵数据)时引用计数会被减1,当引用计数为0时,矩阵数据会被清理。
上图是Mat对象a,b共用一个矩阵,故其引用计数refcount为2.
但是有些时候仍然会需要复制矩阵数据本身(不只是矩阵头和矩阵指针),这时候可以使用clone 和copyTo方法。
cv::Mat c = a.clone();
cv::Mat d ;
a.copyTo(d);
上面代码中的c,d各自拥有自己的矩阵,改变自己的矩阵数据不会相互影响。
在使用Mat中,需要记住:
  1. OpenCV中的内存分配是自动完成的(不是特别指定的话)
  2. 使用OpenCV的C++ 接口时不需要考虑内存释放问题
  3. Mat的赋值运算和拷贝构造函数只会拷贝矩阵头,仍然共同同一个矩阵
  4. 如果要复制矩阵数据,可以使用clone和copyTo函数

2.Mat存储方法

Mat中矩阵的每个元素可以使用不同的数据类型,最小的数据类型是char,占用一个字节或者8位,可以是有符号的(0到255)或者是无符号的(-127到127)。在RGB颜色空间中,使用三个char类型可以表示1600万中颜色,但在图像处理的过程中有可能会使用到float或者double来表示图像的像素。

Mat的创建

构造函数
cv::Mat img(2,2,CV_8UC3,cv::Scalar(0,0,255));

上述代码创建了一个2行2列的矩阵,矩阵元素使用8位无符号char类型保存,具有3通道,每个像素的初始值是(0,0,255)
构造函数的前两个参数指定了矩阵的行和列
第三个参数指定矩阵元素的数据类型以及通道数,其指定规则如下:
CV_[The number of bits per item][Signed or Unsigned][TypePrefix]C[The channel number]

四部分分别指定:元素的大小,是有符号还是无符号,数据类型以及通道数

最后一个参数,Scalar是short型的vector,提供矩阵的初始化。
Create方法
该方法不能为矩阵设置初始值,只是在改变尺寸时为矩阵数据重新分配内存。使用方法:
img.create(4,4,CV_8UC(2));

创建了一个4行4列有2个通道的矩阵
MATLAB形式的初始化
cv::Mat e = cv::Mat::eye(4,4,CV_64F);
cv::Mat z = cv::Mat::ones(2,2,CV_32F);
cv::Mat o = cv::Mat::zeros(3,3,CV_8UC1);
Mat e是4行4列的对角矩阵
Mat z是2行2列的单位矩阵
Mat o是3行3列的零矩阵
小矩阵的初始化
对于小矩阵可以使用逗号分割的初始化函数
Mat c =(Mat_<double>(3,3)<<1,2,3,0,-1,0,4,5,6);

在对图像进行模板运算时,定义模板使用这种方法是很方便的。

3.Mat的输入输出

使用imread函数,向Mat对象中写入一个图像。
a = cv::imread("f:\\psb.jpg");//读入图像
imread的原型如下
cv::Mat imread(const string& filename,int flags=1)

filename指定要读取图像的位置
flags指定图像的颜色空间  
    flags > 0 3通道的彩色图像
     flags = 0 灰度图像
    flags < 0 不作改变
也可以有以下的枚举值
CV_LOAD_IMAGE_ANYDEPTH、 CV_LOAD_IMAGE_COLOR、 CV_LOAD_IMAGE_GRAYSCALE
 
使用imwrite函数,将Mat对象保存到指定的文件中。
imwrite的函数原型如下:
bool imwrite(const string& filename,InputArray img,constvector<int>& params=vector<int>())

filename,指定的文件
img  要保存的Mat对象
params 用来指定图像的保存编码方式。
使用filename的扩展名来指定图像的保存格式(.jpg  .png  .bmp),对于不同的图像保存类型,params是不同的值
  • JPEG,params用来指定图像的质量(0到100),默认的是95.  CV_IMWRITE_JPEG_QUALITY
  • PNG,params用来指定图像的压缩级别(0到9),压缩级别越高图像占用的空间越小,保存图像所用的时间越久。默认值是3. CV_IMWRITE_PNG_COMPRESSION
  • PPM,PGM,PBM,params是一个标记(0或者1),默认的是1.CV_IMWRITE_PXM_BINARY
imwrite只能保存8位( 或者是16位无符号(CV_16UC)的PNG,JPEG200或者TIFF图像) 单通道或者三通道的图像, 如果要保存的不是这样的图片,可以使用convertTo或者cvtColor来进行转变。
下面代码展示了如果使用imwrite向文件中写入一个4通道的png图像
void createAlphaMat(Mat &mat)
{for(int i = 0 ; i < mat.rows ; i ++) {for(int j = 0 ; j < mat.cols ; j ++) {Vec4b &rgba = mat.at<Vec4b>(i,j);rgba[0] = UCHAR_MAX ;rgba[1] = saturate_cast<uchar>((float (mat.cols - j)) / ((float)mat.cols) * UCHAR_MAX);rgba[2] = saturate_cast<uchar>((float (mat.rows - i)) / ((float)mat.rows) * UCHAR_MAX);rgba[3] = saturate_cast<uchar>(0.5 * (rgba[1] + rgba[2]));}}
}
int main()
{Mat mat(480,640,CV_8UC4);createAlphaMat(mat);vector<int> compression_params ;compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION);compression_params.push_back(9);imwrite("alpha.png",mat,compression_params);return 0;
}

4.Mat的显示

OpenCV提供了用以窗口的形式显示图片的方法,代码如下:
Mat img = imread("f:\psb.jpg");
const string name ="Hu";
namedWindow(name);
imshow(name,img);
waitKey();

cv::mat的基本操作相关推荐

  1. OpenCv学习笔记(二)—cv Mat学习

    由于在写上一篇图像的数据结构时,发现自己只知道CvMat,竟然还有Mat数据结构,真是无知了,看了这么多程序,貌似没有看到这个结构.有可能那些程序都是些老版本的例子,这是在2.0以后加上的,所以我也得 ...

  2. 【OpenCv】c++ 入门认识 Mat 类,单通道 Mat 的基本操作

    文章目录 前言 Mat 类 Mat 类的构造方式 Mat 基本操作 单通道 Mat 的基本操作 使用成员变量 rows 和 cols 获取矩阵的行数和列数 使用成员函数 size() 来获取矩阵的尺寸 ...

  3. Mat矩阵基本操作与示例 OpenCV

    OpenCV的基本矩阵操作与示例 OpenCV中的矩阵操作非常重要,本文总结了矩阵的创建.初始化以及基本矩阵操作,给出了示例代码,主要内容包括: 创建与初始化 矩阵加减法 矩阵乘法 矩阵转置 矩阵求逆 ...

  4. OpenCV【零】—————cv::Mat——Mat对象创建方法

    OpenCV (一)--Mat对象创建方法 目录 OpenCV (一)--Mat对象创建方法 1. cv::Mat优点及原理(本质类) 2. Mat类拷贝及对象的创建方法 3. Mat 对象元素的高效 ...

  5. 【FFmpeg】使用sws_scale将AVFrame转换后的图像数据放入cv::Mat中

    1.方法一,伪代码如下 cv::Mat mat; AVFrame avFrame; const int stride[] = {static_cast<int>(mat.step[0])} ...

  6. 【OpenCV】正确创建用于保存YUV420P格式的cv::Mat

    1.问题描述 cv::Mat保存RGB24或BRG24格式时,传入宽.高和格式类型CV_8UC3就行了:今天在创建cv::Mat用来保存YUV420P时,有点懵圈了,因为类型是CV_8UC1,直接传宽 ...

  7. 【OpenCV】cv::Mat和std::vector之间的相互转换

    Mat转换成Vector 以vector 为例,其它模型类似 vector getVector(const Mat & a) { Mat b; a.convertTo(b, CV_64F); ...

  8. cv::Mat使用笔记

    1. 构造 无参数构造方法 Mat::Mat() 创建行数为 rows,列数为 col,类型为 type 的图像 Mat::Mat(int rows, int cols, int type) 创建大小 ...

  9. OpenCV学习(4) Mat的基本操作(1)

    图像在OpenCV中都是通过Mat类来存储的,Mat可以用来表示N维矩阵,当然用的最多的还是二维矩阵. Mat类有两部分组成:第一部分是头信息,这些信息主要用来描述矩阵,比如矩阵维数ndims,row ...

最新文章

  1. sftp进入指定目录_CentOS7服务搭建----搭建SFTP(安全文件传送协议)服务器
  2. angular5 httpclient的示例实战
  3. adb shell 修改文件名_从零开始学Linux运维|27.Shell编程(函数与参数的传递)
  4. 查看Unity工程版本
  5. linux过滤端口抓包_Linux抓包工具tcpdump使用总结,WireShark的过滤用法
  6. 无人出租车被警察截停后逃逸!AI:我当时害怕极了
  7. 还有必要吗?iPhone 11系列终于要全家族支持双卡双待了
  8. 【kafka】kafka Producer Metadata概述及源码分析
  9. 在C#中利用Keep-Alive处理Socket网络异常断开的方法 (转)
  10. 上海GDD(谷歌开发者大会),第一天总结
  11. python 螺旋数组_奇技淫巧 - Python绘制各种简单优美曲线
  12. sun的java认证考试_Sun Java认证考试科目
  13. 设计模式-Builder模式详解
  14. 忆我的大学老师----(一)
  15. 第12届信息化领袖峰会丨行程安排新鲜出炉
  16. 数据分析Power BI数据建模教程(四)——如何创建计算度量值和计算表
  17. 华硕路由搭建php网站,华硕路由器操作模式
  18. 用腾讯云COS制作个人图床
  19. VMware虚拟机的安装,并编写简单的C程序
  20. PHP PEAR网站遭黑客入侵,官方软件安装包被篡改

热门文章

  1. CTeX里是如何无限期试用winedt 7的
  2. python渗透测试入门之burpsuite载核生成器
  3. 机器学习资料与攻略超强整理吐血推荐(一)
  4. Android 13正式发布,谷歌I/O大会你不得不知的4大看点
  5. 顺序表插入删除查找操作
  6. win10连接共享打印机报错问题如0x00000709/0x0000011b/0x00000040等
  7. 《互联网金融投资理财一册通》一一第2章 揭秘余额宝收益背后的秘密
  8. 三个好用的云渲染推荐
  9. FinalData恢复数据
  10. 更新Linux维护的PCI硬件数据库,Bus options (PCI etc.)总线选项 - Linux-4.4-x86_64 内核配置选项...