C++ opencv图像存储和MAT容器

news2024/11/26 12:44:01


1.图像在内存之中的存储方式:


图像矩阵的大小取决于所用的颜色模型,确切说,取决于所用通道数。如果是灰度图像,矩阵就会如图5.1所示。
 

 

对于多通道图像来说,矩阵中的列会包含多个子列,其子列个数与通道数相同,如图5.2所示RGB颜色模型的矩阵。

可以看到,OpenCV中子列的通道顺序是反过来的——BGR而不是RGB。 有时候,由于内存足够大,可实现连续存储,图像中的各行是一行一行连接起来的,形成一个长行。可以使用isContinuous()来判断矩阵是否是连续存储的。

2.mat矩阵   (图像存储类型)

1.概念:

Mat是一个类,由两部分组成:

什么是Mat呢,Mat其实就是matrix(矩阵)的缩写
我们看到的图像,就是以数字矩阵的形式存储在计算机中,在opencv中,我们用Mat类的对象存储图像。

在opencv中,Mat类分为两个部分

  • 矩阵头
  • 矩阵数据

矩阵头

图像有很多属性。如:大小,宽和高,数据类型,通道数。这些数据存储在矩阵头

矩阵数据

图像也有很多的数据,图像的数据部分是所有像素的值的一个集合,存储在矩阵数据

在这里插入图片描述

如下边代码:

Mat A, C;  // 仅创建信息头部分
A = imread("1.jpg", CV_LOAD_IMAGE_COLOR)  // 这里为矩阵开辟内存
Mat B(A)  //使用拷贝构造函数
C=A;     //赋值运算符
上述代码中的所有Mat对象最终都指向同一个也是唯一一数据矩阵。虽然它们的信息头不同,但通过任何一个对象所做的改变也会影响其他对象。

创建部分信息数据的信息头:只需要创建包含边界信息的信息头
Mat D(A, Rect(10, 10, 100, 100));  //使用矩形界定
Mat E = A(Range:all(), Range(1, 3)
复制矩阵本身(不只是复制信息头和矩阵指针):使用函数clone()、copyTo()
Mat F = A.clone();
Mat G;
A.copyTo(G)
上述代码,改变F和G就不会影响Mat信息头所指向的矩阵。

2.Mat对象复制


看上图,我们发现Mat对象复制是有三种方法的

克隆
拷贝
赋值


这里说一下它们的区别

赋值:相当于浅复制,只复制了矩阵头,指向的是同一个数据块。类似浅拷贝,指针直接指向

克隆/拷贝:相当于深复制,还会复制相应的数据块

//1.赋值——浅复制
Mat src = imread("……");
Mat m3 = src;

//2.克隆——深复制
Mat src = imread("……");
Mat m1 = src.clone();

//3.拷贝——深复制
Mat src = imread("……");
Mat m2;
src.copyTo(m2);

3.Mat对象属性


Mat对象存储了一些属性,如:列数,行数,通道数(维度),位深度,图像类型

Mat image= imread("……");

获取方式:

image.cols;列
image.rows;行
image.channels();通道
image.depth();深度
image.type();类型

image.size() 长x高

数据类型和通道数
图像的数据类型type由两部分组成

std::cout << m << std::endl;//为了说明以上语句的不同,我们把矩阵进行打印

说明:

  • 通道数

在opencv中type是枚举类型的数值
如CV_8UC3:表示 8位无符号整数(字节类型)三通道。枚举数值16
在这里插入图片描述
忽略掉前面的字符,我们只关注Cx,可以很快的发现,Cx即表示通道数channels。
如C1——单通道,C2——双通道……

注意:

当为单通道时,C1可以省略,直接为CV_8U
单通道为灰度图像,三通道为彩色图像

  • 深度

图像深度depth和数据类型关联密切,其在opencv中也为枚举数值。

在这里插入图片描述
图像深度有真实值和枚举值之分。

  • 枚举值

图像depth的枚举值跟通道数无关,相同类型下如CV_8UC1和CV_8UC3,图像深度的枚举值是一样的

  • 真实值

图像depth的真实值还要考虑通道数,如CV_8UC3 的通道数为 8*3=24位

3.Mat对象的创建 与初始化

 
1.使用无参数构造函数,创建Mat对象。

Mat image = Mat();
image.create(4, 4, CV_8UC3);//创建一个4x4大小的像素块,每个像素都是三通道每个通道的位数都是8位
1
2
上述CV_8UC3中的8表示8位,UC表示uchar类型,3表示三个通道。


2.使用带行、列、类型这个三个参数的构造函数创建Mat对象

Mat m = Mat(4, 4, CV_8UC3); //创建一个4x4大小的像素块,每个像素都是三通道每个通道的位数都是8位
与方法二创建的像素块一样。


3.使用行、列、类型、Scalar向量四个参数的构造函数创建Mat对象。

Mat m = Mat(4, 4, CV_8UC3, Scalar(0, 255, 255)); 
//创建一个4x4大小的像素块,每个像素都是三通道每个通道的位数都是8位,指定三通道颜色值向量Scalar(0, 255, 255)

同样表示创建一个4x4的像素块,唯一的区别是颜色不是默认值,而是我们指定的三通道颜色值向量Scalar(0, 255, 255)。其中Scalar向量数目永远是等于通道数目。


4.使用大小、类型两个参数的构造函数创建Mat对象。

Mat m = Mat(Size(4, 4), CV_8UC3); //创建一个4x4大小的像素块,每个像素都是三通道每个通道的位数都是8位


5.使用大小、类型、Scalar向量三个参数的构造函数创建Mat对象。

Mat m = Mat(Size(4, 4), CV_8UC3, Scalar(255, 0, 0)); //创建一个4x4大小的像素块,每个像素都是三通道每个通道的位数都是8位

Mat对象创建,常用的是创建空白图像。如下演示了三种

Mat src = imread("……");


Mat m4 = Mat::zeros(src.size(),src.type())
/*
矩阵填充0
    行列为src行列
        数据类型为src的数据类型
*/

Mat m5 = Mat::zeros(Size(512,512),CV_8UC3);
/*
矩阵填充0
    行列为512*512
        数据类型为CV_8UC3(8UC指8位无符号字符,3指3个通道)            
*/

Mat m6 = Mat::ones(Size(512,512),CV_8UC3);
/*
矩阵填充1
    其余与上相同
*/


Mat kernel = (Mat_<char>(3,3)<<0,-1,0,-1,5,-1,0,-1,0); 位数,只有灰度
/*
矩阵自由填充 类型
    
*/

4.Mat对象的赋值

最常用的有4种方法

  • Mat::zeros()
  • Mat::ones();
  • =
  • Scalar

现在开始分别说明

  • Mat::zeros

创建空矩阵

Mat m = Mat::zeros(Size(8, 8), CV_8UC1);
Mat m = Mat::zeros(Size(8, 8), CV_8UC3);

矩阵宽度 = 图像的列 * 通道数

当为CV_8UC1时,单通道,矩阵宽度8
当为CV_8UC3时,三通道,矩阵宽度24


在这里插入图片描述
在这里插入图片描述

  • Mat::ones

创建1矩阵

Mat m = Mat::ones(Size(8, 8), CV_8UC1);
Mat m = Mat::ones(Size(8, 8), CV_8UC3);

注:

当填充为1的时候,要特别小心

单通道没问题,但是三通道这种多通道,只在第一个通道为1
在这里插入图片描述

  • 重载的 =

直接赋值

m=127;

和Mat::ones相同,单通道没问题,多通道只赋值第一个
在这里插入图片描述

  • Scalar

前面的三种方式,只用Mat::zeros实现了多通道的赋值,但是只能赋值为0,非常局限。

下面介绍一个非常常用的赋值方法,比如我们赋值三通道,全变127

m=Scalar(127,127,127);

在这里插入图片描述

5.Mat对象的显示


在opencv中Mat矩阵就是图像,那我们来显示一下全127对应的图像

void QuickDemo::mat_creation_demo(Mat& image) {

    //创建空白图像
    Mat m3 = Mat::ones(Size(400, 400), CV_8UC3);

    m3 = Scalar(127, 127, 127);

    imshow("创建图像", m3);
}

6.总结:

OpenCV函数中输出图像的内存分配是自动完成的(如果不特别指定的话)

使用OpenCV的C++接口时不需要考虑内存释放问题

赋值运算符和拷贝构造函数(构造函数)只复制信息头和矩阵指针

使用clone()函数或copyTo()来复制一幅图像的矩阵

像素值的存储方法:


RGB:最常见

HSV、HSL:将颜色分解成色调、饱和度、亮度/明度

YCrCb:JPEG图像格式广泛使用

CIE L*a*b*:在感知上均匀的颜色空间,适合度量两个颜色之间的距离
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/4278.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【运筹优化】结合天际线启发式的蚁群算法求解二维矩形装箱问题 + Java代码实现

文章目录一、天际线启发式二、蚁群算法结合天际线启发式2.1 构建序列2.1.1 思路一2.1.2 思路二2.1.3 思路N三、Java代码实现3.1 项目结构3.2 Ant3.3 ACO3.4 Run3.5 运行结果展示3.5.1 思路一3.5.2 思路二3.5.3 思路N四、小结一、天际线启发式 关于天际线启发式的介绍请看我的另…

推荐算法---矩阵分解

矩阵分解报告 1. 试验介绍 矩阵分解就是把原来的大矩阵&#xff0c;近似的分解成小矩阵的乘积&#xff0c;在实际推荐计算时不再使用大矩阵&#xff0c;而是使用分解得到的两个小矩阵。具体来说就是&#xff0c;假设用户物品的评分矩阵R是m乘n维&#xff0c;即一共有m个用户&…

Redis资料整理

Redis--->是非关系型数据库(也称缓存数据库),是一种NoSQL数据库 存放5种数据类型 String key-value形式 另外list,set,zset,hash 另外两种不常用的:bitmap(位图类型),geo(地理位置类型),另外Redis5.0新增 stream类型 相对来说Redis适合存放少数据量的数据,如果需要存放…

BERT知识蒸馏TinyBERT

1. 概述 诸如BERT等预训练模型的提出显著的提升了自然语言处理任务的效果&#xff0c;但是随着模型的越来越复杂&#xff0c;同样带来了很多的问题&#xff0c;如参数过多&#xff0c;模型过大&#xff0c;推理事件过长&#xff0c;计算资源需求大等。近年来&#xff0c;通过模…

PX4基本配置

目录 下载固件 下载原生稳定版固件 安装PX4 Master, Beta或自定义固件 FMUv2 Bootloader 更新 机架设置 飞行控制器/传感器方向 计算朝向 设置朝向 罗盘校准 执行校准 陀螺仪校准 # 执行校准 加速度计 执行校准 空速计校准 执行校准 水平平面校准 执行校准 …

Spring Cloud Zookeeper 升级为Spring Cloud Kubernetes

这里是weihubeats,觉得文章不错可以关注公众号小奏技术&#xff0c;文章首发。拒绝营销号&#xff0c;拒绝标题党 背景 现有的微服务是使用的Spring Cloud Zookeeper这一套&#xff0c;实际应用在Kubernetes中部署并不需要额外的注册中心&#xff0c;本身Kubernetes自己就支持…

10道不得不会的 Java容器 面试题

博主介绍&#xff1a; &#x1f680;自媒体 JavaPub 独立维护人&#xff0c;全网粉丝15w&#xff0c;csdn博客专家、java领域优质创作者&#xff0c;51ctoTOP10博主&#xff0c;知乎/掘金/华为云/阿里云/InfoQ等平台优质作者、专注于 Java、Go 技术领域和副业。&#x1f680; 最…

FFmpeg内存IO模式

ffmpeg 支持从网络流 或者本地文件读取数据&#xff0c;然后拿去丢给解码器解码&#xff0c;但是有一种特殊情况&#xff0c;就是数据不是从网络来的&#xff0c;也不在本地文件里面&#xff0c;而是在某块内存里面的。 这时候 av_read_frame() 函数怎样才能从内存把 AVPacket…

TensorFlow的GPU使用相关设置整理

前言 TensorFlow是一个在机器学习和深度学习领域被广泛使用的开源软件库&#xff0c;用于各种感知和语言理解任务的机器学习。 默认情况下&#xff0c;TensorFlow 会映射进程可见的所有 GPU&#xff08;取决于 CUDA_VISIBLE_DEVICES&#xff09;的几乎全部内存。这是为了减少内…

国考省考行测:问题型材料主旨分析,有问题有对策,主旨是对策,有问题无对策,要合理引申对策

国考省考行测&#xff1a;问题型材料主旨分析&#xff0c;有问题有对策&#xff0c;主旨是对策&#xff0c;有问题无对策&#xff0c;要合理引申对策 2022找工作是学历、能力和运气的超强结合体! 公务员特招重点就是专业技能&#xff0c;附带行测和申论&#xff0c;而常规国考…

【Linux】Linux背景、环境的搭建以及用XShell实现远程登陆

目录Linux 背景Linux环境搭建Linux远程登陆Linux 背景 肯尼斯蓝汤普森最早用汇编语言创建了UNIX系统&#xff0c;后来与他的好“基友”丹尼斯里奇&#xff08;C语言之父&#xff09;&#xff0c;他们两个一同用C语言重新写了UNIX系统&#xff0c;但是操作系统的使用是需要收费…

ActiveState Platform - November 2022

ActiveState Platform - November 2022 ActiveState平台定期更新新的、修补的和版本化的软件包和语言。 Python 3.10.7、3.9.14、3.8.14-解决了许多安全问题的点发布。 Python C库-ibxml 2.10.3、libxslt 1.1.37、libexpat 2.4.9、zlib 1.2.13、curl 7.85.0和sqlite3 3.39.4&am…

Python添加水印简简单单,三行代码教你批量添加

环境使用: Python 3.8Pycharm 如何配置pycharm里面的python解释器? 选择file(文件) >>> setting(设置) >>> Project(项目) >>> python interpreter(python解释器)点击齿轮, 选择add添加python安装路径 pycharm如何安装插件? 选择file(文件) …

使用Python PyQt5完成残缺棋盘覆盖仿真作业

摘要&#xff1a;本文内容是关于如何实现残缺棋盘覆盖仿真软件&#xff0c;算法课作业要求设计开发一个残缺棋盘覆盖仿真软件。使用”分治算法“求解问题&#xff0c;Python编程语言实现功能&#xff1b;使用PyQt5和Python热力图实现界面和仿真效果展示。 1 残缺棋盘覆盖仿真作…

[Linux打怪升级之路]-yun安装和gcc的使用

前言 作者&#xff1a;小蜗牛向前冲 名言&#xff1a;我可以接受失败&#xff0c;但我不能接受放弃 如果觉的博主的文章还不错的话&#xff0c;还请点赞&#xff0c;收藏&#xff0c;关注&#x1f440;支持博主。如果发现有问题的地方欢迎❀大家在评论区指正。 本期学习目标&am…

Java:外包Java项目有什么好处?

Java已经成为众多解决方案的通用开发语言&#xff0c;包括web应用、游戏、软件开发等等。超过710万全球的Java程序员都在忙着为业界下一个最好的应用程序编码。 随着企业努力在当今的全球市场中保持竞争力&#xff0c;对Java项目外包的需求不断增加。 以下是你的企业通过外包Ja…

python基于PHP+MySQL的论坛管理系统

互联网给了我们一个互通互信的途径,但是如何能够更加高效的进行各种问题的分享和交流是很多人关心的问题,市面上比较知名的一些分享交流平台也很多,比如百度的贴吧,知乎等高质量内容分享平台,本系统是一个类似这样的论坛分享系统 随着互联网的发展人们分享和交流的分享也变的越…

leetcode刷题(128)——1575. 统计所有可行路径,动态规划解法

leetcode刷题&#xff08;127&#xff09;——1575. 统计所有可行路径&#xff0c;DFS解法 给你一个 互不相同 的整数数组&#xff0c;其中 locations[i] 表示第 i 个城市的位置。同时给你 start&#xff0c;finish 和 fuel 分别表示出发城市、目的地城市和你初始拥有的汽油总…

【CSS】CSS字体样式【CSS基础知识详解】

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;花无缺 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 花无缺 原创 本文章收录于专栏 【CSS】 【CSS专栏】已发布文章 &#x1f4c1;【CSS基础认知】 &#x1f4c1;【CSS选择器全解指南】 本文目录【CS…

物联网感知-光纤光栅传感器技术

一、光纤光栅传感技术 光纤光栅是利用光纤材料的光敏性&#xff0c;通过紫外光曝光的方法将入射光相干场图样写入纤芯&#xff0c;将周期性微扰作用于光纤纤芯&#xff0c;在纤芯内产生沿纤芯轴向的折射率周期性变化&#xff0c;从而形成永久性空间的相位光栅&#xff0c;其作用…