Mat中的step[i],step1(i),elemsize,elemsize1

2023-10-12 15:30

本文主要是介绍Mat中的step[i],step1(i),elemsize,elemsize1,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Mat中的step[i], step1(i), elemsize, elemsize1在读取数据和数据转换的时候经常用到,分析了目前比较流行的几种说法,加入了一些自己的见解。

文章目录

  • 概念
  • 举例说明
  • 代码演示

概念

elemsize指的是每个像素的字节数
elemsize1指的是每个像素值的字节数(比如三通道的图像每个像素有三个像素值)
step是一个数组,用 step 数据属性可得到单位是字节的图像的有效宽度,即使图像的类型不是 uchar,step 仍然能提供行的字节数。

举例说明

  1. opencv中Mat类的elemsize是每个像素的字节数,如果一个图像是3通道,每个通道是16位,那么其elemsize就是3*(16/8)=6,即每个元素占6个字节

  2. opencv中Mat类的elemsize1是指每个像素每个通道的像素值所占的字节数,对应于上面就是2个字节

  3. opencv中Mat类的step,step是一个数组,用 step 数据属性可得到单位是字节的有效宽度。即使图像的类型不是 uchar,step 仍然能提供行的字节数。有以下关系

step1(i) = step[i] / elemsize1;
step[m-1] = elemsize;

其中m是图像的维数,step1(m-1)=channels;

矩阵 (M) 中数据元素的地址计算公式:

$addr(Mi_0,i_1,…i_{m-1}) = M.data + M.step[0] * i0 + M.step[1] * i1 + … + M.step[m-1] * im-1 $
(其中 m = M.dims M的维度)

下面举例:对于2维的情况:
一个 3 X 4 的矩阵,假设其数据类型为 CV_8U,也就是单通道的 uchar 类型

这是一个二维矩阵,那么维度为 2 即:

M.dims == 2
M.rows == 3;
M.cols == 4;

sizeof(uchar) = 1,那么每一个数据元素大小为 1 。即

M.elemSize() == 1
M.elemSize1() == 1;

CV_8U 得到 M.depth() == 0, M.channels() == 1;

因为是二维矩阵,那么 step 数组只有两个值, step[0] 和 step[1] 分别代表一行的数据大小和一个元素的数据大小,则

M.step[0] == 4,
M.step[1] == 1
M.step1(0) == M.cols = 4;
M.step1(1) == 1;

假设上面的矩阵数据类型是 CV_8UC3,也就是三通道,则

M.dims == 2
M.channels() == 3
M.depth() == 0
M.elemSize() == 3 (每一个元素包含3个uchar值)
M.elemSize1() == 1 (elemSize / channels)
M.step[0] == M.cols * M.elemSize() == 12
M.step[1] == M.channels() * M.elemSize1() == M.elemSize() == 3

在这里插入图片描述

上面是一篇博客里边提到的,说的不是太清楚,下面我再细讲一下关于step的概念,step其实是有效宽度,其与图像数据缓存的时候的数据对齐有关。

在彩色图像中,图像数据缓冲区的前 3 字节表示左上角像素的三个通道的值,接下来的 3字节表示第 1 行的第 2 个像素,以此类推(注意 OpenCV 默认的通道次序为 BGR)。一个宽 W高 H 的图像所需的内存块大小为 W×H×3 uchars。不过出于性能上的考虑,我们会用几个额外的像素来填补行的长度。这是因为,如果行数是某个数字(例如 8)的整数倍,图像处理的性能可能会提高,因此最好根据内存配置情况将数据对齐。当然,这些额外的像素既不会显示也不被保存,它们的额外数据会被忽略OpenCV 把经过填充的行的长度指定为有效宽度。如果图像没有用额外的像素填充,那么有效宽度就等于实际的图像宽度。我们已经学过,用 cols和 rows 属性可得到图像的宽度和高度。与之类似,用 step 数据属性可得到单位是字节的有效宽度。即使图像的类型不是 uchar,step 仍然能提供行的字节数。 用 step 属性可得到一行的总字节数(包括填充像素)。通常可以用下面的方法得到第 j 行、 第 i 列的像素的地址:
// (j,i)像素的地址,即&image.at(j,i)
data= image.data+j*image.step+i*image.elemSize();

对于3维时(通道数不算另一维):

在这里插入图片描述
上面是一个 3 X 4 X 6 的矩阵,假设其数据类型为 CV_16SC4,也就是 short 类型

M.dims == 3 ; M.channels() == 4 ;
M.elemSize1() == sizeof(short) == 2 ;
M.rows == M.cols == –1;
M.elemSize() == M.elemSize1() * M.channels() == M.step[M.dims-1] == M.step[2] == 2 * 4 == 8;
M.step[0] == 4 * 6 * M.elemSize() == 192;
M.step[1] == 6 * M.elemSize() == 48;
M.step[2] == M.elemSize() == 8;
M.step1(0) == M.step[0] / M.elemSize() == 192 / 2 == 96 (第一维度(即面的元素个数) * 通道数);
M.step1(1) == M.step[1] / M.elemSize() == 48 / 2 == 24(第二维度(即行的元素个数/列宽) * 通道数);
M.step1(2) == M.step[2] / M.elemSize() == M.channels() == 4(第三维度(即元素) * 通道数);

代码演示

void myLog(Mat src)
{int dim = src.dims;for (int i = 0; i < dim; i++){cout << src.type() <<" step[" <<i << "]:"<< src.step[i] << "\t";cout << src.type() << " step1[" << i << "]:" << src.step1(i) << endl;}cout << src.type() << " elemSize:" << src.elemSize() << "\t";cout << src.type() << " elemSize1:" << src.elemSize1() << endl;
}int main(int argc, char** argv)
{Mat test = Mat(3, 4, CV_8UC1);myLog(test);Mat test1 = Mat(3, 4, CV_8UC3);myLog(test1);Mat test2 = Mat(3, 4, CV_16SC4);myLog(test2);int sz[3] = { 3, 4, 6};//sz指定数组尺寸大小3*4*6uchar* p; //用于访问像素Mat test3(3, sz, CV_16SC4);//指定n维,当前为3维;for (int i = 0; i < 3; i++) //行数for (int j = 0; j < 4; j++)//列数for (int k = 0; k < 6; k++)//高{p = test3.data + test3.step[0] * i + test3.step[1] * j + test3.step[2] * k; //访问m_nut(i,j,k)(*p) = i + j + k; // 为当前访问的像素赋值}myLog(test3);return 0;
}

结果:
在这里插入图片描述

参考:https://blog.csdn.net/LIYUAN123ZHOUHUI/article/details/52922951

这篇关于Mat中的step[i],step1(i),elemsize,elemsize1的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/196760

相关文章

Step by Step 实现基于 Cloudera 5.8.2 的企业级安全大数据平台 - Kerberos的整合

大数据技术与架构 点击右侧关注,大数据开发领域最强公众号! 暴走大数据 点击右侧关注,暴走大数据! Kerberos简介 之前非常担心的一件事就是如果有人拿到了hdfs超级管理员帐号,直接把数据rm -rf怎么办?有了Kerberos,就可以轻松防止这样的事情发生。Kerberos 协议实现了比“质询-响应”模式协议更高的安全性:第一,在身份验证过程中,所有的数据都使用不同的密码进行加密

MAT:一款针对MSSQL服务器的安全检测与审计工具

关于MAT MAT是一款针对MSSQL服务器的安全检测与审计工具,该工具使用C#开发,可以帮助广大研究人员快速识别和发现MSSQL 服务器中的安全问题,并实现安全检测与审计目的。 功能介绍 1、执行自动检查并识别安全问题; 2、允许通过 Windows 集成身份验证以及 SQL 身份验证登录; 3、如果权限存在则快速激活 XP_cmdshell(本地以及链接服务器上); 4、通过

[有彩蛋]大模型独角兽阶跃星辰文生图模型Step-1X上线,效果具说很炸裂?快来看一手实测!

先简单介绍一下阶跃星辰吧 公司的创始人兼CEO是姜大昕博士,他在微软担任过全球副总裁,同时也是微软亚洲互联网工程研究院的副院长和首席科学家。 2024年3月,阶跃星辰发布了Step-2万亿参数MoE语言大模型预览版,这是国内初创公司首次发布的万亿参数模型。 而Step-1X,是阶跃星辰在2024年世界人工智能大会上亮相的文生图模型。Step-1X在深度语义对齐和细节生成方面进行了重点打磨

阶跃星辰推出Step-1X:让你的想象力插上翅膀

阶跃星辰 在人工智能快速发展的今天,AI绘画技术正以惊人的速度不断突破创新。就在不久前,阶跃星辰在2024世界人工智能大会上发布的Step-1X图像生成大模型。让我们一起走进Step-1X的世界,看看它如何为我们的想象力插上翅膀。 Step-1X Step-1X Step-1X 模型拥有强大的图像生成能力,支持文本描述作为输入方式。具备原生的中文支持,能够更

JavaScript - First step - Arrays

创建数组 任何类型的对象,都可以放入数组中。 var shopping = ['bread', 'milk', 'cheese', 'hummus', 'noodles'];shopping;// (5) ["bread", "milk", "cheese", "hummus", "noodles"]var sequence = [1, 1, 2, 3, 5, 8, 13];var ra

JavaScript - First step - Strings

var string = 'The revolution will not be televised.';var string = "The revolution will not be televised."; 转义字符 var bigmouth = 'I\'ve got no right to take my place...';bigmouth; 字符串连接 var one =

JavaScript - First step - Numbers and operators

Types of numbers Integers 整数Floating point numbers 单精度浮点数Doubles 双精度浮点数Binary 二进制Octal 八进制Hexadecimal 十六进制 Arithmetic operators 算术运算符 + 加法- 减法* 乘法/ 除法% 求余** 指数 (次方 5 ** 5 = 5 * 5 * 5 * 5 * 5) Oper

JavaScript - First step - Variables

Variable 变量是存放值的容器。使用 var 或者 let 关键字创建变量。 创建变量: let myName;let myAge; 此时变量容器是空的,没有值放在里面,若取得变量的值,返回值会是:undefine 初始化变量: myName = 'Chris';myAge = 37;let myDog = 'Rover'; var 和 let 的区别 为什么会有两个声明

JavaScript - First step

JavaScript 在页面做什么? 当浏览器显示文档是,它必须将文档内容和样式信息联合起来。此时分两个步骤处理文档: 浏览器将 HTML & CSS 转换为 DOM(Document Object Model),此时处于内存中的 DOM 代表这个文档。它使用文档的样式来结合文档的内容。浏览器显示 DOM 中的内容。 当 HTML & CSS 由网页集合装配完成之后,才由浏览器的 Jav

matlab一:数字图象处理之读取显示——Matlab读取三维mat数据并灰度显示

目的: 手里面有一个(1040,1392,31)的数据,mat格式,我希望看到深度1的矩阵,也就是(1-1040,1-1391,1)符合这样下标的数据,并且显示出来。也就是鼠标处的ref。如果像我这样一个mat里面含有两个矩阵,那么双击load,会在工作区load两个矩阵。   代码:  A=ref(:,:,1);//冒号就是表示这一个维度我都要,这样下来,我这个矩阵A是个二维的,大小