【C++的OpenCV】第十四课-OpenCV基础强化(三):Mat元素的访问之data和step属性
🎉🎉🎉
欢迎来到小白
p
i
a
o
的学习空间!
\color{red}{欢迎来到小白piao的学习空间!}
欢迎来到小白piao的学习空间!🎉🎉🎉
💖 C++\Python所有的入门技术皆在
我的主页
\color{#0cc123}{我的主页}
我的主页:我的主页
💖 我的资源: \color{purple}{我的资源:} 我的资源:我的资源
- IT技术各档次模板
- 各类项目(企业项目、毕设)
- 数据库安装包(Mysql8.0)
- 技能资料(电子书、软考等)
目录
- 前言 \color{purple}{前言} 前言
- 💖 一、利用成员变量 s t e p 和 d a t a 访问 M a t 中的元素 \color{blue}{一、利用成员变量step和data访问Mat中的元素} 一、利用成员变量step和data访问Mat中的元素
- 1.1 s t e p 和 d a t a 的概念 \color{green}{1.1 step和data的概念} 1.1step和data的概念
- 1.1.1 step
- 1.1.2 data
- 1.2 具体使用方法 \color{green}{1.2 具体使用方法} 1.2具体使用方法
- 1.2.1 图解教程
- 1.2.2 代码实例
- 1.3 小结 \color{green}{1.3 小结} 1.3小结
- 💖 二、总结 \color{red}{二、总结} 二、总结
前言 \color{purple}{前言} 前言
昨天由于有点写不动了,所以还剩了些内容放在今天完成,今天的内容完成常用Mat操作的元素访问环节的介绍,如果还没有看过前边内容的小伙伴,赶紧从前文开始学起来哦!
💖前文链接:【C++的OpenCV】第十四课-OpenCV基础强化(二):访问单通道Mat中的值
💖 一、利用成员变量 s t e p 和 d a t a 访问 M a t 中的元素 \color{blue}{一、利用成员变量step和data访问Mat中的元素} 一、利用成员变量step和data访问Mat中的元素
通过之前的学习内容我们知道,Mat中的元素在空间中存储的形式无非以下两种:
-
形式一:行元素连续,行与行之间有固定等大的间隔
-
形式二:所有元素连续存储
如果不知道为什么的小伙伴,请赶快点击上边的前文链接学习起来!【C++的OpenCV】第十四课-OpenCV基础强化(二):访问单通道Mat中的值
1.1 s t e p 和 d a t a 的概念 \color{green}{1.1 step和data的概念} 1.1step和data的概念
1.1.1 step
不难看出,首先step是一个MatStep类型的值,那MatStep又是什么呢?
在OpenCV中,MatStep是一个结构体,用于描述一个多维矩阵(Mat)的步幅(stride)。步幅是指在内存中从一个元素到下一个元素所需的字节数。
值得注意的是:
- step[0] 代表矩阵每一行所占的字节数,如果有间隔的话,这个间隔的字节数也算作在内!
- step[1] 代表每一个数值所占的字节数。
1.1.2 data
首先呢,它就是一个uchar类型的指针而已!其次呢,其实就是指向矩阵第一个值的指针。
1.2 具体使用方法 \color{green}{1.2 具体使用方法} 1.2具体使用方法
// 基于上述的描述:
// 访问一个元素可以如下:
*((int*)(m.data+m.step[0]*r+m.step[1]*c))
// 其中:
1.r代表行,c代表列,都是从0开始。
2.m就是一个Mat对象,后续有完整代码展示,这里特此申明!
1.2.1 图解教程
重点来了,花点事件通过图解的形式理解一下上述的代码为什么可以找到每一个想要找到的元素:
假如说,我们需要访问下边矩阵中的元素4
首先,解析代码中的m.data: 指向首个元素的指针,即目前其位置如下:
接下来,我们来看 m.data+m.step[0]*r :
4 所在的位置的r值(r=1),如果是访问第一行元素则很简单了,r为0就没有 m.step[0]*r 这一项了。
m.step[0]*r此时就是第一行所有的字节数,包含间距,即如下图,蓝色方框框住的即为m.step[0]所占的字节空间:
所以上述的操作其实相当于是把m.data往后移动了“ m.step[0] * 1 ” 的字节数,此时,m.data就跨过了第一行的间隔,来到了第二行首个元素的位置。
(这里纠正一下,在上边一张描述m.data的位置的图片中,我将其指向了那个数字1,这种描述不够准确,特此纠正!应该是指向空间的头!)
最后就是这个“ m.step[1]*c ”了,首先step[1]还记得吗?代表“一个数值所占的字节数”,这里4处于的位置中c的值为1,
所以这里相当于给m.data加了一个元素的字节数(m.step[1] * 1),所以m.data发生了移动:
经过上述一系列的操作,终于搞懂了“(m.data+m.step[0]*r+m.step[1]*c)”的含义,至于外边的那个(int*)就不解释了(类型强制转换而已 )。
而这个玩意呢?不就是把强转之后的指针去解除引用找到对应位置的元素吗?那不就是4吗?下边是代码展示:
1.2.2 代码实例
#include<iostream>
#include"opencv2/core/utility.hpp"
using namespace std;
using namespace cv;
int main()
{
Mat m = (Mat_<int>(3,2) << 1,2,3,4,5,6);
cout << m <<endl; // 注意:显示的是3行2列
/*
[1, 2;
3, 4;
5, 6]
*/
cout << *((int*)(m.data+m.step[0]*1+m.step[1]*1)) << endl;
return 0;
}
1.3 小结 \color{green}{1.3 小结} 1.3小结
简短总结下访问Mat中元素的方法:
- 成员函数at() 前文链接
- 成员函数ptr() 前文链接
- isContinuous()和ptr()组合的方式 前文链接
- step和data组合方式
这是四种最常用的方法,希望大家可以熟练掌握,即使没有新的思路,那这几个基本可以解决开发中实际遇到的访问元素的情况(千万不要觉得难的方法就不用了,有些复杂环境下可能更加高效,总而言之,掌握多一点,对你没坏处)!
💖 二、总结 \color{red}{二、总结} 二、总结
这部分内容落下了(实际是写不动了),给大家补全,可以理解为是上一章节的补充章节!可以学习起来了。新章节的内容,我们另起一页重头说起!
💖💖💖 持续更新,期待关注! \color{blue}{持续更新,期待关注!} 持续更新,期待关注!💖💖💖