【精选优质专栏推荐】
- 《AI 技术前沿》 —— 紧跟 AI 最新趋势与应用
- 《网络安全新手快速入门(附漏洞挖掘案例)》 —— 零基础安全入门必看
- 《BurpSuite 入门教程(附实战图文)》 —— 渗透测试必备工具详解
- 《网安渗透工具使用教程(全)》 —— 一站式工具手册
- 《CTF 新手入门实战教程》 —— 从题目讲解到实战技巧
- 《前后端项目开发(新手必知必会)》 —— 实战驱动快速上手
每个专栏均配有案例与图文讲解,循序渐进,适合新手与进阶学习者,欢迎订阅。

前言
在处理图像时,一些最基本的操作包括从磁盘读取图像、显示图像、访问像素值,以及将图像从一种颜色空间转换到另一种颜色空间,这些都是掌握图像处理的基础。
本教程将解释这些基本操作,并首先描述数字图像是如何通过空间坐标和像素强度值来构成的。
在本教程中,你将熟悉在处理图像时使用 OpenCV 的最基础操作。
完成本教程后,你将学会:
-
数字图像如何通过空间坐标和像素强度值来构成。
-
如何在 OpenCV 中读取和显示图像。
-
如何访问图像的像素值。
-
如何将图像从一种颜色空间转换为另一种颜色空间。
本教程分为三部分:
-
图像的构成
-
在 OpenCV 中读取和显示图像
-
颜色空间之间的转换
图像的构成
数字图像由像素组成,每个像素由其在图像空间内的空间坐标和强度值(灰度值)描述。
本质上,一幅图像可以用二维函数 I(x, y) 描述,其中 x 和 y 表示空间坐标,I(x, y) 的值表示该像素的强度。在数字图像中,空间坐标和强度值都是有限的离散量。
我们刚描述的图像类型称为灰度图像,因为它只包含单通道,每个像素仅包含强度信息。像素强度通常用整数表示,范围为 [0, 255],即每个像素有 256 个离散值。
另一方面,RGB 图像由三个通道组成,分别为红色(Red)、绿色(Green)和蓝色(Blue)。
RGB 颜色模型不是唯一的颜色模型,但它在计算机视觉应用中可能是最常用的。它是一种加色模型,通过混合不同颜色光源的光谱来创建颜色。
由于 RGB 图像由三个通道组成,我们需要三个函数来描述它:IR(x, y)、IG(x, y)、IB(x, y),分别对应红、绿、蓝三个通道。因此,在 RGB 图像中,每个像素值由三个强度值组成的三元组表示。
在 OpenCV 中读取和显示图像
首先从 Python 的 OpenCV 库中导入 imread 方法:
from cv2 import imread
然后读取一幅 RGB 图像。例如,我下载了一张图片,并将其保存为 ‘Images/Dog.jpg’。
img = imread('Images/Dog.jpg')
imread 方法返回一个 NumPy 数组 img,其中包含图像像素值。可以检查数组的数据类型和维度:
print('Datatype:', img.dtype, '\nDimensions:', img.shape)
输出结果示例:
Datatype: uint8
Dimensions: (4000, 6000, 3)
该信息说明数组的数据类型为 uint8(8 位无符号整数),每个通道的像素值在 0 到 255 之间,正好符合前面介绍的图像构成。数组的维度为 4000 × 6000 × 3,分别对应图像的行数、列数和通道数。
图像是一个三维 NumPy 数组,因此可以使用 NumPy 语法对其进行操作。
例如,访问图像左上角的第一个像素(Python 中数组索引从 0 开始,对应坐标为 (0, 0)):
print(img[0, 0])
输出示例:
[173 186 232]
如预期,每个像素包含三个值,分别对应 RGB 三个通道。下一节将解释这三个值分别对应哪个通道。
注意:如果 imread 方法未能加载图像(例如文件不存在或路径无效),它不会报错,而是返回 None 类型对象。因此,在使用 img 之前可进行如下检查:
if img is not None:
...
接下来,我们使用 Matplotlib 包以及 OpenCV 的 imshow 方法显示图像。imshow 方法的第一个参数是窗口名称,第二个参数是要显示的图像。显示图像后,可以调用 OpenCV 的 waitKey 方法等待键盘事件,单位为毫秒。如果输入值为 0,则无限等待,直到检测到键盘事件。
使用 Matplotlib 显示图像示例:
import matplotlib.pyplot as plt
plt.imshow(img)
plt.title('Displaying image using Matplotlib')
plt.show()

使用 OpenCV:
from cv2 import imshow, waitKey
imshow('Displaying image using OpenCV', img)
waitKey(0)

如果你对 Matplotlib 显示的输出感到惊讶,并想知道这是怎么发生的,其原因在于 OpenCV 读取和显示图像时使用的是 BGR 而不是 RGB 顺序。
OpenCV 的早期开发者选择 BGR 颜色格式(而非 RGB),是因为当时 BGR 颜色格式在软件提供商和摄像头厂商中非常流行。
——《Mastering OpenCV 4 with Python, 2019》
而 Matplotlib 使用的是 RGB 颜色格式,因此在显示之前,需要先将 BGR 图像转换为 RGB 格式,才能正确显示。
使用 OpenCV,你也可以将 NumPy 数组写入图像文件,例如:
from cv2 import imwrite
imwrite("output.jpg", img)
使用 imwrite() 函数写入图像时,需要确保 NumPy 数组符合 OpenCV 期望的格式,即一个三维的 uint8 数组,形状为 行 × 列 × 通道,通道顺序为 BGR。
颜色空间转换
将图像从一种颜色空间转换到另一种颜色空间,可以使用 OpenCV 的 cvtColor 方法。该方法需要传入源图像和颜色空间转换代码。
例如,在 BGR 和 RGB 之间转换,可以使用以下代码:
from cv2 import cvtColor, COLOR_BGR2RGB
img_rgb = cvtColor(img, COLOR_BGR2RGB)
如果再次使用 Matplotlib 显示图像,现在它将正确显示:
plt.imshow(img_rgb)
plt.show()

如果我们想访问新转换为 RGB 图像的左上角第一个像素的值:
print(img_rgb[0, 0])
输出示例:
[232 186 173]
将其与之前 BGR 图像的值 [173 186 232] 进行比较,可以发现第一个值和第三个值交换了位置。这说明,像素值的顺序对应于图像通道的顺序。
使用 cvtColor 方法不仅可以实现 BGR 到 RGB 的转换。实际上,还有很多颜色空间转换代码可供选择,例如 COLOR_RGB2HSV,可以在 RGB 和 HSV(色调、饱和度、亮度)颜色空间之间进行转换。
另一种常见的转换是从 RGB 转为灰度图像,如前面提到的,输出将是单通道图像。示例代码如下:
from cv2 import COLOR_RGB2GRAY, cvtColor, imshow, waitKey
img_gray = cvtColor(img_rgb, COLOR_RGB2GRAY)
imshow('Grayscale Image', img_gray)
waitKey(0)

灰度转换已经成功完成,但我们也可以尝试访问左上角第一个像素(坐标 (0, 0))的值:
print(img_gray[0, 0])
输出示例:
198
如预期,仅打印出了一个数字,对应该像素的强度值。
值得注意的是,这并不是将图像转换为灰度图的唯一方法。实际上,如果应用只需要灰度图像而非 RGB 图像,也可以在读取图像时直接以灰度方式读取:
from cv2 import IMREAD_GRAYSCALE, imread, imshow, waitKey
img_gray = imread('Images/Dog.jpg', IMREAD_GRAYSCALE)
imshow('Grayscale Image', img_gray)
waitKey(0)
注意:OpenCV 文档指出,使用 IMREAD_GRAYSCALE 时,如果可用,会利用编码器的内部灰度转换,这可能导致输出与 cvtColor() 不完全一致。
imread 方法还支持其他几个标志值,其中两个是 IMREAD_COLOR 和 IMREAD_UNCHANGED。
-
IMREAD_COLOR 是默认选项,会将图像转换为 BGR 彩色图像,并忽略任何透明度信息。
-
IMREAD_UNCHANGED 会读取可能包含 alpha 通道的图像。
总结
在本教程中,你已经熟悉了处理图像时使用 OpenCV 的最基础操作。
具体来说,你学会了:
-
数字图像如何通过空间坐标和像素强度值来构成。
-
如何在 OpenCV 中读取和显示图像。
-
如何访问图像的像素值。
-
如何将图像从一种颜色空间转换为另一种颜色空间。
899



被折叠的 条评论
为什么被折叠?



