cv::Mat遍历赋值的几种方式

2023-11-04

1、前言

背景:获取传感器数据后需要保存成图片,有时需要对里面的元素进行操作,因为是自己开发,不能直接得到图片,所以研究了一下Mat赋值的几种方式。建议首先要理解预定义结构的类型CV_<bit_depth>(S|U|F)C<number_of_channels>,再进行下面的阅读,这部分不在这里细说。


2、Mat简介

Mat这种类,可以理解为动态数组,不需要人为释放内存。它由两个数据部分组成:矩阵头(包含矩阵尺寸、存储方式、存储地址等信息)和一个指向存储所有像素值的矩阵(根据所存储方法的不同矩阵可以是不同的维数)的指针。在opencv中,矩阵赋值(拷贝),比如cv::Mat a = b 或者 cv::Mat a(b),是将a的指针指向b的地址,通过浅拷贝的方式,让矩阵指针指向同一地址而实现的。如果想深拷贝的话,可以用函数clone()或者copyTo()来实现。


3、遍历Mat赋值方式

方式一

采用指针的方式,效率最高,一开始理解有点困难,习惯就好了,具体见代码中的解释。

#include <stdio.h>  
#include <iostream> 
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main(){
	int height = 5;
	int width = 5;
	//初始化赋值
	cv::Mat image  = cv::Mat::zeros(height, width, CV_16UC2);
	//CV_[The number of bits per item][Signed or Unsigned][Type Prefix]C[The channel number]
    	for (int row = 0; row < height; row++)
		{	
			//指向矩阵当前行的指针
			Vec<ushort, 2> *data_Ptr = image.ptr<Vec<ushort, 2>> (row);
			//可以将data_Ptr看出一个数组,data_Ptr[col]代表了第几个元素
			//每个元素的数据类型是<ushort,2>,包含了2个无符号整型的元素
			for (int col = 0; col < width; col++)
			{
				data_Ptr[col][0] = 5;
				data_Ptr[col][1] = 2;
            }
		}
	cout << image << endl;

	return 0;
}

方式二

使用成员函数.at的方式,直接定位到第几行第几列,然后根据定义的数据类型,给元素赋值。这种方法最容易理解,但是,他的效率是最低的。

	for (int row = 0; row < height; row++)
	{
		for (int col = 0; col < width; col++)
		{
			//直接给第几行第几列赋值
			image.at<Vec<ushort, 2>>(row,col)[0] = 5;
			image.at<Vec<ushort, 2>>(row,col)[1] = 2;
        }
	}

方式三

使用迭代器来进行遍历赋值。可以用cv::MatIterator_< cv::Vec3b>it或者cv::Mat_< cv::Vec3b>::iterator it。中间的类型取决于Mat定义的类型。这种方式,可以理解为将整个矩阵拉成一个向量,每个向量里面的元素就是申明Mat变量时定义的元素的类型。比如定义的是2通道的ushort型,那么向量里面的存储的每个元素就是2通道的ushort型,这理解的解释是我个人的类比,不是很严谨。这种方式迭代赋值效率一般,在这三种方法中排第二。

	//迭代起始位置
	cv::Mat_<Vec<ushort, 2>>::iterator it  = image2.begin<Vec<ushort, 2>>();
	//迭代终止位置
	cv::Mat_<Vec<ushort, 2>>::iterator end = image2.end<Vec<ushort, 2>>();
	for (; it != end; ++it)
	{
		(*it)[0] = 5;
		(*it)[1] = 2;
	}

4、测试

将三种方法测试了一下,代码如下,比较简单。

#include <stdio.h>  
#include <chrono>  
#include <iostream> 
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main(){

	int height = 5;
	int width = 5;

	cv::Mat image  = cv::Mat::zeros(height, width, CV_16UC2);
	cv::Mat image1  = cv::Mat::zeros(height, width, CV_16UC2);
	cv::Mat image2  = cv::Mat::zeros(height, width, CV_16UC2);
	chrono::steady_clock::time_point t1 = chrono::steady_clock::now();
    for (int row = 0; row < height; row++)
	{	
		//指向矩阵当前行的指针
		Vec<ushort, 2> *data_Ptr = image.ptr<Vec<ushort, 2>> (row);
		//可以将data_Ptr看出一个数组,data_Ptr[col]代表了第几个元素
		//每个元素的数据类型是<ushort,2>,包含了2个无符号整型的元素
		for (int col = 0; col < width; col++)
		{
			data_Ptr[col][0] = 5;
			data_Ptr[col][1] = 2;
        }
	}
	chrono::steady_clock::time_point t2 = chrono::steady_clock::now();
	chrono::duration<double> time_used = chrono::duration_cast<chrono::duration<double>>(t2-t1);
	cout << "The first method cost time is "<<time_used.count()  << " seconds."<< endl;

	for (int row = 0; row < height; row++)
	{
		for (int col = 0; col < width; col++)
		{
			image1.at<Vec<ushort, 2>>(row,col)[0] = 5;
			image1.at<Vec<ushort, 2>>(row,col)[1] = 2;
        }
	}
	chrono::steady_clock::time_point t3 = chrono::steady_clock::now();
	time_used = chrono::duration_cast<chrono::duration<double>>(t3-t2);
	cout << "The second method cost time is "<<time_used.count()  << " seconds."<< endl;

	//迭代起始位置
	cv::Mat_<Vec<ushort, 2>>::iterator it  = image2.begin<Vec<ushort, 2>>();
	//迭代终止位置
	cv::Mat_<Vec<ushort, 2>>::iterator end = image2.end<Vec<ushort, 2>>();
	for (; it != end; ++it)
	{
		(*it)[0] = 5;
		(*it)[1] = 2;
	}
	chrono::steady_clock::time_point t4 = chrono::steady_clock::now();
	time_used = chrono::duration_cast<chrono::duration<double>>(t4-t3);
	cout << "The third method cost time is "<<time_used.count()  << " seconds."<< endl;

	cout << image  << endl;
	cout << image1 << endl;
	cout << image2 << endl;

	return 0;
}

在这里插入图片描述
例子中的这个矩阵比较小,一般图片矩阵都很大的,这时候运算速度就很关键了。建议以后采用第一种方式。

5、参考文献

【1】Mat类详解 之 元素的获取与赋值
【2】Mat-基本图像容器

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

cv::Mat遍历赋值的几种方式 的相关文章

  • 使用 openCV 和 python 检测物体

    我正在尝试使用 OpenCV 和 Python 检测下图中的白点 我尝试使用函数 cv2 HoughCircles 但没有成功 我需要使用不同的方法吗 这是我的代码 import cv2 cv import numpy as np impo
  • Opencv未找到所有轮廓

    我试图找到该图像的轮廓 但是该方法查找轮廓只返回1轮廓 轮廓突出显示image 2 我正在努力寻找all外部轮廓就像这些圆圈 里面有数字 我究竟做错了什么 我可以做什么来实现它 image 1 image 2 以下是我的代码的相关部分 th
  • 在 RGB 图像上绘制多类语义分割透明叠加

    我有语义分割掩码的结果 值在 0 1 之间 需要大津阈值来确定什么是积极的 我想直接在 RGB 图像上绘制 在 RGB 图像上每个预测类具有不同的随机颜色 我使用以下内容绘制了具有单一颜色的单个蒙版 是否有一个包或简单的策略可以为多类别做到
  • 如何在opencv python中为图像添加边框

    如果我有如下图所示的图像 如何在图像周围添加边框 以便最终图像的整体高度和宽度增加 但原始图像的高度和宽度保持在中间 下面的代码添加了一个大小恒定的边框10像素到原始图像的所有四个边 对于颜色 我假设您想要使用背景的平均灰度值 这是我根据图
  • 提高 pytesseract 从图像中正确识别文本的能力

    我正在尝试使用读取验证码pytesseract模块 大多数时候它都能提供准确的文本 但并非总是如此 这是读取图像 操作图像以及从图像中提取文本的代码 import cv2 import numpy as np import pytesser
  • 如何删除树莓派的相机预览

    我在我的 raspberryPi 上安装了 SimpleCv 并安装了用于使用相机板的驱动程序 uv4l 驱动程序 现在我想使用它 当我在 simpleCV shell Camera 0 getImage save foo jpg 上键入时
  • OpenCV的拼接模块可以拼接平行运动相机拍摄的图像吗?

    我想知道是否缝合 http docs opencv org modules stitching doc stitching html http docs opencv org modules stitching doc stitching
  • 我可以使用 openCV 比较两张不同图像上的两张脸吗?

    我对 openCV 很陌生 我看到它可以计算出脸部并返回一个矩形来指示脸部 我想知道 openCV 是否可以访问两张包含一张脸的图像 并且我希望 openCV 返回这两个人是否相同的可能性 Thanks OpenCV 不提供完整的人脸识别引
  • 当我将鼠标移到 Mat 关键字上时,Visual Studio 2017 冻结(OpenCv 3.4.1)

    我想在 Visual Studio 2017 中开发 openCv 项目 我下载了 opencv 预构建库并进行了必要的设置 那是 1 我添加了系统路径 build x64 vc14 bin 2 在 Visual Studio 中的项目属性
  • 为什么我无法在 Mac 12.0.1 (Monterey) 上使用 pip 安装 OpenCV? [复制]

    这个问题在这里已经有答案了 当我尝试使用 python pip 安装 OpenCV 时 它显示了以下内容 Remainder of file ignored Requirement already satisfied pip in Libr
  • 从图像坐标获取对象的世界坐标

    I have been following this http docs opencv org modules calib3d doc camera calibration and 3d reconstruction html docume
  • OpenCV 2.4.3 中的阴影去除

    我正在使用 OpenCV 2 4 3 最新版本 使用内置的视频流检测前景GMG http docs opencv org modules gpu doc video html highlight gmg gpu 3a 3aGMG GPU算法
  • 如何使用 Python 裁剪图像中的矩形

    谁能给我关于如何裁剪两个矩形框并保存它的建议 我已经尝试过这段代码 但效果不佳 import cv2 import numpy as np Run the code with the image name keep pressing spa
  • 如何确定与视频中物体的距离?

    我有一个从行驶中的车辆前面录制的视频文件 我将使用 OpenCV 进行对象检测和识别 但我停留在一方面 如何确定距已识别物体的距离 我可以知道我当前的速度和现实世界的 GPS 位置 但仅此而已 我无法对我正在跟踪的对象做出任何假设 我计划用
  • 从包含带边框的表格的图像中提取表格结构

    我正在尝试提取下表中的单元格位置 应用自适应阈值处理后 我能够获得细胞位置周围的轮廓 并且 HoughLines 获得垂直和水平结构元素 这是我的代码 img cv2 imread os path join img path file im
  • 2d 图像点和 3d 网格之间的交点

    Given 网格 源相机 我有内在和外在参数 图像坐标 2d Output 3D 点 是从相机中心发出的光线穿过图像平面上的 2d 点与网格的交点 我试图找到网格上的 3d 点 This is the process From Multip
  • 如何使用 opencv python 计算乐高积木上的孔数?

    我正在开发我的 python 项目 我需要计算每个乐高积木组件中有多少个孔 我将从输入 json 文件中获取有关需要计算哪个程序集的信息 如下所示 img 001 red 0 blue 2 white 1 grey 1 yellow 1 r
  • 在 Visual Studio 2012 中安装 OpenCV

    我正在尝试安装 OpenCV 来与 Visual Studio 一起使用 我使用的是2012Pro版本 但我认为它应该与vs10相同 我正在关注这个教程 http docs opencv org doc tutorials introduc
  • OpenCV VideoWriter 未写入 Output.avi

    我正在尝试编写一段简单的代码来获取视频 裁剪视频并写入输出文件 系统设置 OS Windows 10 Conda Environment Python Version 3 7 OpenCV Version 3 4 2 ffmpeg Vers
  • “没有名为‘cv2’的模块”,但已安装

    我已经安装了包含 opencv 贡献的 whl 文件 因为我想使用 SIFT 算法 我在 conda 环境中使用 pip 安装了它 所以当我在 conda list 中提示时 它会向我显示 opencv python 3 4 5 contr

随机推荐

  • 深度学习中epoch、batch、step、iteration等神经网络参数是什么意思?

    epoch 表示将训练数据集中的所有样本都过一遍 且仅过一遍 的训练过程 在一个epoch中 训练算法会按照设定的顺序将所有样本输入模型进行前向传播 计算损失 反向传播和参数更新 一个epoch通常包含多个step batch 一般翻译为
  • goland面试题第八天

    第八天 1 关于init函数 下面说法正确的是 A 一个包中 可以包含多个 init 函数 B 程序编译时 先执行依赖包的 init 函数 再执行 main 包内的 init 函数 C main 包中 不能有 init 函数 D init
  • conda和pip都可以安装Python包,那么它们有哪些区别呢?

    文章目录 conda和pip都可以安装Python包 那么二者有什么区别呢 如果想单独了解conda可以查看这篇文章 conda详细的使用教程 不仅能够管理Python包 还能管理虚拟环境 了解pip可以查看这篇文章 Python包管理工具
  • lambda no instance(s) of type variable(s) T exist so that void conforms to R

    代码如下出现标题报错 List
  • 初学TypeScript

    TypeScript介绍 开发环境搭建 常用数据类型 1 什么是TypeScript TypeScript 是JavaScript的一个超集 支持ECMAScript 6标准 Typescript由微软开发的自由和开源的编程语言 TypeS
  • 合作搜索优化算法(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 Matlab代码实现 4 参考文献 1 概述 合作搜索算法 CSA 在问题空间中随机生成
  • flutter-使用第三方库,编译和运行版本不一致问题 2

    问题 接着上一个问题 如果是继续有问题 你讲看到这篇文章 新的问题又出现啦 如 Command xx xx develop android flutter app android gradlew app properties Finishe
  • Anaconda切换python版本

    比如 我的 已经安装好了anaconda4 即已经有了python3 5 现在想切换3 7 安装3 7 命令行运行 前提是anaconda环境变量已经配置好 创建一个名为python37的环境 指定Python版本是3 7 conda会为我
  • Dictionary Learning(字典学习、稀疏表示以及其他)

    第一部分 字典学习以及稀疏表示的概要 字典学习 Dictionary Learning 和稀疏表示 Sparse Representation 在学术界的正式称谓应该是 稀疏字典学习 Sparse Dictionary Learning 该
  • js-JavaScript 对象

    1 对象定义 JavaScript 对象是拥有属性和方法的数据 2 格式 键值对 var person firstName John lastName Smith age 50 eyeColor blue move function ale
  • 后端Long型数据传给前端精度丢失问题 分布式id 解决方案

    Long型数据id传给前端精度丢失问题 数据库数据类型bigint 今天将文章类ArticleVo的数据传给前端时 发现前端接收的数据id不一样 如前端获得的id 1405916999732707300 但数据库里是id 140591699
  • springboot国际化message配置

    常常在需求中遇到国际化的要求 而国际化最常见的就是中英文切换 除了前端 后端也需要进行国际化处理 这里来记录一下我实现国际化的步骤代码 1 在resource下的i18n下建立messages properties messages en
  • CycleGAN和Conditional GAN(cGAN)

    当谈到CycleGAN和Conditional GAN cGAN 时 我们涉及到生成对抗网络 GAN 的不同变体 让我逐步介绍它们的原理和应用 CycleGAN CycleGAN是一种无监督的图像转换模型 它可以在两个不同的图像域之间进行转
  • Ubuntu Source Insight 4.0安装后首次打开报错

    系统为中文会出现 Unable to open or create 中文路径 sidb 参照网上修改regedit方法 发现没用 直接修改 wine drive c users server 我的文档 为 wine drive c user
  • C++ 中 map 容器的内存释放机制及内存碎片管理

    C 中 map 容器的内存释放机制及内存碎片管理 C 中的容器很好用 比如 vector map 等 可以动态扩容 自己管理内存 不用用户关心 但是在某些极端情况下 如果内存比较紧张的情况下 可能用户对于这些容器自己的管理规则 主要是释放规
  • Linux read命令

    读取n个字符存入变量 不用按回车 输入到第n个自动结束 student myhost read n 3 a 123 student myhost echo a 123 无回显方式读取密码 student myhost read s pass
  • windows spacemacs实现org-mode转latex,然后生成pdf

    spacemacs默认英文字体做如下修改 安装了完整版ctex套装 spacemacs增加layer gt latex 增加windows的path路径 解决org mode里中英文等宽问题 latex编译命令 pdf预览等 实现了org转
  • 什么是文件目录,文件目录项的主要内容是什么?

    文件目录是记录系统中所有文件的名字及其存放地址的目录表 表中还包括关于文件的说明信息和控制信息 主要内容如下 1 文件名 文件名分为文件的符号名和内部标识符 id号 2 文件的逻辑结构 说明该文件是否是定长 记录长度及记录个数等 3 文件的
  • USB如何布局走线

    1 先上图 USB分为2 0和3 0 2 USB布局走线需要注意的地方 静电防护 阻抗匹配 同组等长
  • cv::Mat遍历赋值的几种方式

    cv Mat赋值的几种方式 1 前言 2 Mat简介 3 遍历Mat赋值方式 方式一 方式二 方式三 4 测试 5 参考文献 1 前言 背景 获取传感器数据后需要保存成图片 有时需要对里面的元素进行操作 因为是自己开发 不能直接得到图片 所