OpenCV 是计算机视觉领域一个非常强大的第三方库,全称 Open Source Computer Vision Library。OpenCV 不仅提供了对图像的基本操作的 API,也提供了一些经典的计算机视觉算法。常用于解决计算机视觉,图像处理和模式识别等方面的问题。关于 OpenCV 的详细介绍,这里不赘述,有兴趣请参考 OpenCV Wikipedia 或者 OpenCV 主页

  OpenCV 使用 C 语言高速地实现了许多图像处理和计算机视觉方面的通用算法,并且通过 SWIG 提供了 Python 的调用接口。OpenCV 提供的 Python 调用接口和 C 语言的 API 基本上是一致的,这个接口对于动态语言 Python 来说有些累赘。不过由于 Python 程序和 C 语言程序差别不大,用 Python 调用 OpenCV,能够帮助我们测试 API 函数和快速实现算法。

  接下来就开始从简单的图像读取、显示、创建(复制)和写入等操作来逐步了解 OpenCV for Python。

0x00.导入模块

首先导入 OpenCV for Python 的模块 cv2:

1
import cv2

由于 OpenCV for Python 是和 Numpy 绑定在一起的,很多时候可以直接使用 Numpy 的 API 来操作图像,所以这里也导入 Numpy 模块:

1
import numpy as np

至于代码中涉及的 matplotlib,目前只用于图像显示,可以忽略 :)

0x01.读取图像

读取图像非常简单:

1
cv2.imread(filename[, flags])

支持常见的图像格式,并且可以通过 flags 参数指定读取图像的颜色类型(Color or Gray)。通过 type(img) 可以看到,读取出来的图像是一个 Numpy 数组:

1
<type 'numpy.ndarray'>

所以可以使用 Numpy 的 API 来处理图像。

0x02.显示图像

新建一个窗口:

1
cv2.namedWindow(winname[, flags])

然后在这个窗口中显示图像,或者直接显示图像而不显式创建窗口。前者可以通过 flags 参数设置窗口的一些属性,比如当图片过大屏幕显示不下,使用 cv2.WINDOW_NORMAL 可以让图片正常显示:

1
cv2.imshow(winname, mat)

后面还要添上一句:

1
cv2.waitKey([delay])

如果不添这一句,在 IDLE 中执行窗口直接无响应;在命令行中执行的话,会一闪而过。delay 参数单位是毫秒,当 delay <= 0,会无限等待一个键盘输入,至于传递一个正值,目前还没发现当到达这个设置的 delay 值却没有任何键盘输入会发生什么,文档中写的是会返回一个 -1;如果按键了,会返回这个按键的 ASCII 值。

0x03.创建图像

创建图像可以创建一个 Numpy 的全 0 数组:

1
numpy.zeros(shape, dtype=float, order='C')

这个空白图像其实就是一个用 0 填充的 Numpy 数组,可以通过 shape 指定数组的形状,通过 dtype 指定数组中存的数据的类型。另一种方式,通过复制一幅图像来创建一个副本:

1
image_copy = image_original.copy()

0x04.写入图像

1
imwrite(filename, img[, params])

通过 params 可以设置保存图像的质量和压缩级别等参数。对于保存的图像,格式不同,参数的意义也不同,比如对于 JPEG 格式的图像,其表示的是图像的质量,用 0-100 的整数表示,默认为95。 注意,cv2.IMWRITE_JPEG_QUALITY 类型为 Long,必须转换成 int;而对于 PNG 格式的图像,第三个参数表示的是压缩级别,cv2.IMWRITE_PNG_COMPRESSION,从 0 到 9,数值越大压缩级别越高,图像尺寸越小,默认压缩级别为 3.

0x05.程序清单

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
# @Date : 2015-01-09 23:25:31
# @Author : NSSimacer
# @Version : 1.0
import cv2
import numpy as np
from matplotlib import pyplot as plt
def show_image(img, window_name):
'''
显示图像
'''
cv2.namedWindow(window_name, cv2.WINDOW_AUTOSIZE)
cv2.imshow(window_name, img)
if cv2.waitKey(0) & 0xFF == 27: # 按 ESC 退出
cv2.destroyWindow(window_name)
def show_image_with_matplotlib(img, window_name):
'''
用 Matplotlib 显示图像
'''
plt.title(window_name, fontsize=18)
plt.imshow(X=img, cmap='gray', interpolation='bicubic')
plt.xticks([])
plt.yticks([])
plt.show()
def write_image(name, img, quality=100, compression=0):
'''
把图像写入文件,设置图片质量等参数
'''
cv2.imwrite(name, img, [int(cv2.IMWRITE_JPEG_QUALITY), quality])
def create_image(img):
'''
新建图像
'''
blank_image = np.zeros(img.shape, np.uint8) # 使用 numpy 新建空白图像
write_image('blank.jpg', blank_image)
show_image(cv2.imread('blank.jpg'), 'Blank Image')
def copy_image(img):
'''
复制图像
'''
copy_image = img.copy()
write_image('testCopy.jpg', copy_image, 5)
show_image(cv2.imread('testCopy.jpg'), 'Copy Image')
if __name__ == '__main__':
img = cv2.imread('Lenna.png')
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
show_image_with_matplotlib(img, 'ImageShow')
create_image(img)
copy_image(img)
cv2.destroyAllWindows()

最后,不要忘了释放所有窗口 :)

1
cv2.destroyAllWindows()