Python_OpenCV入门到精通——入门篇(看这一篇就足够了!!!) - 实践

此文章一共分为四篇

第一篇 入门篇(本篇)

第二篇 基础篇

第三篇 进阶篇

第四篇 项目篇

在这篇系列文章中,我将带你从“完全小白”一路打怪升级到能动手做真实任务
不堆术语、不讲空话,只用你能跑通的代码 + 能看懂的图解 + 踩过的坑总结
手把手拆解 OpenCV 的核心逻辑。点个关注不迷路!!!

目录

第一章 Python 和OpenCV

OpenCV包含的模块

第二章 搭建构建环境

第三章 图像处理的基本操作

3.1读取图像

3.2显示图像

3.3保存图像

3.4获取图像属性

3.5小结

第四章 像素的操作

4.1像素

4.2使用NumPy模块运行像素

第五章 色彩空间与通道

5.1色彩空间

5.2通道

5.3 小结


第一章 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)。

如何获取指定位置上的像素的B通道、G通道和R通道的值呢?就是从上文能够知晓,在BGR色彩空间的图像中,每3个数值表示一个像素,这3个数值 分别表示蓝色、绿色和红色3种颜色分量,把每一种颜色分量所在的区域称作通道。那 么,OpenCV

有如下两种方式(以坐标(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色彩空间

从黑到白,被处 理为256个灰度级别的单色图像。这256个灰度级别分别用区间[0, 255]中的数值表示。 其中,“0”表示纯黑色,“255”表示纯白色,0~255的数值表示不同亮度(即色彩的 深浅程度)的深灰色或者浅灰色。因此,一幅灰度图像也能够展现丰富的细节信息就是GRAY色彩空间通常指的是灰度图像,灰度图像是一种每个像素都

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色彩空间则是基于色调、饱和度和亮度而言的。

指光的颜色,例如,彩虹中的赤、橙、黄、绿、青、蓝、紫分别 表示不同的色调,如图5.4所示。在OpenCV中,色调在区间[0, 180]内取值。例如,代 表红色、黄色、绿色和蓝色的色调值分别为0、30、60和120。就是其中,色调(H)

饱和度(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通道设置图像的透明度时,为 了能够直观地看到图像的透明效果,需先保存已经设置透明度的图像。

posted @ 2025-12-27 15:26  clnchanpin  阅读(50)  评论(0)    收藏  举报