OpenCV 第二课 认识图像的存储结构
OpenCV 第二课 认识图像的存储结构
Mat 类包含两部分,矩阵头和矩阵体。矩阵头包含矩阵的大小,存储方式和矩阵体存储空间的指针。因此,Mat中矩阵头的大小是固定的,矩阵体大小是不定的。
为了减少矩阵拷贝产生的计算消耗,opencv中一般使用引用计数方式处理矩阵,比如下面三种创建Mat的形式
- Mat A,C; //这里仅仅创建了矩阵头,具体矩阵体还没创建
- A=imread(argv[1],CV_LOAD_IMAGE_COLOR); //给矩阵分配空间,并将首地址给了A
- Mat B(A); //拷贝构造函数,B是A的拷贝,只是矩阵头不同
- C=A; //赋值操作仍然指向的是同一块矩阵体地址。
这时候使用任何一个Mat对象修改数据,其他的对象也会跟着变化。
如果想拷贝矩阵体,那么可以使用clone()和copyTo()函数。
- Mat F=A.clone();
- Mat G;
- A.copyTo(G)
为什么称为reference counting system呢,因为每次拷贝矩阵拷贝次数都加1,当一个拷贝结束时,拷贝次数减一,最后一个引用决定了这块地址什么时候释放。
需要注意的点:
Output image allocation for OpenCV functions is automatic (unless specified otherwise).
You do not need to think about memory management with OpenCVs C++ interface.
The assignment operator and the copy constructor only copies the header.
The underlying matrix of an image may be copied using the clone() and copyTo() functions
Mat的结构
- class CV_EXPORTS Mat
- {
- public:
- int flags;//标志位
- int dims;//维度>=2
- int rows,cols;//行和列或者(-1,-1),此时数组超过了2维
- uchar * data;//矩阵数据块的指针
- int *refcount;//指针引用计数器
- }
Mat的构造函数
- #include "opencv2/imgproc/imgproc.hpp"
- #include "opencv2/highgui/highgui.hpp"
- #include <iostream>
- #include<stdlib.h>
- using namespace cv;
- using namespace std;
- int main()
- {
- Mat image1; //创建无初始化的矩阵
- Mat image2(6, 6, CV_8UC1);//创建大小为6*6,8位unsigned单通道矩阵
- Mat image3(Size(7, 7), CV_8UC3);//创建7*7的size,8位无符号3通道矩阵
- Mat image4(8, 8, CV_32FC2, Scalar(1, 3));//创建8*8,32位浮点型2通道矩阵,赋值1+3j
- Mat image5(Size(9, 9), CV_8UC3, Scalar(1, 2, 3));//创建9*9大小的矩阵,3通道,8位无符号型,每一个位置三个通道初始化值为(1,2,3)
- Mat image6(image2);//使用已经创建的矩阵创建矩阵,这时候仅拷贝矩阵头,矩阵值指针是相同的
- cout << image1 << endl;
- cout << image2 << endl;
- cout << image3 << endl;
- cout << image4 << endl;
- system("PAUSE");
- }

看输出结果可以看出,Mat数据在存储时首先向同一个位置的多个通道值存储了再存储别的位置元素。
Mat的基本操作
- #include "opencv2/imgproc/imgproc.hpp"
- #include "opencv2/highgui/highgui.hpp"
- #include <iostream>
- #include<stdlib.h>
- using namespace cv;
- using namespace std;
- int main()
- {
- Mat image1(10, 8, CV_8UC1, Scalar(5));
- cout << "Image1 rows:" << image1.rows << endl; //行数
- cout << "Image1 col:" << image1.cols << endl;//列数
- cout << "Image channel:" << image1.channels ()<< endl;//通道,方法
- cout << image1.rowRange(1, 3) << endl; //取1,2两行
- cout << image1.colRange(1, 4) << endl;//取1,2,3列
- Mat image2(8, 8, CV_32FC2, Scalar(1, 5));
- image2.create(10, 10, CV_8UC3);//create重建举着数据
- //cout << image2 << endl;
- image2.convertTo(image2, CV_32F);//类型转换
- cout << "Image2 depth:" << image2.depth() << endl;//深度,方法
- Mat image3 = Mat::zeros(image1.rows, image1.cols, CV_8UC1);//全零矩阵
- Mat image4 = Mat::ones(image2.rows, image2.cols, CV_8UC1);//全一矩阵
- image4.row(1) = image4.row(2) * 5; //矩阵行操作,列操作可以使用row(),col()函数直接操作
- cout << image4 << endl;
- Mat image5 = image2.row(2);
- image1.row(1).copyTo(image5);//第一行拷贝到image5
- cout << image5 << endl;
- system("PAUSE");
- }
OpenCV 第二课 认识图像的存储结构的更多相关文章
- 跟我一起学opencv 第二课之图像的掩膜操作
1.掩膜(mask)概念 用选定的图像,图形或物体,对处理的图像(全部或局部)进行遮挡,来控制图像处理的区域或处理过程.用于覆盖的特定图像或物体称为掩模或模板.光学图像处理中,掩模可以足胶片,滤光片等 ...
- 跟我一起学opencv 第一课之图像加载,修改,保存
使用opencv前记得引入库和头文件: #include<opencv2\opencv.hpp> 1.加载图像(cv::imread)(OPENCV 支持 JPG,PNG,TIFF等常见格 ...
- opencv第二课 进行缩放图片~
#include<stdio.h> #include<iostream> #include<opencv2\opencv.hpp> using namespace ...
- opencv第二课,使用cmake编译OpenCV,并添加opencv_contrib模块
一.下载安装cmake 想要在Windows平台下生成OpenCV的解决方案,我们需要一个名为cmake的开源软件,可以在camke的官网:http://www.cmake.org/上下载到 或者点击 ...
- 【ios开发学习 - 第二课】iOS项目文件夹结构
文件夹结构 AppDelegate Models Macro General Helpers Vendors Sections Resources 一个合理的文件夹结构首先应该是清晰的.让人一眼看 ...
- OpenCV第二课,嵌入MFC
单纯显示图片,只需链接 opencv_core2411d.libopencv_highgui2411d.lib 1.首先创建一个MFC的dlg,添加Picture Control控件 void CCO ...
- NeHe OpenGL教程 第十三课:图像字体
转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...
- grails2.3.11第二课
第二课主要介绍grails相关插件的使用,这是敏捷开发所必需的途径. 可以把grails的插件看作是grails正常项目的迷你型,因为看插件的源码,它的目录结构和正常项目相差无几. 官方开源插件地址 ...
- (续)一个demo弄清楚位图在内存中的存储结构
本来续---数字图像处理之位图在计算机中的存储结构一文,通过参考别人的代码,进行修改和测试终于成功运行. 该实例未使用任何API和相关类,相信如果对此实例能够完全理解那么将有进一步进行数字图像处理的能 ...
随机推荐
- c语言中的浮点数
一.浮点数常量(小数) 0.11L, 0.0f ,0.0,1.88,2.5f ,0.188E1 E3表示103 比如 1.88E 3=1.88*1000=1880.0f E-3表示10- ...
- 消息队列MQ - Apache ActiveMQ
Apache ActiveMQ是Apache软件基金会所研发的开放源码消息中间件:由于ActiveMQ是一个纯Jave程式,因此只需要操作系统支持Java虚拟机,ActiveMQ便可执行. 1.que ...
- nyoj1007(euler 函数)
euler(x)公式能计算小于等于x的并且和x互质的数的个数: 我们再看一下如何求小于等于n的和n互质的数的和, 我们用sum(n)表示: 若gcd(x, a)=1,则有gcd(x, x-a)=1: ...
- 微信支付开发(1) JS API支付V3版(转)
http://www.cnblogs.com/txw1958/p/wxpayv3-jsapi.html 本文介绍微信支付下的jsapi实现流程 前言 微信支付现在分为v2版和v3版,2014年9月10 ...
- ASP.NET Web API 数据验证
第一种方式单独为每一个Action做验证 // POST api/values public HttpResponseMessage Post([FromBody]UserInfo userInfo) ...
- poj 1611:The Suspects(并查集,经典题)
The Suspects Time Limit: 1000MS Memory Limit: 20000K Total Submissions: 21472 Accepted: 10393 De ...
- Ubuntu下快速安装php环境
今天蛋疼了一下,在Ubuntu下装了一下php的环境,也就是装了一下MySQL.PHP.Apache.话说还真是简单...不禁让我想起原来在windows下开发的时候撑死就是装不上,而且一个就是几个G ...
- LIS的nlogn
nlogn老忘,开个帖记录一下 开一个栈,每次取栈顶元素top和读到的元素temp做比较,如果temp > top 则将temp入栈:如果temp < top则二分查找栈中的比temp大的 ...
- APP交互
交互设计基本功!5个值得学习的APP交互方式http://www.uisdc.com/5-interactive-design-worth-learning 移动App交互设计10大趋势–你用到了吗? ...
- windows内核需要注意的
修改windows内核函数 先屏蔽KdPrint 测试. Hook函数一律使用全局变量 妹的..KiTrap0E 修改.触发了已经断点.但是硬件断点Hook函数里只要使用KdPrint 就蓝屏