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

相关文章

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

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

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

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

Python包管理工具核心指令uvx举例详细解析

《Python包管理工具核心指令uvx举例详细解析》:本文主要介绍Python包管理工具核心指令uvx的相关资料,uvx是uv工具链中用于临时运行Python命令行工具的高效执行器,依托Rust实... 目录一、uvx 的定位与核心功能二、uvx 的典型应用场景三、uvx 与传统工具对比四、uvx 的技术实

java中Optional的核心用法和最佳实践

《java中Optional的核心用法和最佳实践》Java8中Optional用于处理可能为null的值,减少空指针异常,:本文主要介绍java中Optional核心用法和最佳实践的相关资料,文中... 目录前言1. 创建 Optional 对象1.1 常规创建方式2. 访问 Optional 中的值2.1

Python中OpenCV与Matplotlib的图像操作入门指南

《Python中OpenCV与Matplotlib的图像操作入门指南》:本文主要介绍Python中OpenCV与Matplotlib的图像操作指南,本文通过实例代码给大家介绍的非常详细,对大家的学... 目录一、环境准备二、图像的基本操作1. 图像读取、显示与保存 使用OpenCV操作2. 像素级操作3.

C/C++中OpenCV 矩阵运算的实现

《C/C++中OpenCV矩阵运算的实现》本文主要介绍了C/C++中OpenCV矩阵运算的实现,包括基本算术运算(标量与矩阵)、矩阵乘法、转置、逆矩阵、行列式、迹、范数等操作,感兴趣的可以了解一下... 目录矩阵的创建与初始化创建矩阵访问矩阵元素基本的算术运算 ➕➖✖️➗矩阵与标量运算矩阵与矩阵运算 (逐元

C/C++的OpenCV 进行图像梯度提取的几种实现

《C/C++的OpenCV进行图像梯度提取的几种实现》本文主要介绍了C/C++的OpenCV进行图像梯度提取的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录预www.chinasem.cn备知识1. 图像加载与预处理2. Sobel 算子计算 X 和 Y

C/C++和OpenCV实现调用摄像头

《C/C++和OpenCV实现调用摄像头》本文主要介绍了C/C++和OpenCV实现调用摄像头,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录准备工作1. 打开摄像头2. 读取视频帧3. 显示视频帧4. 释放资源5. 获取和设置摄像头属性

c/c++的opencv图像金字塔缩放实现

《c/c++的opencv图像金字塔缩放实现》本文主要介绍了c/c++的opencv图像金字塔缩放实现,通过对原始图像进行连续的下采样或上采样操作,生成一系列不同分辨率的图像,具有一定的参考价值,感兴... 目录图像金字塔简介图像下采样 (cv::pyrDown)图像上采样 (cv::pyrUp)C++ O

c/c++的opencv实现图片膨胀

《c/c++的opencv实现图片膨胀》图像膨胀是形态学操作,通过结构元素扩张亮区填充孔洞、连接断开部分、加粗物体,OpenCV的cv::dilate函数实现该操作,本文就来介绍一下opencv图片... 目录什么是图像膨胀?结构元素 (KerChina编程nel)OpenCV 中的 cv::dilate() 函