opencv笔记 -- 核心功能模块(Mat)

2024-06-05 17:20

本文主要是介绍opencv笔记 -- 核心功能模块(Mat),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

笔者之前零零碎碎地用过一些opencv,但是一直没有足够详尽的了解,正巧刷到了opencv的tutorial,仅以此记录。
网址:link

Mat - 基本的图像容器

在这里插入图片描述
一张普通的图片,如果想让计算机也能读得懂的话,我们需要把他转换成矩阵格式,也就是上图中的数字部分。使用Opencv的主要重点就是操作和处理这些数据。那么第一步就是如何存储和处理图片。

在opencv中使用mat来存储图像,且不需要手动分配其内存或在不需要时释放它。大多数OpenCV函数将自动分配其输出数据。如果您传递一个已经存在的Mat对象,它已经为矩阵分配了所需的空间,那么它将被重用。换句话说,我们在任何时候都只使用执行任务所需的内存。

为了避免对较大图像的不必要复制,opencv使用了一个引用计数系统,让每个mat对象都有自己的头,但是一个矩阵可以在两个mat对象之间共享,通过让它们的矩阵指针指向相同的地址。此外,复制操作符只复制头文件和指向大矩阵的指针,而不复制数据本身。

Mat A, C; // creates just the header parts
A = imread(argv[1], IMREAD_COLOR); // here we'll know the method used (allocate matrix)Mat B(A); // Use the copy constructorC = A; // Assignment operator

上面的所有的对象都指向了同一个单一的数据矩阵,并且其中任意一个发生了改变都会影响其他的。实际上不同的对象仅会对同一个根本数据提供不同的入口。然而,它们的标题部分是不同的。真正有趣的部分是,您可以创建仅引用完整数据的一部分的头。例如,要在图像中创建感兴趣的区域(ROI),只需创建带有新边界的新标题:

Mat D (A, Rect(10, 10, 100, 100) ); // using a rectangle
Mat E = A(Range::all(), Range(1,3)); // using row and column boundaries

如果矩阵属于不同的Mat对象,最后一个使用该矩阵的对象负责清理该矩阵。如果有复制图片的需求,那么可以使用cv::Mat::clone() 和cv::Mat::copyTo()功能。

Mat F = A.clone();
Mat G;
A.copyTo(G);

对F和G的修改不会对A造成任何影响。以下是一些总结的tips

  • 输出的图片分瓶是自动完成的。
  • 无需担心内存管理。
  • 赋值操作和复制构造只复制了头部。
  • 一个图片的根本矩阵可以使用clone和copyto功能进行复制。

存储方法

我们可以使用颜色空间和数据类型来存储像素的值。颜色空间指的是我们如何组合颜色组件来编码给定的颜色。最简单的一种是灰度,我们可以使用的颜色是黑色和白色。这些组合使我们能够创造出许多灰色阴影。

彩色方案可以被分成三到四个基础颜色组合(三原色)。最流行的组合是RGB,主要是因为我们的眼睛就是以此为基础来组成颜色的。此外,透明度alpha(A)也会被添加进来。(0代表完全透明,255代表完全不透明)。

但是不同的颜色系统的优势各不相同:

  • RGB是最常见的,因为我们的眼睛使用类似的东西,但请记住,OpenCV标准显示系统使用BGR色彩空间(红色和蓝色通道交换位置)来组合颜色。
  • HSV和HLS将颜色分解成它们的色调、饱和度和值/亮度组件,这是我们描述颜色的一种更自然的方式。例如,您可以忽略最后一个组件,使您的算法对输入图像的光照条件不那么敏感。
  • 流行的JPEG图像格式使用YCrCb。
  • CIE Lab*是一个感知上一致的色彩空间,如果你需要测量一种给定颜色到另一种颜色的距离,它会派上用场。

创造一个Mat对象

以下是创建一个Mat对象的方法:

  • 默认构造
 Mat M(2,2, CV_8UC3, Scalar(0,0,255));cout << "M = " << endl << " " << M << endl << endl;

在这里插入图片描述

对于二维多通道图像,我们首先需要定义他们的大小,行数和列数。然后需要明确用来存储这些元素的数据类型和每个矩阵点的通道数。

CV_[The number of bits per item][Signed or Unsigned][Type Prefix]C[The channel number]

举个例子,CV_8UC3代表我们使用unsigned char类型,8bit长且每个像素都有三个char类型来组成三个通道。通道最多只有四个。标量是一个四元素短向量。指定它,您可以用自定义值初始化所有矩阵点。如果需要更多类型,可以使用上面的宏创建类型,在括号中设置通道号,如下所示。

  • 使用c/c++队列并通过构造器进行初始化。
 int sz[3] = {2,2,2};Mat L(3,sz, CV_8UC(1), Scalar::all(0));

上面的例子展示了如何创建一个二维以上的矩阵。指定它的维度,然后传递一个包含每个维度大小的指针,其余部分保持不变。

  • cv::Mat::create功能
 M.create(4,4, CV_8UC(2));cout << "M = "<< endl << " " << M << endl << endl;

在这里插入图片描述
你无法通过这个构造器来初始化这个矩阵,尽在新的大小不符合原来的大小时,才会重新分配数据内存。

  • MATLAB style 初始化: cv::Mat::zeros , cv::Mat::ones , cv::Mat::eye
 Mat E = Mat::eye(4, 4, CV_64F);cout << "E = " << endl << " " << E << endl << endl;Mat O = Mat::ones(2, 2, CV_32F);cout << "O = " << endl << " " << O << endl << endl;Mat Z = Mat::zeros(3,3, CV_8UC1);cout << "Z = " << endl << " " << Z << endl << endl;

在这里插入图片描述

  • 对于小的矩阵,你可以使用逗号来区分初始化器
 Mat C = (Mat_<double>(3,3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);cout << "C = " << endl << " " << C << endl << endl;
 C = (Mat_<double>({0, -1, 0, -1, 5, -1, 0, -1, 0})).reshape(3);cout << "C = " << endl << " " << C << endl << endl;

在这里插入图片描述

  • 为一个已经存在的Mat对象创造一个新的头部并使用 cv::Mat::clone or cv::Mat::copyTo
 Mat RowClone = C.row(1).clone();cout << "RowClone = " << endl << " " << RowClone << endl << endl;

在这里插入图片描述

note:
你可以使用**cv::randu()**功能来随机填充一个矩阵,但是需要给出一个最小和最大值的限制。

 Mat R = Mat(3, 2, CV_8UC3);randu(R, Scalar::all(0), Scalar::all(255));

输出格式

原文写得挺好的,直接贴上来。
在这里插入图片描述

其他的常见输出

在这里插入图片描述

总结

本文主要介绍了一下如何在opencv中进行存储,以及相应的一些操作,如复制,构造等。
在笔者的实际使用过程中,需要格外注意opencv的操作耗时问题,尤其是cv::imread操作。

这篇关于opencv笔记 -- 核心功能模块(Mat)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1033692

相关文章

深度解析Spring Security 中的 SecurityFilterChain核心功能

《深度解析SpringSecurity中的SecurityFilterChain核心功能》SecurityFilterChain通过组件化配置、类型安全路径匹配、多链协同三大特性,重构了Spri... 目录Spring Security 中的SecurityFilterChain深度解析一、Security

OpenCV在Java中的完整集成指南分享

《OpenCV在Java中的完整集成指南分享》本文详解了在Java中集成OpenCV的方法,涵盖jar包导入、dll配置、JNI路径设置及跨平台兼容性处理,提供了图像处理、特征检测、实时视频分析等应用... 目录1. OpenCV简介与应用领域1.1 OpenCV的诞生与发展1.2 OpenCV的应用领域2

在Java中使用OpenCV实践

《在Java中使用OpenCV实践》用户分享了在Java项目中集成OpenCV4.10.0的实践经验,涵盖库简介、Windows安装、依赖配置及灰度图测试,强调其在图像处理领域的多功能性,并计划后续探... 目录前言一 、OpenCV1.简介2.下载与安装3.目录说明二、在Java项目中使用三 、测试1.测

Olingo分析和实践之OData框架核心组件初始化(关键步骤)

《Olingo分析和实践之OData框架核心组件初始化(关键步骤)》ODataSpringBootService通过初始化OData实例和服务元数据,构建框架核心能力与数据模型结构,实现序列化、URI... 目录概述第一步:OData实例创建1.1 OData.newInstance() 详细分析1.1.1

Spring Boot Maven 插件如何构建可执行 JAR 的核心配置

《SpringBootMaven插件如何构建可执行JAR的核心配置》SpringBoot核心Maven插件,用于生成可执行JAR/WAR,内置服务器简化部署,支持热部署、多环境配置及依赖管理... 目录前言一、插件的核心功能与目标1.1 插件的定位1.2 插件的 Goals(目标)1.3 插件定位1.4 核

Python使用OpenCV实现获取视频时长的小工具

《Python使用OpenCV实现获取视频时长的小工具》在处理视频数据时,获取视频的时长是一项常见且基础的需求,本文将详细介绍如何使用Python和OpenCV获取视频时长,并对每一行代码进行深入解析... 目录一、代码实现二、代码解析1. 导入 OpenCV 库2. 定义获取视频时长的函数3. 打开视频文

Python如何将OpenCV摄像头视频流通过浏览器播放

《Python如何将OpenCV摄像头视频流通过浏览器播放》:本文主要介绍Python如何将OpenCV摄像头视频流通过浏览器播放的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完... 目录方法1:使用Flask + MJPEG流实现代码使用方法优点缺点方法2:使用WebSocket传输视

详解MySQL中DISTINCT去重的核心注意事项

《详解MySQL中DISTINCT去重的核心注意事项》为了实现查询不重复的数据,MySQL提供了DISTINCT关键字,它的主要作用就是对数据表中一个或多个字段重复的数据进行过滤,只返回其中的一条数据... 目录DISTINCT 六大注意事项1. 作用范围:所有 SELECT 字段2. NULL 值的特殊处

使用Python和OpenCV库实现实时颜色识别系统

《使用Python和OpenCV库实现实时颜色识别系统》:本文主要介绍使用Python和OpenCV库实现的实时颜色识别系统,这个系统能够通过摄像头捕捉视频流,并在视频中指定区域内识别主要颜色(红... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间详解

OpenCV实现实时颜色检测的示例

《OpenCV实现实时颜色检测的示例》本文主要介绍了OpenCV实现实时颜色检测的示例,通过HSV色彩空间转换和色调范围判断实现红黄绿蓝颜色检测,包含视频捕捉、区域标记、颜色分析等功能,具有一定的参考... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间