opencv元素访问基础知识

【OpenCV】c++ 入门认识 Mat 类,单通道 Mat 的基本操作 在计算器内存中,数字图像是以矩阵的形式保存的,矩阵信息中包含了所有像素点的强度值,如何获取并储存这些像素值可根据实际场景应用来确定。在计算机处理中所有图像信息都将转化为数值信息矩阵。OpenCV作为计算机视觉处理库,其主要目的就是通过处理和操作这些矩阵信息来获得更加高级的信息。在处理图像前,我们需要先了解一下OpenCV中最基础的库类Mat以及其相关操作。 阅读详情

图像基础知识和opencv踩的坑

0是黑,255是白。灰度图和彩色图区别为:组成不同、通道不同、表示不同。 一、组成不同 1、灰度图:灰度图把白色与黑色之间按对数关系用灰度表示的图像

深度图16为都要进行归一化处理

opencv的坑

opencv访问mat元素的时候必须用相同的类型

for(int i=0;i<nr;i++)
    {
        for(int j=0;j<nc;j++)
        {
            if(image.at<uchar>(i,j)==0)
            {
                image.at<uchar>(i,j)=255;
            }
        }
    }

这是cv_8u1; 如果我用ushort访问那么会出现下面的错误;还有就是切记要注意矩阵范围是uchar还是ushort

Segmentation fault (core dumped)

掩膜

inpaintMask:掩码矩阵,为0的像素作修复处理,不为0的不作修复处理

掩膜只对0像素进行处理

用选定的图像、图形或物体,对待处理的图像(全部或局部)进行遮挡,来控制图像处理的区域或处理过程。用于覆盖的特定图像或物体称为掩模或模板

关于cv::mat at进行访问的问题

row == height == Point.y
col == width  == Point.x

lena

这是因为在计算机中,图像是以矩阵的形式保存的。一张宽度640像素、长度480像素的灰度图保存在一个480 * 640的矩阵中。

先行后列。而我们习惯的坐标表示是先X横坐标,再Y纵坐标。在OpenCV中需要对矩阵进行计算,先行再列。这种隐形的错误需要细心。

Rect的构造函数给定的X,Y坐标即为矩形的左上角坐标。
设置为(0,100),效果如下。

rect

1.坐标体系中的零点坐标为图片的左上角,X轴为图像矩形的上面那条水平线;Y轴为图像矩形左边的那条垂直线。该坐标体系在诸如结构体Mat,Rect,Point中都是适用的。(虽然网上有学着说OpenCV中有些数据结构的坐标原点是在图片的左下角,但是我暂时还没碰到过)。

2.在使用image.at(x1, x2)来访问图像中点的值的时候,x1并不是图片中对应点的x轴坐标,而是图片中对应点的y坐标。因此其访问的结果其实是访问image图像中的Point(x2, x1)点,即与image.at(Point(x2, x1))效果相同。

3.如果所画图像是多通道的,比如说image图像的通道数时n,则使用Mat::at(x, y)时,其x的范围依旧是0到image的height,而y的取值范围则是0到image的width乘以n,因为这个时候是有n个通道,所以每个像素需要占有n列。但是如果在同样的情况下,使用Mat::at(point)来访问的话,则这时候可以不用考虑通道的个数,因为你要赋值给获取Mat::at(point)的值时,都不是一个数字,而是一个对应的n维向量。

也就是说,用point(i,j)访问的就是正常的(i,j)这个点,而at访问的是(j,i)这个点

opencv 元素访问

opencv进行at访问的时候,记住数据占据空间的大小是不一样的, 比如,ushort是 16位的占据两个字节, double64位会占据8个字节

如果at 访问的ushort数据的时候,用double那么一次性读取的就是8个字节的数据,就会出现数据转换时候的错误,同样,原来是double的数据如果强制转换成ushort在放进存放这个double的地方,就相当于原来16位的来存8位,原来的16位中剩下的8位会因为没有被释放掉造成内存泄露。

opencv 各种访问速度

at ptr data

这三种访问速度都很接近

at: 31.06
ptr: 31.25
data: 31.3

测试代码

#include <time.h>

#include <iostream>
#include <opencv2/opencv.hpp>

#include "common_op.h"

int main() {
  clock_t start, stop;
  double duration;
  double k = 0;
  cv::Mat database = cv::imread("mean_depth.png", cv::IMREAD_ANYDEPTH);
  ushort tmp;

  start = clock();
  for (int j = 0; j < 100; j++) {
    while (k != 1000000) {
      k++;
      for (int i = 0; i < database.rows; i++) {
        for (int j = 0; j < database.cols; j++) {
          tmp = database.at<ushort>(i, j);
        }
      }
    }
  }
  stop = clock();
  duration = static_cast<double>(stop - start) / 100.0;
  std::cout << RED;
  std::cout << "at: " << duration << std::endl;

  k = 0;
  start = clock();
  for (int j = 0; j < 100; j++) {
    while (k != 1000000) {
      k++;
      for (int i = 0; i < database.rows; i++) {
        ushort *ptr_data = database.ptr<ushort>(i);
        for (int j = 0; j < database.cols; j++) {
          tmp = ptr_data[j];
        }
      }
    }
  }
  stop = clock();
  duration = static_cast<double>(stop - start) / 100;
  std::cout << RED;
  std::cout << "ptr: " << duration << std::endl;

  k = 0;
  start = clock();
  for (int j = 0; j < 100; j++) {
    while (k != 1000000) {
      k++;
      for (int i = 0; i < database.rows; i++) {
        ushort *ptr_data = database.ptr<ushort>(i);
        for (int j = 0; j < database.cols; j++) {
          tmp = *(database.data + database.step[0] * i + database.step[1] * j);
        }
      }
    }
  }
  stop = clock();
  duration = static_cast<double>(stop - start) / 100;
  std::cout << RED;
  std::cout << "data: " << duration << std::endl;
}

tip:

无论用什么方法访问其实都是根据空间的取法来的

举例子:

at :

at 根据后面的类型来进行取值 at<ushort> 这时候ushort是16位的,所以每次取数据就是16位的。如果这个时候取值空间的类型不是ushort而是别的比如double那么取出16位而double是64位这时候数值就会发生变化
ptr也一样,根据ptr的类型来进行取值,来取多少位
data一样

关于opencv与stl 的操作

stl中的push_back

对于内建类型(int float char等),容器的工作方式是纯粹的位拷贝,这里没有什么需要多说的。

对于自定义的对象,容器容纳了对象(比如通过insert或push_back等),但容器中存放的对象不是你给它们的那个对象,因为两个对象在内存中的位置不一样。此外,当你从容器中获取一个对象时,你所得到的对象不是容器里的那个对象。取而代之的是,当你向容器中添加一个对象(比如通过insert或push_back等),进入容器的是你指定的对象的拷贝。拷进去,拷出来。拷贝是STL的方式。
明白了容器的工作方式,那么进一步来讨论容器存放对象和指针在操作过程中的开销。内建类型的数据进行拷贝的方式是位拷贝,自定义类型的数据进行拷贝会调用类的拷贝构造函数,这个函数是每个类都有的,如果类中没有显式的声明那么编译器也会给提供一个默认的拷贝构造函数。如果一个类的数据非常多,或者包含其他复杂自定义类型,那么此时类的拷贝构造的开销是非常大的。

关于opencv的mat

Mat 是一个类,由两个数据部分组成:矩阵头(包含矩阵尺寸,存储方法,存储地址等信息)和一个指向存储所有像素值的矩阵(根据所选存储方法的不同矩阵可以是不同的维数)的指针。矩阵头的尺寸是常数值,但矩阵本身的尺寸会依图像的不同而不同,通常比矩阵头的尺寸大数个数量级。因此,当在程序中传递图像并创建拷贝时,大的开销是由矩阵造成的,而不是信息头。所以,除非有必要,否则我们不应该拷贝大的图像,因为这会降低程序速度。
为了搞定这个问题,OpenCV使用引用计数机制。其思路是让每个 Mat 对象有自己的信息头,但共享同一个矩阵。这通过让矩阵指针指向同一地址而实现。而拷贝构造函数则 只拷贝信息头和矩阵指针 ,而不拷贝矩阵。但某些时候你仍会想拷贝矩阵本身(不只是信息头和矩阵指针),==这时可以使用函数 clone() 或者 copyTo() 。==

所以,如果vector<mat> 这个时候如果 push_back(mat_a) 这时候调用mat的拷贝构造函数,此时,mat_a只会只拷贝信息头和矩阵指针 ,而不拷贝矩阵。且引用机制加一,这时候如果改变mat_a里面的内容,那么就会同时改变vector的存放的值,而且局部mat_a析构的时候只是引用计数减去一 但内容还在

为了避免这种情况:

改写: push_back(mat_a.clone()) 相当于放进去了一个匿名的对象,这时候就可以隔离vector和mat_a,这样就不会互相干扰了

LVDS信号调试必备:5分钟搞懂Xilinx IDELAYE3的TIME模式校准 本文深入解析了在Xilinx Ultrascale系列FPGA中调试LVDS信号时,如何正确使用IDELAYE3的TIME模式进行精密延迟校准。文章重点阐述了IDELAYCTRL、EN_VTC管脚与校准状态机的协同工作机制,揭秘了内置自校准(BISC)中Align_Delay的影响,并提供了从抽头值计算到实际眼图优化的完整实战方案,帮助工程师快速解决高速接口的时序问题。 阅读详情

相关推荐

避坑指南:处理A股通达信分时数据转日K线时,你可能会遇到的3个时间戳问题

本文针对量化交易中处理A股通达信分时数据转日K线时的常见时间戳问题,提供了专业解决方案。重点解析了午休时段处理、Pandas重采样参数设置及CSV读取时的日期解析陷阱,帮助开发者避免数据预处理错误,提升策略回测准确性。适用于Python量化交易开发者。

weixin_42549496的博客 289

OpenCV基础知识

API概念 cv命名空间 自动内存管理 输出数据的自动分配 饱和算法 固定像素类型,模板使用限制 InputArray 和 OutputArray 错误处理 多线程和可重入 OpenCV是一个开源的BSD许可库,其中包含数百种计算机视觉算法。该文档描述了所谓的OpenCV 2.x API,它基本上是C ++ API,与基于C的OpenCV 1.x API相反。后者在opencv...

SSS 1227

onnxruntime模型部署(一)-pythonAPI

简单模型的onnx模型的导出,以及onnxruntime推理引擎的模型部署

qq_45983373的博客 4059

OpenCV中Mat元素的访问及效率对比

OpenCV中Mat元素的访问及效率对比

m0_54215988的博客 514

【CVPR 2025】清华:注意力状态空间模块,Mamba与注意力的超强组合,即插即用!

MambaIRv2提出了一种创新的图像恢复模型,通过引入注意力状态空间模块(ASSM)解决了Mamba模型因果建模限制问题。该模型结合语义引导邻域机制和注意力状态空间方程,实现了非因果建模,有效缓解了长距离衰减问题。实验表明,MambaIRv2在图像超分辨率、JPEG压缩伪影减少和图像去噪等任务中表现优异,参数更少但性能超越现有方法。

qq_43303160的博客 3040

创客学院嵌入式驱动开发——学习资料汇总

1.创客学院知识巩固-01C语言回顾_C/C++_Set_Mode的博客-优快云博客https://blog.youkuaiyun.com/Set_Mode/article/details/94431050 2.创客学院知识巩固-02数据结构_Set_Mode的博客-优快云博客https://blog.youkuaiyun.com/Set_Mode/article/details/94431087 3.创客学院知...

snaking616 5116

【c++|opencv】一、基础操作---3.访问图像元素

访问图像元素。

胡侃有料的博客 850

重塑计算的五层蛋糕:解读黄仁勋CES2026演讲背后的AI新秩序与物理世界

2026年CES演讲揭示AI新纪元:从语言模型到物理智能 NVIDIA CEO黄仁勋在2026年CES演讲中描绘了计算产业的根本性变革。核心突破包括: 计算范式转移:从指令执行转向意图理解,智能体系统崛起 物理AI突破:发布Cosmos世界模型,通过合成数据训练AI理解物理定律 全新VeraRubin计算平台:6芯片协同设计,解决摩尔定律放缓与AI需求增长的矛盾 自动驾驶革命:推出具备推理能力的Alpamayo模型,实现L4级自动驾驶 演讲标志着AI正从数字世界迈向物理世界,NVIDIA通过全栈布局,正在重

老孙 | Ethan Sun 的博客:AI 智能体与 AI 原生软件的工程实践 1274

OpenCV Tutorial: 縮寫(uchar、ushort、Vec)

縮寫(uchar、ushort、Vec)這邊介紹OpenCV常見的三種縮寫,分別是uchar、ushort、Vec。typedef unsigned char uchar typedef unsigned short ushort OpenCV使用Vec簡化vector,數字表示這個vector有幾個元素,英文字母表示元素的資料結構,通常用於影像像素。以最常見的8位元無負號3通道圖來說,我們可用Ve

GPU全栈博主 2282

群晖NAS实战:从零部署Container Manager与Docker代理配置全攻略

本文详细介绍了在群晖NAS上从零部署Container Manager与配置Docker代理的完整流程。针对国内用户常见的镜像拉取问题,提供了图形化界面与SSH命令行两种解决方案,并分享了MySQL容器部署的实战案例。文章特别强调了网络配置技巧和日常维护方法,帮助用户高效管理NAS上的容器应用。

weixin_29254673的博客 1303

UNet改进(54):当医学图像分割遇上频域学习与自监督

本文提出了一种改进U-Net的方法,通过频域增强模块和代理任务模块提升医学图像分割性能。频域增强模块在傅里叶空间对特征图进行可学习的频率调制,重点增强高频细节特征;代理任务模块通过图像重建约束编码器保留关键信息。两个模块协同工作,在仅增加5%参数量的情况下,形成空间域、频域和重建约束三条互补的信息路径。该方法特别适用于需要精细边缘分割的医学图像任务,预期能提升5%-10%的边缘分割精度,在小样本场景效果更显著。部署时可移除代理任务模块,不影响推理效率。未来可探索空间自适应频域调制和更丰富的代理任务设计。

2501_91516851的博客 226

OpenCV访问元素的几种方式.at<>(), .ptr<>(), .data,并测试了各自的速度

OpenCV访问元素的几种方法

qq_41253960的博客 1178

XLSX Workbench 在 ABAP 世界的定位与实战:从概念到完整示例

XLSX Workbench 在可视化、易维护与批量后台生成三方面填补了 ABAP 报表到 Excel 的空白。它与官方类及社区明星 abap2xlsx 形成了“模板驱动、代码驱动、二者兼顾”的互补格局。掌握 Workbench 后,开发者能把精力集中在业务逻辑以及数据质量,而把排版细节交给图形化工具,大幅加速交付与迭代。通过本文提供的示例,你可以立即在项目中落地并尝到效率提升的红利。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 522

OpenCV Mat 常用的基础知识

Mat 基础 图片在计算机中的本质就是一个数组。其中 Mat 就是在 OpenCV 中图像的表示形式,因此简单介绍 Mat 中一些常用的基础知识。 其中 Mat 类中有一些基本属性: cols :矩阵列数 rows:矩阵行数 channels:通道数 type:数据类型 total:矩阵总元素数 data:指向矩阵数据块的指针 其中 Mat 排列方式如下: 通道顺序为 BGR 参考:http...

Librarvl的博客 4122

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

【OpenCV】访问图像中每个像素的值

转载请注明出处:http://blog.youkuaiyun.com/xiaowei_cqu/article/details/7557063 !!此篇是基于IplImage* (C接口或者说2.1之前版本的接口,新的Mat的访问方式请参考博文: 《访问Mat图像中每个像素的值》) IplImage是OpenCV中CxCore部分基础的数据结构,用来表示图像,其中Ipl是Intel Image P...

编程语言小筑 89

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

Opencv读取mat和cvMat元素&&Mat与IplImage和CvMat类型之间的相互转换

综述: OpenCV有针对矩阵操作的C语言函数. 许多其他方法提供了更加方便的C++接口,其效率与OpenCV一样. OpenCV将向量作为1维矩阵处理. 矩阵按行存储,每行有4字节的校整. 分配矩阵空间: CvMat* cvCreateMat(int rows, int cols, int type); type: 矩阵元素类型. 格式为CV_(S|U|F)C.

chlele0105的专栏 1万+

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

【02】OpenCv C#——OpenCvSharp编程入门与矩阵Mat的基础知识

C#,OpenCv开发指南(02)——OpenCvSharp编程入门与矩阵Mat的基础知识 1.4 属性和常量方法的解释 1.4.7 Depth() 每一个像素中每一个通道的精度。在Opencv中,Mat.Depth()得到的是一个 0~6 的数字,分别代表不同的位数,对应关系如下: 其中U是unsigned的意思,S表示signed,也就是有符号和无符号数。 1.4.9 Step() and Step1() 1.5 Mat Type 的定义 2.1 从数据(数组)创建 Mat 其中显示 矩阵 的

程序员,他们想的是什么?他们想的永远都是技术,他们崇尚的也永远都是技术。 2620

opencv CvMat操作总结

综述:         OpenCV有针对矩阵操作的C语言函数. 许多其他方法提供了更加方便的C++接口,其效率与OpenCV一样.         OpenCV将向量作为1维矩阵处理.         矩阵按行存储,每行有4字节的校整.           分配矩阵空间:     CvMat* cvCreateMat(int rows, int cols, int type)

todayq的专栏 1059

OpenCv矩阵操作 .

OpenCv矩阵操作 有很多函数有mask,代表掩码,如果某位mask是0,那么对应的src的那一位就不计算,mask要和矩阵/ROI/的大小相等 大多数函数支持ROI,如果图像ROI被设置,那么只处理ROI部分 少部分函数支持COI,如果COI设置,只处理感兴趣的通道 矩阵逻辑运算 void cvAnd(const CvArr* src1,const CvArr* src2,

优雅黑曼巴的专栏 2343

OpenCV学习(4) Mat的基本操作(1)

http://www.cnblogs.com/mikewolf2002/p/3320284.html OpenCV学习(4) Mat的基本操作(1)       图像在OpenCV中都是通过Mat类来存储的,Mat可以用来表示N维矩阵,当然用的最多的还是二维矩阵。       Mat类有两部分组成:第一部分是头信息,这些信息主要用来描述矩阵,比如矩阵维数ndims,row

不是我的博客 569

opencv 图像和大数组类型

一、The cv::Mat Class: N-Dimensional Dense Arrays 1.1 Creating an Array Mat m; m.create(3, 10, CV_32FC3); m.setTo(Scalar(100.0f, 100.0f, 100.0f)); Mat n(3, 10, CV_32FC3, Scalar(100.0f, 100.0f, 100.0...

zhangjunp3的博客 695

Opencv矩阵操作函数大全---分类整理

原文地址:【转载】OpenCv矩阵操作作者:键盘上跳舞 OpenCv矩阵操作 有很多函数有mask,代表掩码,如果某位mask是0,那么对应的src的那一位就不计算,mask要和矩阵/ROI/的大小相等 大多数函数支持ROI,如果图像ROI被设置,那么只处理ROI部分 少部分函数支持COI,如果COI设置,只处理感兴趣的通道 矩阵逻辑运算 void cvAnd(

muzhiai的专栏 1512

OpenCv矩阵操作

OpenCv矩阵操作 有很多函数有mask,代表掩码,如果某位mask是0,那么对应的src的那一位就不计算,mask要和矩阵/ROI/的大小相等 大多数函数支持ROI,如果图像ROI被设置,那么只处理ROI部分 少部分函数支持COI,如果COI设置,只处理感兴趣的通道 矩阵逻辑运算 void cvAnd(const CvArr* src1,const CvArr* src2,

6533

【OpenCV】CvMat的用法详解及实例

1.初始化矩阵 2.IplImage 到cvMat的转换 3.cvArr(IplImage或者cvMat)转化为cvMat 4.图像直接操作 5.cvMat的直接操作 6.间接访问cvMat 7.修改矩阵的形状——cvReshape的操作 8.计算色彩距离

Panonsense 1225

opencv矩阵总结

OpenCV 矩阵操作 CvMat 转自:http://hi.baidu.com/xiaoduo170/blog/item/10fe5e3f0fd252e455e72380.html 每回用矩阵都要查,这回查到一个比较正确齐全的,放在自己的博客上以后可查 综述: OpenCV有针对矩阵操作的C语言函数. 许多其他方法提供了更加方便的C++接口,其效率与OpenCV一...

weixin_30924239的博客 123

OpenCV分配与释放图像空间

 图像处理 单通道图像灰度取值 IplImage * pSrcImage = cvLoadImage("Sunset.jpg",CV_LOAD_IMAGE_GRAYSCALE); uchar * pSrcData = (uchar *)pSrcImage->imageData; for (int i = 0; i height; i++)    {       for (int

ly334846035的专栏 1699
上一篇: rosdep init rosep update问题解决
下一篇: InputArray和OutputArray
黑猫爱小鹿
博客等级 码龄8年 1万+粉丝 205原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值