当前位置: 首页 > article >正文

【C++的OpenCV】第十四课-OpenCV基础强化(三):Mat元素的访问之data和step属性

🎉🎉🎉 欢迎来到小白 p i a o 的学习空间! \color{red}{欢迎来到小白piao的学习空间!} 欢迎来到小白piao的学习空间!🎉🎉🎉
💖 C++\Python所有的入门技术皆在 我的主页 \color{#0cc123}{我的主页} 我的主页:我的主页


💖 我的资源: \color{purple}{我的资源:} 我的资源:我的资源

  1. IT技术各档次模板
  2. 各类项目(企业项目、毕设)
  3. 数据库安装包(Mysql8.0)
  4. 技能资料(电子书、软考等)


前言 \color{purple}{前言} 前言

        昨天由于有点写不动了,所以还剩了些内容放在今天完成,今天的内容完成常用Mat操作的元素访问环节的介绍,如果还没有看过前边内容的小伙伴,赶紧从前文开始学起来哦!

💖前文链接:【C++的OpenCV】第十四课-OpenCV基础强化(二):访问单通道Mat中的值


💖 一、利用成员变量 s t e p 和 d a t a 访问 M a t 中的元素 \color{blue}{一、利用成员变量step和data访问Mat中的元素} 一、利用成员变量stepdata访问Mat中的元素

        通过之前的学习内容我们知道,Mat中的元素在空间中存储的形式无非以下两种:

  • 形式一:行元素连续,行与行之间有固定等大的间隔
    在这里插入图片描述

  • 形式二:所有元素连续存储
    在这里插入图片描述

        如果不知道为什么的小伙伴,请赶快点击上边的前文链接学习起来!【C++的OpenCV】第十四课-OpenCV基础强化(二):访问单通道Mat中的值

1.1 s t e p 和 d a t a 的概念 \color{green}{1.1 step和data的概念} 1.1stepdata的概念

1.1.1 step

在这里插入图片描述        不难看出,首先step是一个MatStep类型的值,那MatStep又是什么呢?

在这里插入图片描述        在OpenCV中,MatStep是一个结构体,用于描述一个多维矩阵(Mat)的步幅(stride)。步幅是指在内存中从一个元素到下一个元素所需的字节数

值得注意的是:

  1. step[0] 代表矩阵每一行所占的字节数,如果有间隔的话,这个间隔的字节数也算作在内!
  2. 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中元素的方法:

  1. 成员函数at() 前文链接
  2. 成员函数ptr() 前文链接
  3. isContinuous()和ptr()组合的方式 前文链接
  4. step和data组合方式

        这是四种最常用的方法,希望大家可以熟练掌握,即使没有新的思路,那这几个基本可以解决开发中实际遇到的访问元素的情况(千万不要觉得难的方法就不用了,有些复杂环境下可能更加高效,总而言之,掌握多一点,对你没坏处)!


💖 二、总结 \color{red}{二、总结} 二、总结

        这部分内容落下了(实际是写不动了),给大家补全,可以理解为是上一章节的补充章节!可以学习起来了。新章节的内容,我们另起一页重头说起!


💖💖💖 持续更新,期待关注! \color{blue}{持续更新,期待关注!} 持续更新,期待关注!💖💖💖


http://www.kler.cn/a/108640.html

相关文章:

  • 〔 MySQL 〕数据类型
  • Linux基础1
  • Spring Boot 中的全局异常处理器
  • 密码学的基本原理
  • AtomicInteger 和 AtomicIntegerFieldUpdater的区别
  • 【学习】【HTML】HTML、XML、XHTML
  • 正点原子嵌入式linux驱动开发——外置RTC芯片PCF8563
  • TELUS Ventures(泰勒斯)
  • 项目管理概论:什么是项目生命周期、项目阶段都包含哪些、项目管理过程都有什么以及三者的关系
  • Vue实现首页导航和左侧菜单,介绍mock.js并实现登录注册间的跳转,实现左侧栏折叠效果,优化Main.vue组件,使用mock.js生成随机响应数据
  • 队列(8.6)
  • 多媒体应用设计师 第17章 多媒体应用场景的技术应用和实现示例
  • 适用于物联网的UI设计工具都有哪些?
  • 云原生之深入解析如何合并多个kubeconfig文件
  • python之计算平面点集的的面积
  • FRP内网穿透(待续)
  • 如何防范AI等技术带来的诈骗风险?从技术、法律、教育等多方面入手
  • ChatGPT如何应对用户提出的道德伦理困境?
  • 聊聊装饰模式
  • 『51单片机』 DS1302时钟
  • 第八周实验记录
  • 计算机网络【CN】介质访问控制
  • Spring AOP源码解读
  • 使用Go模块进行依赖管理
  • PCI9054入门1:硬件引脚定义、时序、FPGA端驱动源码
  • 企业如何安全跨国传输30T文件数据