此文章一共分为四篇
第一篇 入门篇(本篇)
第二篇 基础篇
第三篇 进阶篇
第四篇 项目篇
在这篇系列文章中,我将带你从"完全小白"一路打怪升级到能动手做真实项目 。
不堆术语、不讲空话,只用你能跑通的代码 + 能看懂的图解 + 踩过的坑总结 ,
手把手拆解 OpenCV 的核心逻辑。点个关注不迷路!!!
目录
[第一章 Python 和OpenCV](#第一章 Python 和OpenCV)
[第二章 搭建开发环境](#第二章 搭建开发环境)
[第三章 图像处理的基本操作](#第三章 图像处理的基本操作)
[第四章 像素的操作](#第四章 像素的操作)
[第五章 色彩空间与通道](#第五章 色彩空间与通道)
第一章 Python 和OpenCV
本篇包括Python与OpenCV、搭建开发环境、图像处理的基本操作、像素的 操作和色彩空间与通道。这5章的作用相当于"扫盲",即完成一个从"什么都不 知道"到"掌握关键知识点"的转变过程,为学习后面的内容奠定基础。
OpenCV是一个开源的计算机视觉库,并 以为计算机视觉提供通用性接口为目标。
计算机视觉 不会像人类视觉那样能够对图像进行感知和识别,更不会自动控制焦距和光圈,而是把图 像解析为按照栅格状排列的数字。以图1.7为例,计算机视觉将其解析为如图1.8所示的 按照栅格状排列的数字(图1.8只是图1.7的一部分)。

**这些按照栅格状排列的数字包含大量的噪声,噪声在图像上常表现为引起较强视觉效 果的孤立像素点或像素块,使得图像模糊不清。**因此,噪声是计算机视觉面临的一个难 题。要让图片变得清晰,就需要对抗噪声。
计算机视觉使用统计的方法对抗噪声,例如,计算机视觉虽然很难通过某个像素或者 这个像素的相邻像素判断这个像素是否在图像主体的边缘上,但是如果对图像某一区域内 的像素做统计,那么上述判断就变得简单了,即在指定区域内,图像主体的边缘应该表现 为一连串独立的像素,而且这一连串像素的方向应该是一致的。这部分内容就是本书第 13章要为读者讲解的图形检测。
例如,使用图形检测的相关方法,能够把图1.9中的图形边缘绘制成红色,进而得到 如图1.10所示的效果


OpenCV包含的模块
OpenCV包含的模块的层级结构
OpenCV常用的模块及其说明

Python OpenCV的开发工具

第二章 搭建开发环境

第三章 图像处理的基本操作
OpenCV的作用在于让开发人员更容易地通过编码来处理图像。那么,处理图像需 要执行哪些操作呢?图像处理的基本操作包含4个方面的内容:读取图像、显示图像、保 存图像和获取图像属性。其中,常用的图像属性有3个:shape、size和dtype。本章将 依次详解实现图像处理的4个基本操作,并分别阐明常用的3个图像属性各自的含义及其 使用方法。
3.1读取图像
image = cv2.imread(filename, flags)
image:imread()方法的返回值,返回的是读取到的图像。
filename:要读取的图像的完整文件名。例如,要读取当前项目目录下的 3.1.jpg,filename的值为"3.1.jpg"(双引号是英文格式的)。
flags:读取图像颜色类型的标记。当flags的默认值为1时,表示读取的是彩色图像,此时的flags值可以省略;当flags的值为0时,表示读取的是灰度图像 (如果读取的是彩色图像,也将转换为与彩色图像对应的灰度图像)。
图像不在工作目录下的时候,可以用绝对路径,如"D:/1.jpg"
灰度图像是一种每个像素都是从黑到白,被处理为256个灰度级别的单色图像。256 个灰度级别分别用0(纯黑色)~255(纯白色)的数值表示。
3.2显示图像
(1)imshow()方法用于显示图像,其语法格式如下:
cv2.imshow(winname, mat)
winname:显示图像的窗口名称。
mat:要显示的图像。
(2)waitKey()方法用于等待用户按下键盘上按键的时间。当用户按下键盘上的任 意按键时,将执行waitKey()方法,并且获取waitKey()方法的返回值。其语法格式如下:
retval = cv2.waitKey(delay)
retval:与被按下的按键对应的ASCII码。例如,Esc键的ASCII码是27,当用 户按Esc键时,waitKey()方法的返回值是27。如果没有按键被按下,waitKey() 方法的返回值是-1。
delay:等待用户按下键盘上按键的时间,单位为毫秒(ms)。当delay的值为 负数、0或者空时,表示无限等待用户按下键盘上按键的时间。
(3)destroyAllWindows()方法用于销毁所有正在显示图像的窗口,其语法格式如 下:
cv2.destroyAllWindows()
3.3保存图像
在实际开发的过程中,对一幅图像进行一系列的处理后,需要保存处理图像后的结 果。为此,OpenCV提供了用于按照指定路径保存图像的imwrite()方法,其语法格式如下:cv2.imwrite(filename, img)
filename:保存图像时所用的完整路径。(这个没必要是完整路径,我是用vs code开发的,所以保存和寻找图片都是当前工作空间文件夹下的,只要相对路径就可以保存了)
img:要保存的图像。
3.4获取图像属性
在处理图像的过程中,经常需要获取图像的大小、类型等图像属性。为此, OpenCV提供了shape、size和dtype 3个常用属性,具体含义分别如下。
shape: 如果是彩色图像,那么获取的是一个包含图像的水平像素、垂直像素 和通道数的数组,即(垂直像素,水平像素,通道数);如果是灰度图像,那么 获取的是一个包含图像的水平像素和垂直像素的数组,即(垂直像素,水平像 素)。
说明: 垂直像素指的是垂直方向上的像素,水平像素指的是水平方向上的像素。有关像 素、灰度图像和通道的内容,将在本书的第4章和第5章进行讲解
**size:**获取的是图像包含的像素个数,其值为"水平像素×垂直像素×通道 数"。灰度图像的通道数为1。
**dtype:**获取的是图像的数据类型。


3.5小结
本章主要详解了两个内容:图像处理的基本操作和常用的图像属性。
读者在完成图像 处理的基本操作的过程中,要注意3个问题:
一是通过更改参数,imread()方法读取到的图像既可以是一幅彩色图像,也可以是一幅灰度图像;
二是为了能够正常显示图像,要在 cv2.imshow()方法后紧跟着cv2.waitKey()方法;
三是当声明路径名 时,"/"和"\\"的作用是等价的(例如,D:/3.1.jpg等价于D:\\3.1.jpg)。
第四章 像素的操作
像素是图像的最小单位。每一幅图像都是由M行N列的像素组成的,其中每一个像素 都存储一个像素值。以灰度图像为例,计算机通常把灰度图像的像素处理为256个灰度级 别,256个灰度级别分别使用区间[0, 255]中的整数数值表示。其中,"0"表示纯黑 色;"255"表示纯白色。本章将围绕着像素展开,介绍如何使用NumPy模块操作像 素。

4.1像素
像素是构成数字图像的基本单位。现有一幅显示花朵的图像(见图4.1),在花瓣边 缘提取一个小圆圈圈住的区域,将得到一幅如图4.2所示的图像。


不难发现,图4.2所示的图像是由许多小方块组成的,通常把一个小方块称作一个像 素。因此,一个像素是具有一定面积的一个块,而不是一个点。需要注意的是,像素的形 状是不固定的,大多数情况下,像素被认为是方形的,但有时也可能是圆形的或者是其他 形状的。
4.1.1 确定像素的位置
以图4.1为例,在访问图4.1中的某个像素前,要确定这个像素在图4.1中的位置。那 么,这个位置应该如何确定呢?
在Windows 10系统的"画图"工具中打开图4.1,得到如图4.4所示的界面。在这 个界面中,就会得到图4.1在水平方向的像素是219个,在垂直方向的像素是292个

说明 图4.1在水平方向的像素是219个,与其对应的是x轴的取值范围,即0~218;同 理,在垂直方向的像素是292个,与其对应的是y轴的取值范围,即0~291。
这样,就能够通过坐标来确定某个像素在图4.1中的位置。在OpenCV中,正确表示 图4.1中某个像素坐标的方式是(y, x)。例如,在如图4.5所示的坐标系中,图4.1右下角 的像素坐标是(291, 218)。
4.1.2 获取像素的BGR值
现使用print()方法打印这个 像素,将得到这个像素的BGR值,代码如下:
得到的是一个BGR的数组 [247 149 49]
在讲解这3个数值各自代表的含义之前,先了解什么是三基色。
如图4.6所示,人眼能够感知红色、绿色和蓝色3种不同的颜色,因此把这3种颜色称 作三基色。如果将这3种颜色以不同的比例进行混合,人眼就会感知到丰富多彩的颜色。
那么,对于计算机而言,是如何对这些颜色进行编码的呢?答案就是利用色彩空间 。 也就是说,色彩空间是计算机对颜色进行编码的模型。
以较为常用的RGB色彩空间为例,在RGB色彩空间中,存在3个通道,即R通道、G 通道和B通道。其中,R通道指的是红色通道;G通道指的是绿色通道;B通道指的是蓝色 通道;并且每个色彩通道都在区间[0, 255]内取值。
这样,计算机将利用3个色彩通道的不同组合来表示不同的颜色。如图4.7所示,通 过截图工具,能够得到坐标(291, 218)上的像素值为(49, 42, 36)。 

使用print()方法打印图4.1中坐标(291, 218)上的像素px,其结果是(36, 42, 49)。 而图4.7中这个坐标上的像素值为(49, 42, 36)。这时会发现这两个结果中的数值是相同 的,但顺序是相反的,这是为什么呢?
原因是在RGB色彩空间中,彩色图像的通道顺序是R(49)→G(42) →B(36);但是,在OpenCV中,RGB色彩空间被BGR色彩空间取代,使得彩色图像 的通道顺序变为了B(36)→G(42)→R(49)。
从上文能够知晓,在BGR色彩空间的图像中,每3个数值表示一个像素,这3个数值 分别表示蓝色、绿色和红色3种颜色分量,把每一种颜色分量所在的区域称作通道。那 么,OpenCV是如何获取指定位置上的像素的B通道、G通道和R通道的值呢?
有如下两种方式(以坐标(291, 218)上的像素为例)。



4.1.3 修改像素的BGR值 
对于BGR色彩空间的图像,当每个像素的B、G、R的3个数值相等时,就可以得到灰 度图像。其中,B=G=R=0为纯黑色,B=G=R=255为纯白色。

4.2使用NumPy模块操作像素
图像在OpenCV中以二维或三维数组表示,数组中的每一个值就是图像的像素值。 善于操作数组的NumPy模块就成了OpenCV的依赖包。**OpenCV中很多操作都要依赖 NumPy模块,例如创建纯色图像、创建掩模和创建卷积核等。**本节将简单介绍NumPy 模块的常用操作方法,并演示如何利用NumPy模块创建图像。
4.2.1 NumPy概述
NumPy(见图4.9)更像是一个魔方(见图4.10),它是Python数组计算、矩阵运 算和科学计算的核心库,NumPy来源于Numerical和Python两个单词。NumPy提供了 一个高性能的数组对象,以及可以轻松创建一维数组、二维数组和多维数组等大量实用方 法,帮助开发者轻松地进行数组计算,从而广泛地应用于数据分析、机器学习、图像处理 和计算机图形学、数学任务等领域中。由于NumPy是由C语言实现的,所以其运算速度 非常快。具体功能如下。
1有一个强大的N维数组对象ndarray。
2广播功能方法。
3线性代数、傅里叶变换、随机数生成、图形操作等功能。
4整合C/C++/Fortran代码的工具。


4.2.2 数组的类型
在对数组进行基本操作前,首先了解一下NumPy的数据类型。NumPy比Python增 加了更多种类的数值类型,如表4.1所示,为了区别于Python数据类型,NumPy中的 bool、int、float、complex等数据类型名称末尾都加了短下画线"_"。
这里要注意,float_ 已经被叉出NumPy了,用的是float64替代
每一种数据类型都有相应的数据转换方法。举例如下:
4.2.3 创建数组
NumPy提供了很多创建数组的方法,下面分别介绍。
1.最常规的array()方法
NumPy创建简单的数组主要使用array()方法,通过传递列表、元组来创建NumPy 数组,其中的元素可以是任何对象,语法如下:
numpy.array(object, dtype, copy, order, subok, ndmin)
**object:**任何具有数组接口方法的对象。
**dtype:**数据类型。
**copy:**可选参数,布尔型,默认值为True,则object对象被复制;否则,只有 当__array__返回副本,object参数为嵌套序列,或者需要副本满足数据类型和 顺序要求时,才会生成副本。
**order:**元素在内存中的出现顺序,其值为K、A、C、F。如果object参数不是 数组,则新创建的数组将按行排列(C),如果值为F,则按列排列;如果 object参数是一个数组,则以下顺序成立:C(按行)、F(按列)、A(原顺 序)、K(元素在内存中的出现顺序)。
说明 :当order是' A ',object是一个既不是' C '也不是' F ' order的数组,并且由于 dtype的更改而强制执行了一个副本时,那么结果的顺序不一定是' C '。这可能是一个 bug。
**subok:**布尔型。如果值为True,则传递子类,否则返回的数组将强制为基类 数组(默认值)。
**ndmin:**指定生成数组的最小维数。
示例:创建一维和二维数组

示例: 创建浮点类型数组

示例: 创建三维数组

2.创建指定维度和数据类型未初始化的数组
创建指定维度和数据类型未初始化的数组主要使用empty()方法,数组元素因为未被 初始化会自动取随机值。如果要改变数组类型,可以使用dtype参数,如将数组类型设为 整型,dtype=int。
示例 : 创建2行3列的未初始化数组

3.创建用0填充的数组
创建用0填充的数组需要使用zeros()方法,该方法创建的数组元素均为0。OpenCV 经常使用该方法创建纯黑图像。
示例: 创建3行、3列、数字类型为无符号8位整数的纯0数组

4.创建用1填充的数组
创建用1填充的数组需要使用ones()方法,该方法创建的数组元素均为1。OpenCV 经常使用该方法创建纯掩模、卷积核等用于计算的二维数据。
示例: 创建3行、3列、数字类型为无符号8位整数的纯1数组

5.创建随机数组
randint()方法用于生成一定范围内的随机整数数组,左闭右开区间([low,high)), 语法如下:
numpy.random.randint(low,high,size)
**low:**随机数最小取值范围。
**high:**可选参数,随机数最大取值范围。若high为空,取值范围为(0, low)。
若high不为空,则high必须大于low。
**size:**可选参数,数组维数。
示例: 创建随机数组。

4.2.4 操作数组
不用编写循环即可对数据执行批量运算,这就是NumPy数组运算的特点,NumPy 称为矢量化。大小相等的数组之间的任何算术运算都可以用NumPy实现。本节主要介绍 如何复制数组和简单的数组运算。
1 加法运算
例如,加法运算是数组中对应位置的元素相加(即每行对应相加),如图4.12所 示。

例子 : 使用NumPy创建2个数组,并让2个数据进行加法运算

2.减法和乘除法运算 
示例 : 使用NumPy创建2个数组,并让2个数组进行减法、乘法和除法运算
方式与上一步一样,不再演示
3.幂运算
幂是数组中对应位置元素的幂运算,使用"**"运算符进行运算,效果如图4.14所示。从图中得出:数组n1的元素1和数组n2的元素3,通过幂运算得到的是1的3次幂; 数组n1的元素2和数组n2的元素4,通过幂运算得到的是2的4次幂。
4.比较运算
NumPy创建的数组可以使用逻辑运算符进行比较运算,运算的结果是布尔值数组, 数组中的布尔值为相比较的数组在相同位置元素的比较结果。
5.复制数组
NumPy提供的array()方法可以使用如下语法复制数据:
n2 = np.array(n1, copy=True)
但开发过程中更常用的是copy()方法,其语法如下:
n2 = n1.copy()
这两种方法都可以按照原数组的结构、类型、元素值创建出一个副本,修改副本中的 元素不会影响到原数组。
4.2.5 数组的索引和切片
NumPy数组元素是通过数组的索引和切片来访问和修改的,因此索引和切片是NumPy中最重要、最常用的操作。
1.索引
所谓数组的索引,即用于标记数组中对应元素的唯一数字,从0开始,即数组中的第 一个元素的索引是0,依次类推。NumPy数组可以使用标准Python语法x[obj]的语法对 数组进行索引,其中x是数组,obj是选择方式。
2.切片式索引
数组的切片可以理解为对数组的分割,按照等分或者不等分,将一个数组切割为多个 片段,与Python中列表的切片操作一样。NumPy中用冒号分隔切片参数来进行切片操作,语法如下:
start:stop:step
start:起始索引,若不写任何值,则表示从0开始的全部索引。
stop:终止索引,若不写任何值,则表示直到末尾的全部索引。
step:步长
例如,对数组n1进行一系列切片式索引操作的示意图如图4.15所示。

举例:按照图4.15所示的切片式索引操作获取数据中某范围的元素

切片式索引操作需要注意以下几点。
(1)索引是左闭右开区间,如上述代码中的n1[0:2],只能取到索引从0~1的元 素,而取不到索引为2的元素。
(2)当没有start参数时,代表从索引0开始取数,如上述代码中的n1[:2]。
(3)start、stop和step 3个参数都可以是负数,代表反向索引。以step参数为 例,如图4.16所示。

3.二维数组索引
二维数组索引可以使用array[n,m]的方式,以逗号分隔,表示第n个数组的第m个元 素。
4.二维数组切片式索引
注意 这里是[y, x ]形式
二维数组也支持切片式索引操作,如图4.18所示就是获取二维数组中某一块区域的 索引。
4.2.6 创建图像
在OpenCV中,黑白图像实际上就是一个二维数组,彩色图像是一个三维数组。数 组中每个元素就是图像对应位置的像素值。因此修改图像像素的操作实际上就是修改数组 的操作。本节将介绍几个在OpenCV中常用的操作。
1.创建黑白图像
在黑白图像中,像素值为0表示纯黑,像素值为255表示纯白。
示例 : 创建一个100行、200列(即宽200、高100)的数组,数组元素格式为无符号8位 整数,用0填充整个数组,将该数组当作图像显示出来

创建纯白图像有两种方式:第一种是先纯黑图像,然后将图像中所有的像素值改为 255;第二种使用NumPy提供的ones()方法创建一个像素值均为1的数组,然后让数组乘 以255。
示例: 创建一个100行、200列(即宽200、高100)的数组,数组元素格式为无符号8位 整数,用1填充整个数组,然后让数组乘以255,最后将该数组当作图像显示出来
示例 : 先绘制纯黑图像作为背景,然后使用切片式索引操作将图像中横坐标为50~100、纵 坐标为25~75的矩形区域颜色改为纯白色
示例:先绘制纯黑图像作为背景,然后在循环中使用切片式索引操作绘制黑白间隔图像
2.创建彩色图像
以上实例演示的都是用二维数组表示的黑白图像,而当显示生活中丰富多彩的颜色需 要引入光谱三基色的概念时,无法用二维数组表示,而要用到三维数组。OpenCV中彩色图像默认为BGR格式,彩色图像的第三个索引表示的就是蓝、绿、红3种颜色的分量。
示例 : 创建彩色图像数组时要将数组创建成三维数组,元素类型仍然为无符号8位整数

3 . 创建随机图像
随机图像是指图像中每一个像素值都是随机生成的,因为像素之间不会组成有效的视 觉信息,所以这样的图像看上去就像杂乱无章的沙子。虽然随机图像没有任何视觉信息, 但对于图像处理技术仍然很重要,毫无规律的像素数组被称为干扰图像的噪声,可以当作 图像加密的密钥。
示例:创建随机像素的雪花点图像。
使用NumPy提供的random.randint()方法就可以创建随机数组,将随机值的取值范 围设定在0~256(即像素值范围),元素类型设定为无符号8位整数
如果要彩色图像就size=(height, width, 3),dtype必须是uint8,因为这样范围是0-255
4.2.7 拼接图像
NumPy提供了两种拼接数组的方法,分别是hstack()方法和vstack()方法。这两种 拼接方法同样可用于拼接图像,下面分别介绍。
1.水平拼接数组
hstack()方法可以对数组进行水平拼接(或叫横向拼接),其语法如下:
array = numpy.hstack(tup)
tup:要拼接的数组元组。
array:将参数元组中的数组水平拼接后生成的新数组。
hstack()方法可以拼接多个数组,拼接效果如图4.28所示。被拼接的数组必须在每 一个维度都具有相同的长度,也就是数组"形状相同",例如2行2列的数组只能拼接2行 2列的数组,否则会出现错误。
示例 :创建3个一维数组,将这3个数组进行水平拼接
2.垂直拼接数组
vstack()方法可以对数组进行垂直拼接(或叫纵向拼接),其语法如下:
array = numpy.vstack(tup)
vstack()方法可以拼接多个数组,拼接效果如图4.29所示。被拼接的数组的格式要求 与hstack()方法相同。
例子: 创建3个一维数组,将这3个数组进行垂直拼接
3.在图像处理中的应用
在OpenCV中,图像就是一个二维或三维的像素数组,这些数组同样可以被NumPy 拼接,下面通过一个实例展示图像拼接的效果。
4.3 小结
本章详细讲解了像素和使用NumPy模块操作像素两个方面的内容。读者要注意掌握 以下几个内容:一是在表示图像某一个像素的坐标的时候,正确的表示方式是(垂直像 素,水平像素);二是在OpenCV中,彩色图像的通道顺序是B→G→R;三是重点掌握 且灵活运用NumPy模块实现图像的创建和图像的拼接。
第五章 色彩空间与通道
色彩是人类的眼睛对于不同频率的光线的不同感受,不同频率的光线既是客观存在的 又是人类主观感知的。为了表示这些不同频率的光线的色彩,人类建立了多种色彩模型, 把这些色彩模型称作色彩空间。OpenCV中的BGR色彩空间有3个通道,即表示蓝色的B 通道、表示绿色的G通道和表示红色的R通道。本章将具体讲解色彩空间和通道,以及二 者之间的紧密联系。
5.1色彩空间
虽然Photoshop把一幅彩色图像的色彩空间默认为RGB色彩空间,但是OpenCV把 一幅彩色图像的色彩空间默认为BGR色彩空间,这是因为OpenCV拆分一幅彩色图像的 通道后,默认的通道顺序是B→G→R。熟悉了BGR色彩空间后,本节将结合如图5.1所 示的图像,介绍另外两个比较常见的色彩空间:GRAY色彩空 间和HSV色彩空间。
5.1.1 GRAY色彩空间
GRAY色彩空间通常指的是灰度图像,灰度图像是一种每个像素都是从黑到白,被处 理为256个灰度级别的单色图像。这256个灰度级别分别用区间[0, 255]中的数值表示。 其中,"0"表示纯黑色,"255"表示纯白色,0~255的数值表示不同亮度(即色彩的 深浅程度)的深灰色或者浅灰色。因此,一幅灰度图像也能够展现丰富的细节信息
2.从BGR色彩空间转换到GRAY色彩空间
两种图像都是同一幅图,只不过,图5.1是彩色图 像,而图5.2是灰度图像。OpenCV能够将同一幅图像从一个色彩空间转换到另一个色彩 空间。例如,图5.1从BGR色彩空间转换到图5.2所示的GRAY色彩空间。
那么,OpenCV是如何实现从BGR色彩空间转换到GRAY色彩空间的呢?答案就是 OpenCV中用于转换图像色彩空间的cvtColor()方法
dst = cv2.cvtColor(src, code)
**dst:**转换后的图像。
**src:**转换前的初始图像。
code:色彩空间转换码。
注意:当图像从BGR色彩空间转换到GRAY色彩空间时,常用的色彩空间转换码是 cv2.COLOR_BGR2GRAY。
例子 : 从BGR色彩空间转换到GRAY色彩空间。

说明 : 虽然色彩空间类型转换是双向的,而且OpenCV也提供了cv2.COLOR_GRAY2BGR(从 GRAY色彩空间转换到BGR色彩空间)和cv2.COLOR_ BGR2GRAY(从BGR色彩空间转换到 GRAY色彩空间)2个色彩空间转换码,但是灰度图像是无法转换成彩色图像的。这是因 为在彩色图像转换成灰度图像的过程中,丢失了颜色比例(即红色、绿色和蓝色之间的 混合比例)。这些比例一旦丢失,就再也找不回来了。
5.1.2 HSV色彩空间
1.什么是HSV色彩空间
BGR色彩空间是基于三基色而言的,三基色指的是红色、绿色和蓝色。而HSV色彩空间则是基于色调、饱和度和亮度而言的。
其中,色调(H)是指光的颜色,例如,彩虹中的赤、橙、黄、绿、青、蓝、紫分别 表示不同的色调,如图5.4所示。在OpenCV中,色调在区间[0, 180]内取值。例如,代 表红色、黄色、绿色和蓝色的色调值分别为0、30、60和120。
饱和度(S)是指色彩的深浅。在OpenCV中,饱和度在区间[0, 255]内取值。当饱 和度为0时,图像将变为灰度图像。
如图所示,亮度(V)是指光的明暗。与饱和度相同,在OpenCV中,亮度在区 间[0, 255]内取值。亮度值越大,图像越亮;当亮度值为0时,图像呈纯黑色。
2.从BGR色彩空间转换到HSV色彩空间
OpenCV提供的cvtColor()方法不仅能将图像从BGR色彩空间转换到GRAY色彩空 间,还能将图像从BGR色彩空间转换到HSV色彩空间。当图像在BGR色彩空间和HSV色 彩空间之间转换时,常用的色彩空间转换码是cv2.COLOR_BGR2HSV和cv2.COLOR_HSV2BGR。
示例: 从BGR色彩空间转换到HSV色彩空间。
5.2通道
在BGR色彩空间中,图像的通道由B通道、G通道和R通道构成。本节将介绍如何使 用OpenCV提供的方法拆分和合并通道。
5.2.1 拆分通道
为了拆分图像中的通道,OpenCV提供了split()方法。
1.拆分一幅BGR图像中的通道
当使用split()方法拆分一幅BGR图像中的通道时,split()方法的语法如下:
b, g, r = cv2.split(bgr_image)
b:B通道图像。
g:G通道图像。
r:R通道图像。
bgr_image:一幅BGR图像。
例子: 拆分一幅BGR图像中的通道。


R通道是红色通道,G通道是绿色通道,B通道是蓝色通道。
但是图中的B通道图 像、G通道图像和R通道图像是3幅不同亮度的灰度图像,这是为什么呢?
原因是当程序执行到cv2.imshow("B", b)时,原图像B、G、R这3个通道的值都会被 修改为B通道图像的值,即(b, b, b)。同理,当程序执行到cv2.imshow("G", g)和 cv2.imshow("R", r)时,原图像R、G、B这3个通道的值将依次被修改为G通道图像的值(g, g, g)和R通道图像的值(r, r, r)。对于BGR图像,只要B、G、R这3个通道的值都相 同,就可以得到灰度图像。
2.拆分一幅HSV图像中的通道
当使用split()方法拆分一幅HSV图像中的通道时,split()方法的语法如下:
h, s, v = cv2.split(hsv_image)
h:H通道图像。
s:S通道图像。
v:V通道图像。
hsv_image:一幅HSV图像。
示例: 拆分一幅HSV图像中的通道。
5.2.2 合并通道
合并通道是拆分通道的逆过程。以图5.1为例,虽然拆分通道后,会得到3幅不同亮 度的灰度图像;但是将这3幅不同亮度的灰度图像合并后,又重新得到图5.1。下面将使用OpenCV中用于合并通道的merge()方法,验证一下上述说法。
1.合并B通道图像、G通道图像和R通道图像
当使用merge()方法按B→G→R的顺序合并通道时,merge()方法的语法如下:
bgr = cv2.merge([b, g, r])
bgr:按B→G→R的顺序合并通道后得到的图像。
b:B通道图像。
g:G通道图像。
r:R通道图像。
示例: 合并B通道图像、G通道图像和R通道图像。
2.合并H通道图像、S通道图像和V通道图像
当使用merge()方法合并H通道图像、S通道图像和V通道图像时,merge()方法的语 法如下:
hsv = cv2.merge([h, s, v])
hsv:合并H通道图像、S通道图像和V通道图像后得到的图像。
h:H通道图像。
s:S通道图像。
v:V通道图像。
示例: 合并H通道图像、S通道图像和V通道图像。

5.2.3 综合运用拆分通道和合并通道
在HSV色彩空间内,如果保持其中两个通道的值不变,调整第3个通道的值,会得到 相应的艺术效果。
示例: 只把H通道的值调整为180。

同理,H通道,S通道,V通道都可以改变
5.2.4 alpha通道
BGR色彩空间包含了3个通道,即B通道、G通道和R通道。OpenCV在BGR色彩空 间的基础上,又增加了一个用于设置图像透明度的A通道,即alpha通道。这样,形成一 个由B通道、G通道、R通道和A通道4个通道构成的色彩空间,即BGRA色彩空间。在BGRA色彩空间中,alpha通道在区间[0, 255]内取值;其中,0表示透明,255表示不透 明。
示例: 调整A通道的值。

虽然在代码中已经调整了BGRA图像中A通道的值,但是显示图像的效果是一样的。 为了显示3幅图像的不同效果,需要使用imwrite()方法将3幅图像保存在D盘根目录下, 代码如下:
说明 : PNG图像是一种典型的4通道(即B通道、G通道、R通道和A通道)图像,因此被保存 的3幅图像的格式均为.png。
那么就可以理解了,为什么显示的时候三张图片是一样的了,显示默认是jpg显示,没有a通道,保存下来再去查看就可以里
5.3小结
当使用cvtColor()方法转换色彩空间时,虽然彩色图像能够转换为灰度图像,但是灰 度图像不能转换为彩色图像。对于HSV色彩空间,如果保持其中两个通道的值不变,调 整第3个通道的值,会得到相应的艺术效果。为了能够显示艺术效果,要把合并通道后的 图像从HSV色彩空间转换到BGR色彩空间。当使用alpha通道设置图像的透明度时,为 了能够直观地看到图像的透明效果,需先保存已经设置透明度的图像。




