第 1 章

图像的读取、显示与保存

本章共 5 个小节 · OpenCV 入门基础
OpenCV 的全名是 Open Source Computer Vision Library,这一章将从 OpenCV 最基础的认识图像说起。本章将讲解下列知识:
  1. 读取图像
  2. 显示图像
  3. 保存图像
  4. 认识图像的属性
1-0

建议阅读书籍

这本书主要是讲解使用 Python 搭配 OpenCV 模块,完整讲解图像处理至 AI 视觉的知识,建议读者要有 Python 基础知识。同时 OpenCV 是使用 Numpy 模块的数组概念处理图像的文件,所以也建议要有 Numpy 的基础知识。

1-1

程序导入 OpenCV 模块

在使用 OpenCV 前,需要安装 OpenCV,读者可以参考附录 A。设计程序前需要使用下列方式导入 OpenCV 模块。

import cv2
1-2

读取图像文件

1-2-1 图像读取 imread() 的语法

OpenCV 读取图像文件是使用 imread() 函数,此函数的语法如下:

image = cv2.imread(path, flag)     # 返回的 image 是图像对象
命名常量 说明
IMREAD_UNCHANGED -1 依原图像读取图像,保留 alpha 透明度通道
IMREAD_GRAYSCALE 0 将图像转为灰度再读取
IMREAD_COLOR 1 将图像转为三通道 BGR 彩色再读取
IMREAD_ANYDEPTH 2 当图像有 16 位或 32 位时,返回相对应深度的图像。否则,将图像转为 8 位
IMREAD_ANYCOLOR 4 以所有可能的颜色读取图像
IMREAD_LOAD_GDAL 8 使用 GDAL 驱动程序读取图像
IMREAD_REDUCED_GRAYSCALE_2 16 将图像转为灰度,同时缩小至原先的 1/2
IMREAD_REDUCED_COLOR_2 17 将图像转为三通道 BGR 彩色,同时缩小至原先的 1/2
IMREAD_IGNORE_ORIENTATION 128 不以 EXIF 方向旋转图像
引用上述常量时左边需要加上 cv2,例如:cv2.IMREAD_GRAYSCALE

程序示例 ch1_1.py:观察读取文件的返回值

1# ch1_1.py 2import cv2 3 4img1 = cv2.imread("jk.jpg") # 读取图像 5print(f"成功读取 : {type(img1)}") 6img2 = cv2.imread("none.jpg") # 读取图像 7print(f"读取失败 : {type(img2)}")
执行结果
成功读取 : <class 'numpy.ndarray'>
读取失败 : <class 'NoneType'>

1-2-2 可读取的图像格式

OpenCV 的 cv2.imread() 可以读取的常见图像格式有下列几种:

1-3

显示图像与关闭图像窗口

OpenCV 有提供几个与显示图像有关的函数,下列将一一解说。

1-3-1 使用 OpenCV 显示图像

OpenCV 可以使用 cv2.imshow() 将读取的图像对象显示在 OpenCV 窗口内,此函数的使用格式如下:

cv2.imshow(window_name, image)

上述 imshow() 函数实际上是执行下列 2 个步骤:

  1. 创建标题是 window_name 的窗口,所创建的窗口无法更改大小。
  2. 将 image 图像对象在 window_name 窗口显示。

程序示例 ch1_2.py:显示图像

1# ch1_2.py 2import cv2 3 4img = cv2.imread("jk.jpg") # 读取图像 5cv2.imshow("MyPicture", img) # 显示图像
执行结果
ch1_2.py 执行结果
运行后打开的 MyPicture 窗口,显示 jk.jpg 图像。按右上方的关闭钮可关闭窗口。

1-3-2 关闭 OpenCV 窗口

将图像显示在 OpenCV 窗口后,若是想删除窗口可以使用下列函数。

cv2.destroyWindow(window_name)     # 删除单一所指定的窗口 cv2.destroyAllWindows()            # 删除所有 OpenCV 的图像窗口

程序示例 ch1_3.py:图像闪一下随即关闭的应用

1# ch1_3.py 2import cv2 3 4img = cv2.imread("jk.jpg") # 读取图像 5cv2.imshow("MyPicture", img) # 显示图像 6cv2.destroyWindow("MyPicture") # 关闭窗口
执行结果
图像闪一下随即关闭。上述第 5 行显示图像,第 6 行是关闭图像,所以造成图像闪一下随即关闭。

1-3-3 等待按键的事件

OpenCV 的 cv2.waitKey() 函数会等待按键事件,语法如下:

ret_key = cv2.waitKey(delay)

使用 OpenCV 显示图像时可以使用 cv2.waitKey(delay) 设置图像显示的时间,或是在显示时间内按键盘的任意键,也可以让 cv2.waitKey() 函数执行结束。若是 delay=0 或是省略,代表无限期等待。若是设为 delay=1000 相当于有等待 1 秒的效果。

程序示例 ch1_4.py:让图像持续显示,直到按下右上方的关闭钮

1# ch1_4.py 2import cv2 3 4img = cv2.imread("jk.jpg") # 读取图像 5cv2.imshow("MyPicture", img) # 显示图像 6ret_value = cv2.waitKey(0) # 无限等待 7cv2.destroyWindow("MyPicture") # 关闭窗口

程序示例 ch1_5.py:让图像显示 5 秒或是有键盘按键发生

1# ch1_5.py 2import cv2 3 4img = cv2.imread("jk.jpg") # 读取图像 5cv2.imshow("MyPicture", img) # 显示图像 6ret_value = cv2.waitKey(5000) # 等待 5 秒 7cv2.destroyWindow("MyPicture") # 关闭窗口 8print(f"ret_value = {ret_value}")
执行结果
等待 5 秒没有按键发生:ret_value = -1
直接按键盘 e 的结果:ret_value = 101
ch1_5.py Python Shell 执行结果
左图为等待 5 秒无按键的结果 ret_value = -1;右图为直接按 e 键的结果 ret_value = 101(e 的 ASCII 码)。截图见原书第 1-6 页。
注意
输入法切换说明
按键检测前建议将输入法切换至英文 (ENG),否则 ret_value 值可能会对应到中文输入法状态。

如果输入是一般键盘键,可以使用 ret_value == ord(key) 判断是否是按了特定的键盘字符。

程序示例 ch1_5_1.py:让图像持续显示,直到按下键盘的 q 或 Q 键

1# ch1_5_1.py 2import cv2 3 4img = cv2.imread("jk.jpg") # 读取图像 5cv2.imshow("MyPicture", img) # 显示图像 6ret_value = cv2.waitKey(0) # 无限等待 7if ret_value == ord('Q') or ret_value == ord('q'): 8 cv2.destroyWindow("MyPicture") # 关闭窗口

1-3-4 创建 OpenCV 图像窗口

使用 OpenCV 的 imshow() 函数显示图像时,默认系统会创建一个图像窗口,这个默认所创建的图像窗口,窗口大小是固定,无法更改。不过 OpenCV 也有提供 namedWindow() 创建未来要显示图像的窗口,它的语法如下:

cv2.namedWindow(window_name, flag)

程序示例 ch1_6.py:以彩色和灰度显示图像的应用

1# ch1_6.py 2import cv2 3cv2.namedWindow("MyPicture1") # 使用默认 4cv2.namedWindow("MyPicture2", cv2.WINDOW_NORMAL) # 可以调整大小 5img1 = cv2.imread("jk.jpg") # 彩色读取 6img2 = cv2.imread("jk.jpg", cv2.IMREAD_GRAYSCALE) # 灰色读取 7cv2.imshow("MyPicture1", img1) # 显示图像 img1 8cv2.imshow("MyPicture2", img2) # 显示图像 img2 9cv2.waitKey(3000) # 等待 3 秒 10cv2.destroyWindow("MyPicture1") # 删除 MyPicture1 11cv2.waitKey(8000) # 等待 8 秒 12cv2.destroyAllWindows() # 删除所有窗口
执行结果
ch1_6.py 执行结果
同时显示两个窗口:左侧 MyPicture1 为彩色(默认大小,不可调整),右侧 MyPicture2 为灰度(WINDOW_NORMAL,可调整大小)。

上述程序第 6 行,cv2.IMREAD_GRAYSCALE 也可以使用 0 代替,读者可以参考 ch1_6_1.py,可以获得一样的结果。

img2 = cv2.imread("jk.jpg", 0)     # 灰色读取
1-4

保存图像

OpenCV 可以使用 imwrite() 保存图像,它的使用语法如下:

ret = cv2.imwrite(path, image)

如果保存图像成功会返回 True,否则返回 False

程序示例 ch1_7.py:将 jk.jpg 保存成 out1_7_1.tiff 和 out1_7_2.png

1# ch1_7.py 2import cv2 3cv2.namedWindow("MyPicture") # 使用默认 4img = cv2.imread("jk.jpg") # 彩色读取 5cv2.imshow("MyPicture", img) # 显示图像 img 6ret = cv2.imwrite("out1_7_1.tiff", img) # 将文件写入 out1_7_1.tiff 7if ret: 8 print("保存文件成功") 9else: 10 print("保存文件失败") 11ret = cv2.imwrite("out1_7_2.png", img) # 将文件写入 out1_7_2.png 12if ret: 13 print("保存文件成功") 14else: 15 print("保存文件失败") 16cv2.waitKey(3000) # 等待 3 秒 17cv2.destroyAllWindows() # 删除所有窗口
执行结果
保存文件成功
保存文件成功
ch1_7.py 执行结果
运行后在 ch1 文件夹可以看到新产生的 out1_7_1.tiff 和 out1_7_2.png 两个图像文件。
习题

1:分别以彩色和灰度读取自己的图像,在屏幕显示,同时以下列方式保存。

  • jk_color.bmp 文件名称:彩色保存。
  • jk_gray.bmp 文件名称:灰度保存。
习题参考效果
参考效果:左侧 Color 彩色窗口,右侧 Gray 灰度窗口。截图见原书第 1-10 页。