OpenCV Mat类数据存储方式
参考BiliBili 于仕琪老师 avoid-memory-copy-in-opencv
class CV_EXPORTS Mat
{
public:
// some members
int rows, cols;
//pointer to data
uchar* data;
//size_t step.p
MatStep step;
};

refcount* 起到智能指针的引用计数作用,Mat类中智能指针机制是OpenCV自行实现的,并没有用到C++的智能指针。
- step的作用一:实现内存对齐便于加速

- step的作用二:

注意,图像矩阵虽然可视化为二维的,但其在内存中是线性储存的一维数组。举个例子,

3行3列3通道的连续存储Mat, mat.data[9]为对应图像的第二行第一列的B通道的值,(&mat.data[9])[1]为第二行第一列的G通道的值。注意,不能使用mat.data[1][1]去索引该值,因为其不是多维数组,而是一维的。
对上图的c而言,其指针指向的不是Matrix Data的首地址,而是后面的某一个地址,且c图像矩阵的每一行不是连续存储的。换言之其每行的最后一个元素的下一个元素不是下一行的首元素。
通过存储step可以解决矩阵元素不连续存储的问题。
第二行的首元素相对于第一行的首元素,其偏移量为step,step为完整的大矩阵每行的字节数。
所以遍历该不连续的矩阵,可以写出如下代码:
for (int row = 0; row < mat.rows; row++)
{
for (int col = 0; col < mat.cols; col++)
{
(&mat.data[row*step])[col * channels * elemSize1] = ...
(&mat.data[row*step])[(col * channels + 1) * elemSize1] = ...
(&mat.data[row*step])[(col * channels + 2) * elemSize1] = ...
}
}
// mat.data[row*step] 数组索引相当于指针解引用
// 此处需要获取每一行的首地址, 所以需要&取值
也可以用mat.ptr<typename T>(row)
for (int row = 0; row < mat.rows; row++)
{
uchar* row_data = mat.ptr<uchar>(row) //获取第row行的首地址
for (int col = 0; col < mat.cols; col++)
{
row_data[col * channels * elemSize1] = ...
row_data[(col * channels + 1) * elemSize1] = ...
row_data[(col * channels + 2) * elemSize1] = ...
}
}
- Mat的step和索引
void test()
{
Mat img(2, 2, CV_16UC4, Scalar_<uchar>(1, 2, 3, 4));
using namespace std;
cout << img << endl;
cout << "step:" << img.step << endl;
cout << "step[0]:" << img.step[0] << endl;
cout << "step[1]:" << img.step[1] << endl;
cout << "step1(0):" << img.step1(0) << endl;
cout << "step1(1):" << img.step1(1) << endl;
cout << "img.data[1 * step] = " << static_cast<int>(img.data[img.step]) << endl;
cout << "(&img.data[1 * step])[1] = " << static_cast<int>((&img.data[img.step])[1]) << endl;
cout << "(&img.data[1 * step])[2] = " << static_cast<int>((&img.data[img.step])[2]) << endl;
cout << "(&img.data[1 * step])[4] = " << static_cast<int>((&img.data[img.step])[4]) << endl;
cout << "(&img.data[1 * step])[6] = " << static_cast<int>((&img.data[img.step])[6]) << endl;
cout << "(&img.data[1 * step])[8] = " << static_cast<int>((&img.data[img.step])[8]) << endl;
cout << "(&img.data[1 * step])[10] = " << static_cast<int>((&img.data[img.step])[10]) << endl;
cout << "img.elemSize = " << img.elemSize() << endl;
cout << "img.elemSize1 = " << img.elemSize1() << endl;
cout << "img.channels = " << img.channels() << endl;
cout << "img.cols = " << img.cols << endl;
}
>>>
[1, 2, 3, 4, 1, 2, 3, 4;
1, 2, 3, 4, 1, 2, 3, 4]
step:16
step[0]:16
step[1]:8
step1(0):8
step1(1):4
img.data[1 * step] = 1
(&img.data[1 * step])[1] = 0
(&img.data[1 * step])[2] = 2
(&img.data[1 * step])[4] = 3
(&img.data[1 * step])[6] = 4
(&img.data[1 * step])[8] = 1
(&img.data[1 * step])[10] = 2
img.elemSize = 8
img.elemSize1 = 2
img.channels = 4
img.cols = 2
OpenCV Mat类数据存储方式的更多相关文章
- OpenCV Mat格式存储YUV图像
YUV图像用的比较多,而且YUV图像的格式众多(YUV格式可以参考YUV pixel formats),如何用OpenCV的Mat类型来存储YUV图像也是经常遇到的问题. 对于YUV444图像来说,就 ...
- Android 接入 OpenCV库的三种方式
OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉库,可以运行在Linux.Windows.Android和Mac OS操作系统上.它轻量级而且高效——由一系列 C 函数和少 ...
- 【转】OpenCV Mat数据结构
转载自xiahouzuoxin原文 OpenCV基础篇之Mat数据结构 程序及分析 /* * FileName : MatObj.cpp * Author : xiahouzuoxin @163.co ...
- [OpenCV]Mat类详解
http://blog.csdn.net/yang_xian521/article/details/7107786 Preface Mat:Matrix Mat类可以被看做是opencv中C++版本的 ...
- OpenCV Mat数据类型及位数总结(转载)
OpenCV Mat数据类型及位数总结(转载) 前言 opencv中很多数据结构为了达到內存使用的最优化,通常都会用它最小上限的空间来分配变量,有的数据结构也会因为图像文件格式的关系而给予适当的变量, ...
- Qt QImage与OpenCV Mat转换
本系列文章由 @yhl_leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/51029382 应一个朋友的要求,整理总 ...
- IOS的四种数据存储方式及优劣
IOS有四种经常使用数据存储方式: 第一种方法:用NSUserDefaults存储配置信息 NSUserDefaults被设计用来存储设备和应用的配置信息.它通过一个工厂方法返回默认的.也是最经常使用 ...
- Ubuntu系统---编译opencv程序的几种方式g++、Makefile、Cmake
Ubuntu系统---编译opencv程序的几种方式g++.Makefile.Cmake 先建立一个工程(一个文件夹),写好xxx.cpp文件,可以是多个: //----------opencv.cp ...
- 前端HTML5几种存储方式的总结
接下来要好好总结一些知识,秋招来啦...虽然有好多知识都不大会,但是还是要努力一下,运气这种东西,谁知道呢~ 总体情况 h5之前,存储主要是用cookies.cookies缺点有在请求头上带着数据,大 ...
- Kooboo CMS技术文档之三:切换数据存储方式
切换数据存储方式包括以下几种: 将文本内容存储在SqlServer.MySQL.MongoDB等数据库中 将站点配置信息存储在数据库中 将后台用户信息存储在数据库中 将会员信息存储在数据库中 将图片. ...
随机推荐
- LeetCode-475 供暖器
来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/heaters 题目描述 冬季已经来临. 你的任务是设计一个有固定加热半径的供暖器向所有房屋供暖. ...
- 第四周作业-N67044-张铭扬
1. 自定义写出10个定时任务的示例:比如每周三凌晨三点执行data命令要求尽量的覆盖各种场景 1)每天早上8点对磁盘使用率进行查看,若超出空间的80%,则发邮件报警 [root@centos8 ~] ...
- Python读取保存图像文件
Python处理图像数据时通常需要对图像文件进行读取.保存等操作,因此将现有的方法归纳了一下. 1. PIL 依赖包:Pillow 安装:pip install Pillow 源码: 1 import ...
- SAP 交货单抬头客制化界面以及字段
需求 因为涉及系统之间的家伙但传输,方便业务查看该交货单是否已经发送,因此再交货单的抬头页面进行增强,给出一个是否发送的字段显示.如下: 业务加载项 LE_SHP_TAB_CUST_HEAD se19 ...
- golang流程控制if,switch分支
if 分支 if 单分支 if 条件表达式 { 逻辑代码 } package main import "fmt" func main() { //var a int = 9 //i ...
- layui富文本编辑器提交时无法获取到值
使用layui的富文本提交时一直获取不到值,仔细检查代码之后发现是没有绑定textarea,要将编辑器中的内容同步到textarea中. 先在lay-verify="名字"中输入一 ...
- 2015 for Mac PDF编辑软件
开始前请先断开网络连接,断网,断网,断网! 开始前请先断开网络连接,断网,断网,断网! 开始前请先断开网络连接,断网,断网,断网! 编辑 1.软件下载完成后,打开软件包如上图五个文件(第1个是安 ...
- USB从机主动断开连接
目录 在一些情况下,需要USB口的引脚复用成其他功能,比如说PB10.PB11要复用成定时器输出引脚:或者需要USB从机主动断开,类似某些杀毒软件带的"安全弹出",不过杀毒软件操作 ...
- 题解[CF575E]Spectator_Riots
题意 一个球场,可以看作 \(10^5\times10^5\) 的矩形,每个位置都是一个整点.一个位置 \((x,y)\) 位于球场内当且仅当 \(x\in[0,10^5]\and y\in[0,10 ...
- 070_GET https://login.salesforce.com/17181/logo180.png 404 (Not Found)
这个问题怎么解答? Google了一下:https://success.salesforce.com/answers?id=90630000000D6qzAAC 谷歌应用商店安装了一个 Resourc ...