「这是我参与2022首次更文挑战的第7天,活动详情查看:2022首次更文挑战」
前言
OpenCV 作为计算机视觉库,其中一项基本功能就是绘制图形,在构建计算机视觉项目时,通常希望通过绘制一些图形来显式的标注图像。例如,在人脸检测算法中,会通过绘制一个矩形,突出显示计算图像中检测到的人脸。此外,如果开发人脸识别算法,除了绘制一个矩形突出显示检测到的人脸外,通常还会绘制文本标识检测到的人脸的身份等,本文将介绍 OpenCV 绘图基础。
OpenCV 绘图基础
OpenCV 提供了许多绘制基本图形的函数,包括直线、矩形和圆形等;除此之外,使用 OpenCV,也可以绘制其它更多的基本图形。图像上绘制基本形状有许多实用的场景,常见的用例主要包括:
- 显示算法的一些中间结果
- 显示算法的最终结果
- 显示一些调试信息
在下图中,可以看到一张绘制有矩形检测框的图像,其中实用矩形来显式的标示检测到的人脸图片(人脸检测),文本信息用于显示算法输出的其它相关的有用信息。通过这种方式,可以查看算法检测到面孔的位置:
本文中,我们将学习如何绘制具有不同颜色的基本图形和文本。为了达到这一目的,首先简要介绍下不同颜色的构建方式。我们可以构建颜色字典,使用颜色字典定义要使用的主要颜色。下表中列示了本文可能用到的颜色及其色值:
| 颜色名 | 颜色值 | 颜色名 | 颜色值 |
|---|---|---|---|
| blue | (255, 0, 0) | black | (0, 0, 0) |
| green | (0, 255, 0) | white | (255, 255, 255) |
| red | (0, 0, 255) | gray | (125, 125, 125) |
| cyan | (255, 255, 0) | dark_gray | (50, 50, 50) |
| magenta | (255, 0, 255) | light_gray | (220, 220, 220) |
| yellow | (0, 255, 255) |
由上表可以构建颜色字典如下:
colors = {'blue': (255, 0, 0), 'green': (0, 255, 0), 'red': (0, 0, 255), 'cyan': (255, 255, 0), 'magenta': (255, 0, 255), 'yellow': (0, 255, 255), 'black': (0, 0, 0), 'white': (255, 255, 255), 'gray': (125, 125, 125), 'dark_gray': (50, 50, 50), 'light_gray': (220, 220, 220), 'rand': np.random.randint(0, high=256, size=(3,)).tolist()}
以上字典中定义了一些预定义的颜色,如果要使用特定颜色,例如红色 (red):
colors['red']
或者,可以使用 (0, 0, 255) 来得到红色。但是使用这个字典,不需要记住 RGB 颜色空间的色值,比数字三元组更容易使用。
除了使用字典外,另一种常见的方法是创建一个 colors_constant.py 文件来定义颜色。其中,每种颜色都由一个常量定义:
BLUE = (255, 0, 0)
GREEN = (0, 255, 0)
RED = (0, 0, 255)
YELLOW = (0, 255, 255)
MAGENTA = (255, 0, 255)
CYAN = (255, 255, 0)
LIGHT_GRAY = (220, 220, 220)
DARK_GRAY = (50, 50, 50)
在项目目录的其他文件中,可以使用以下代码使能够引用这些常量:
import colors_constant as colors
print("red: {}".format(colors.RED))
此外,由于我们使用 Matplotlib 显示图形,因此我们需要通用函数 show_with_matplotlib(),其带有两个参数的,第一个是要显示的图像,第二个是要图形窗口的标题。因为必须使用 Matplotlib 显示彩色图像,因此首先需要将 BGR 图像转换为 RGB。此函数的第二步也是最后一步是使用 Matplotlib 函数显示图像:
def show_with_matplotlib(img, title):
# 将 BGR 图像转换为 RGB
img_RGB = img[:, :, ::-1]
# 使用 Matplotlib 显示图形
plt.imshow(img_RGB)
plt.title(title)
plt.show()
为了演示 colors 常量和 show_with_matplotlib() 函数的使用,创建 testing.py 脚本进行测试:
import cv2
import numpy as np
import matplotlib.pyplot as plt
def show_with_matplotlib(img, title):
# 将 BGR 图像转换为 RGB
img_RGB = img[:, :, ::-1]
# 使用 Matplotlib 显示图形
plt.imshow(img_RGB)
plt.title(title)
plt.show()
# 定义颜色字典:
colors = {'blue': (255, 0, 0), 'green': (0, 255, 0), 'red': (0, 0, 255), 'yellow': (0, 255, 255),
'magenta': (255, 0, 255), 'cyan': (255, 255, 0), 'white': (255, 255, 255), 'black': (0, 0, 0),
'gray': (125, 125, 125), 'rand': np.random.randint(0, high=256, size=(3,)).tolist(),
'dark_gray': (50, 50, 50), 'light_gray': (220, 220, 220)}
# 创建画布
image = np.zeros((500, 500, 3), dtype="uint8")
# 修改画布背景颜色
image[:] = colors['rand']
# 利用 colors 字典绘制直线
separation = 40
for key in colors:
cv2.line(image, (0, separation), (500, separation), colors[key], 15)
separation += 40
# 显示图形
show_with_matplotlib(image, 'Dictionary with some predefined colors')
在上例中,创建了一个大小为 500 x 500的图像,具有 3 个通道(彩色图像),数据类型为 uint8 (8 位无符号整数),原始背景为黑色:
image = np.zeros((500, 500, 3), dtype="uint8")
如果,希望将背景颜色,例如将背景颜色修改为随机色 rand,则执行以下操作:
image[:] = colors['rand']
接下来,使用 cv2.line() 函数(这里仅作示例使用,有关此函数具体使用方式,将在下节进行详细介绍)绘制一些直线,每条线条都使用 colors 字典填充颜色。
separation = 40
for key in colors:
cv2.line(image, (0, separation), (500, separation), colors[key], 10)
separation += 40
最后,使用创建的 show_with_matplotlib() 函数绘制图像:
show_with_matplotlib(image, 'Dictionary with some predefined colors')