Mat相关的一系列知识(基础->进阶)【C++的OpenCV 第十三课-OpenCV基础强化(一)】

🎉🎉🎉 欢迎各位来到小白 p i a o 的学习空间! \color{red}{欢迎各位来到小白piao的学习空间!} 欢迎各位来到小白piao的学习空间!🎉🎉🎉


一、计算机世界的图像 \color{blue}{一、计算机世界的图像} 一、计算机世界的图像

1.1 计算机眼中的图像 \color{green}{1.1 计算机眼中的图像} 1.1计算机眼中的图像

1.1.1 现实中的图像和计算机视觉中的图像的区别

在这里插入图片描述

        计算机视觉中的图像是由计算机生成或处理得出的数字图像,而现实世界中的图像是由物理现象通过光学设备传到人眼或摄像头中的图像。其主要区别在于:

  1. 像素级别的精细度:计算机视觉中的图像可以通过算法处理得到非常精细的图像,可以检测出现实图像中难以察觉的变化。现实图像则受到拍摄设备和光线等外界因素的影响,难以达到计算机生成图像的精细度。
  2. 能否被操作:计算机视觉中的图像可以被计算机程序方便地处理和操作,例如图像识别、目标跟踪等。而现实图像则是静态的,需要通过摄像设备进行捕捉和转换才能被处理。
  3. 显示方式的不同:计算机视觉中的图像可以通过计算机显示器等电子设备呈现,具有清晰度高、可定制化强等优点。而现实图像则只能通过物理显示器、展示器等形式呈现,显示效果受到屏幕尺寸、分辨率等影响。
    综上,计算机视觉中的图像和现实图像在精准度、处理方式、显示方式等方面存在差异。
    \color{red}{}

1.1.2 真实图像在计算机中如何存储的

        图像在计算机中通常以 数字化 的方式存储,即 将图像转换为数字信号 。具体来说,图像被分成 像素 \color{red}{像素} 像素 ,每个像素都有一个颜色值或灰度值。每个颜色值或灰度值都表示为一个数字,通常是8bit整数,即0到255之间的一个数。 这些数字被编码并存储在计算机内存或磁盘上,形成一个数字矩阵,其中每个数字代表一个像素的颜色或灰度值。这个数字矩阵可以被计算机读取和处理,以进行图像编辑、图像处理、图像增强等应用。常见的图像格式包括JPEG、PNG、GIF、BMP等。
在这里插入图片描述

1.1.3 像素的概念

        像素是指组成图像的小方格,这些小方块都有一个明确的位置和被分配的色彩数值,小方格颜色和位置就决定该图像所呈现出来的样子。
在这里插入图片描述        一个像素中容纳的其实是一个或者一组色彩亮度值。先给大家一些提示:

在这里插入图片描述        看不懂没关系,接着往下看!

1.1.4 分辨率的概念

        分辨率指的是图像文件的像素数目,通常以横向像素数×纵向像素数来表示。分辨率越高,图片越清晰,细节表现更为丰富,但相应的文件大小也会增加。分辨率决定了图像的清晰度和可见细节,因此在选择摄影设备、打印设备或屏幕显示设备时,需要考虑达到所需分辨率的要求。
在这里插入图片描述

1.2 图像通道数的概念 \color{green}{1.2 图像通道数的概念} 1.2图像通道数的概念

        图像的通道数是指图像中可以分离出的独立信息的数量(重点,后边会有详细解释split和merge)。在彩色图像中,通常包含红色、绿色和蓝色(Red\Green\Blue)三个通道。这三个通道合称为RGB通道。每个像素都有三个值,它们代表着同一位置上红、绿、蓝三个颜色通道的亮度值。在灰度图像中,只有一个通道,每个像素只有一个亮度值。在一些特殊的图像处理任务中,会使用更多的通道来表示其他信息,例如alpha通道、深度通道或法线通道等。
        我们再沿用一下前边使用过的一张图片,这样大家就理解的更透彻了。
在这里插入图片描述

1.3 灰度图和彩色图像 \color{green}{1.3 灰度图和彩色图像} 1.3灰度图和彩色图像

1.3.1 彩色图像

        其实彩色图像很好理解,也很常见,通常我们常见的是RGB模式的彩色图,即一个像素点上的色彩由三个通道(R通道、G通道、B通道)的值组合而成后表达。
在这里插入图片描述

1.3.2 灰度图

        灰度图就更加简单了,我们前边说了,一个像素点中可以有一组值,或者一个值,而一组值的就是类似RGB这中的彩色图像的值,如果假设,R=G=B,即一个像素上就变成了一个值!那这种一个像素有一个值的图像,称之为灰度图,灰度图对计算机视觉中图像处理的帮助是非常大的!简而言之,非常好理解,一个像素上只有一个值的图像,就是灰度图。
![在这里插入图片描述](https://img-blog.csdnimg.cn/8aebeaf7cf3a42b69b74e43ee586b918.webp


二、 O p e n C V 中的 M a t \color{blue}{二、OpenCV中的Mat} 二、OpenCV中的Mat

2.1 初识 M a t \color{green}{2.1 初识Mat} 2.1初识Mat

        在OpenCV中,Mat是一个多维数组(矩阵)类(Matrix就是矩阵的意思,这里取其前三个字母),可以用于存储和处理图像和其他类型的数据。Mat类提供了许多有用的方法和操作符,使得图像和矩阵的处理更加容易和高效。它可以存储任意类型的数据,因此可以用于处理灰度图像、彩色图像和其他类型的数据。Mat类的使用也是OpenCV编程中非常重要的一部分。
        问题来了,矩阵这玩意和咱们的图像有啥关系,看下边这幅图:
在这里插入图片描述        前边说了,图像保存在磁盘中就是以一组数字保存的,那么这组数字要能够合理表达图像,就得有一定结构,那这里不难发现上边的灰度图的每个像素其实就是一个值,这个值就表达灰色的亮度值,那这种灰度图数据,什么数据结构最好形象的表达出来呢?盯住红色框,不妨往下看:

arr = [
			[101 89 110 101 98 99 103 123]
			[100 67 98 95 89 95 99 110]
			[101 56 87 89 87 93 95 97]
			[96 65 76 78 85 89 91 92]
			[67 56 67 78 74 83 86 86]
			[56 54 65 76 76 78 82 83]
			[67 34 56 56 73 74 79 79]
			[56 45 54 45 65 68 73 75]
		]

        我竟然会变态到把这个东西手敲一遍。。。发现了吗,这种结构是不是特别适合保存图像数据,而这,就是矩阵,只不过用Python代码写的,大家别介意,毕竟这语言变态就变态在易读性上,不妨借过来用一用。总而言之,矩阵当之无愧。(说白了,Mat存图像贼牛!)

2.2 单通道和多通道 M a t 相关的操作 \color{green}{2.2 单通道和多通道Mat相关的操作} 2.2单通道和多通道Mat相关的操作

2.2.1 OpenCV中单通道图片的创建及基本知识

// 其实这里分为两大类:
// 1、创建
#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>

using namespace cv;

int main()
{
    //demo1:
    Mat m;
    m.create(Size(3,2), CV_32FC(1)); // 注意:这是构造一个2行3列的矩阵!Size(列,行)!!!一定记住喽!!!

    Mat n = Mat::zeros(Size(3,2), CV_32FC1);// 元素值都是0的矩阵
    Mat o = Mat::ones(Size(3,2), CV_32FC1);// 元素值都是1的矩阵

    Mat p = (Mat_<int>(2,3) << 1,2,3,4,5,6);
    std::cout << p << std::endl;


    return 0;
}


// 这是另外一块代码:
// 2、从内存中读取(这个和我讲的知识点暂时没关系,也希望你们不要把注意力放在一个接口的使用上,毕竟你需要成长)
#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>

using namespace cv;

int main()
{
    //demo2:
    Mat img = imread("image.jpg");
    if (!img.data)
    {
        return -1;
    }
    imshow("test", img);
    waitKey(0);
    std::cout << "hello world!\n";
    return 0;
}


        上述的demo1代码当中出现了一个参数:CV_32FC(1) 或者CV_32FC1,这是什么?
在这里插入图片描述        其中这个32F :就是代表像素中的每一个值是32位的浮点值。其中还有很多种类:8U 8S 16U 16S 32F 32S 64F ,其中,数字代表每个数字所占的bit位,U代表uchar类型,F代表float或者double(64F中的F),S代表int。
        其中这个C1或者C(1),是一样的,C是Channel,通道的意思,后边的1是通道数,常见的组合有:C(同C1) , C1, C3 … 但其实,通道数可以为n。当n=1时,矩阵为二维矩阵(单通道矩阵),当n>1时,矩阵为三维矩阵(多通道矩阵),是不是有点迷糊了?为什么1代表二维矩阵?而大于1确实三维矩阵?为什么二维矩阵是单通道矩阵?而三维矩阵却成了多通道矩阵了??? 懵逼了吧?引发了一连串的“已放弃,核心已转储”吧?哈哈,不妨接着往下看!
在这里插入图片描述
        首先,这里的维度,不是指二维图像和三维图像,而是矩阵的维度!所以二维矩阵不代表二维图像,三维矩阵更不代表三维图像!
        第二,我们前边反复提到一个概念,一个像素中存储的是一个表示颜色的值,或者一组表示颜色的值,如果一个像素存一个值(单通道),这就是灰度图;换而言之,如果一个像素中存储三个值(三通道,例如:RGB三通道)表示该像素颜色的亮度,则这个图像就是彩色图像
        最后,我们再来讨论,众所周知,所有的图像都具备宽和高(国人口中的长和宽),最起码一张图像得有长和宽,所以,矩阵为了更好的存储图像,即至少是个二维矩阵(只有二维矩阵可以描述行和列)。而烧脑的地方来了,让我们联系第二点,整合一下思路!
在这里插入图片描述        简而言之!通道到底是什么?是像素中 表达颜色的值 的个数!灰度图(单通道)中每个像素只有一个值表示颜色;彩色图(例如RGB模式,三通道),每个像素中表达颜色的值却是3个!你理解了吗?
        所以呀,再提炼一下!看下图,一看就懂!

假如,这是一个灰度图:
在这里插入图片描述
看下边,这是几维?二维矩阵吧?

[
	[108  70  32]
	[201  233  201]
	[111 134 254]
]

假如,这是一个彩色图:
在这里插入图片描述
再看下边,这是不是一个三维矩阵呢?

[
[ [255 2 32]   [101 34 243]   。。。 ]
[ [103 23 233]   [47 0 1]     。。。 ]
      。。。      。。。       。。。
]
// 偷偷说一句:可以理解为宽、高、像素点(一个值【单通道】、三个值【多通道】.....)

是不是豁然开朗了?

2.2.2 OpenCV中单通道图的相关操作

2.2.2.1 使用成员变量rows和cols获取行列数
#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>

using namespace cv;

int main()
{
    //demo3:
    Mat m = (Mat_<int>(3,2) << 11, 12, 33, 42, 23, 53); // 模板构造 3行2列矩阵
    std::cout << "行数:" << m.rows << std::endl; // 行数:3
    std::cout << "列数:" << m.cols << std::endl; // 列数:2

    return 0;
}
2.2.2.2 使用size()成员方法获取矩阵尺寸
#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>

using namespace cv;

int main()
{
    Mat m = (Mat_<int>(3, 2) << 11, 12, 33, 42, 23, 53);
    Size size = m.size();
    std::cout << "尺寸:" << size << std::endl; //Size()对象提供很好的易读性显示的结果:尺寸:[2 x 3]

    return 0;
}
2.2.2.3 使用channels()成员方法获取矩阵通道数
int main()
{
    Mat m = (Mat_<int>(3, 2) << 11, 12, 33, 42, 23, 53);
    std::cout << "通道数:" << m.channels() << std::endl; //通道数:1

    return 0;
}
2.2.2.4 total()成员方法
int main()
{
    Mat m = (Mat_<int>(3, 2) << 11, 12, 33, 42, 23, 53);
    std::cout << "像素个数:" << m.totals() << std::endl; //像素个数:6
	//知道totals()是干嘛的了吧?
    return 0;
}
2.2.2.5 成员变量dims
int main()
{
    Mat m = (Mat_<int>(3, 2) << 11, 12, 33, 42, 23, 53);
    std::cout << "矩阵维数:" << m.dims << std::endl; //矩阵维数:2
	//注意:这是个变量!不是方法!
    return 0;
}

四、总结 \color{red}{四、总结} 四、总结

        点点滴滴的积累终成江河湖海,下次内容我们继续往后介绍《单通道值的访问方法》和《多通道矩阵基本操作》,大家做好准备哦。


💖💖💖 持续更新,期待关注! \color{blue}{持续更新,期待关注!} 持续更新,期待关注!💖💖💖

💖💖💖 持续更新,期待关注! \color{blue}{持续更新,期待关注!} 持续更新,期待关注!💖💖💖


💖 目前已经为大家更新了: \color{green}{目前已经为大家更新了:} 目前已经为大家更新了:

🎉Python基础、中级、高级;
🎉C++数据结构和算法;
🎉 Python数据结构和算法;
🎉OpenCV相关内容等重点内容(以前只有C++,现在同时为大家更新Python的相关内容)


💖 我的主页: \color{purple}{我的主页:} 我的主页:我的主页💖


💖 我的资源: \color{purple}{我的资源:} 我的资源:我的资源💖

  1. IT技术各档次模板
  2. 各类项目(企业、毕设)
  3. 数据库安装包(Mysql8.0)
  4. 技能资料(电子书、软考等)

前文链接:【C++的OpenCV】第十二课-OpenCV图像常用操作(九):找到图像的边界(轮廓)findContours()和drawContours()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小白piao

创作不易,支持一下!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值