OpenCV (Open Source Computer Vision Library) 是一个开源计算机视觉库,其 C++ 核心库被封装为多种语言接口,其中就包括 Python。它提供了丰富的功能,涵盖了从低级图像处理操作(如滤波、变形)到高级计算机视觉任务(如物体检测、人脸识别、姿态估计、机器学习算法)等各个方面。opencv-python 库使得 Python 开发者能够轻松利用这些强大的计算机视觉能力,广泛应用于科研、工业、人工智能等领域。

核心思想:OpenCV 提供了一套全面且高性能的工具集,以简化图像和视频的处理与分析,使计算机能够“看清”并理解世界。


一、为什么选择 OpenCV-Python?

  • 功能全面:涵盖了计算机视觉的几乎所有核心功能。
  • 性能优异:底层由 C/C++ 实现,性能接近原生应用,同时提供了 Python 简单易用的接口。
  • 跨平台:支持 Windows、Linux、macOS 等多种操作系统。
  • 活跃社区与丰富资源:庞大的用户群和详细的文档、教程,解决问题方便。
  • 与 Python 生态集成好:可以方便地与 NumPy、Matplotlib、Scikit-learn 等 Python 库协同工作。

二、安装 OpenCV-Python

opencv-python 并非 Python 的内置库,需要通过 pip 安装。通常推荐安装带有所有额外模块(如深度学习模块、SIFT/SURF 等专利算法)的版本:

1
2
3
pip install opencv-python # 核心模块,不包含一些非免费或实验性模块
# 或
pip install opencv-contrib-python # 包含所有额外模块,推荐

安装完成后,就可以在 Python 代码中导入并使用了:

1
2
3
import cv2
import numpy as np # OpenCV 经常与 NumPy 协同工作
import matplotlib.pyplot as plt # 用于图像显示

三、图像基础操作

3.1 读取、显示和保存图像

OpenCV 使用 NumPy 数组来表示图像,每个像素通常以 BGR(蓝、绿、红)顺序存储。

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
import cv2
import numpy as np
import matplotlib.pyplot as plt

# 创建一个演示用的图片文件 (如果不存在)
# np.zeros((行, 列, 通道), 数据类型)
# 400x600 像素,3通道 (彩色),uint8 (0-255)
dummy_img = np.zeros((400, 600, 3), dtype=np.uint8)
dummy_img[50:150, 100:200] = [255, 0, 0] # 蓝色矩形
dummy_img[200:300, 300:500] = [0, 255, 0] # 绿色矩形
cv2.imwrite('demo_image.jpg', dummy_img)


# 1. 读取图像
# cv2.imread(文件名, 读取模式)
# 读取模式:cv2.IMREAD_COLOR (默认,彩色), cv2.IMREAD_GRAYSCALE (灰度), cv2.IMREAD_UNCHANGED (不变)
img_color = cv2.imread('demo_image.jpg', cv2.IMREAD_COLOR)
img_gray = cv2.imread('demo_image.jpg', cv2.IMREAD_GRAYSCALE)

if img_color is None:
print("错误: 无法加载图像。请确保文件路径正确。")
else:
# 2. 显示图像 (使用 OpenCV 的窗口)
cv2.imshow('彩色图像', img_color)
cv2.imshow('灰度图像', img_gray)
cv2.waitKey(0) # 等待用户按键,0 表示无限等待
cv2.destroyAllWindows() # 销毁所有 OpenCV 窗口

# 3. 使用 Matplotlib 显示 (OpenCV 是 BGR,Matplotlib 是 RGB)
plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1)
plt.title('彩色图像 (Matplotlib)')
plt.imshow(cv2.cvtColor(img_color, cv2.COLOR_BGR2RGB)) # BGR 转 RGB
plt.axis('off')

plt.subplot(1, 2, 2)
plt.title('灰度图像 (Matplotlib)')
plt.imshow(img_gray, cmap='gray') # 灰度图直接显示
plt.axis('off')
plt.show()

# 4. 保存图像
cv2.imwrite('gray_image.jpg', img_gray)
print("图像已保存。")

3.2 图像基本属性

图像被加载为 NumPy 数组,因此可以像操作 NumPy 数组一样获取其属性。

1
2
3
4
5
6
7
8
if img_color is not None:
print(f"彩色图像的形状 (高, 宽, 通道): {img_color.shape}")
print(f"彩色图像的像素总数: {img_color.size}")
print(f"彩色图像的数据类型: {img_color.dtype}")

print(f"灰度图像的形状 (高, 宽): {img_gray.shape}")
print(f"灰度图像的像素总数: {img_gray.size}")
print(f"灰度图像的数据类型: {img_gray.dtype}")

3.3 访问和修改像素

图像是 NumPy 数组,可以直接通过索引访问像素。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
if img_color is not None:
# 访问 (行, 列) 位置的像素值 (BGR 格式)
px = img_color[100, 100]
print(f"(100, 100) 像素值 (BGR): {px}") # 例如 [255 0 0] 表示蓝色

# 修改像素值
img_color[100:102, 100:102] = [0, 0, 255] # 将 (100,100) 附近的像素设为红色

# 访问单个通道
blue_channel = img_color[:, :, 0]
print(f"蓝色通道的形状: {blue_channel.shape}")

cv2.imshow('局部修改后的图像', img_color)
cv2.waitKey(0)
cv2.destroyAllWindows()

四、图像处理核心功能

4.1 图像变换 (几何变换)

  • 缩放 (Resizing)

    1
    2
    3
    4
    5
    6
    resized_img = cv2.resize(img_color, (300, 200), interpolation=cv2.INTER_AREA) # 宽=300,高=200
    # 或按比例缩放
    scaled_img = cv2.resize(img_color, None, fx=0.5, fy=0.5, interpolation=cv2.INTER_LINEAR)
    cv2.imshow('缩放图像', resized_img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
  • 平移 (Translation)

    1
    2
    3
    4
    5
    6
    rows, cols, _ = img_color.shape
    M = np.float32([[1, 0, 100], [0, 1, 50]]) # [1, 0, x方向平移量], [0, 1, y方向平移量]
    shifted_img = cv2.warpAffine(img_color, M, (cols, rows))
    cv2.imshow('平移图像', shifted_img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
  • 旋转 (Rotation)

    1
    2
    3
    4
    5
    6
    center = (cols // 2, rows // 2)
    M = cv2.getRotationMatrix2D(center, 45, 1) # (中心点, 角度, 缩放比例)
    rotated_img = cv2.warpAffine(img_color, M, (cols, rows))
    cv2.imshow('旋转图像', rotated_img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

4.2 图像滤波 (平滑/模糊)

用于去除噪声。

1
2
3
4
5
6
7
8
9
10
11
# 高斯模糊
blurred_gauss = cv2.GaussianBlur(img_color, (5, 5), 0) # (图像, (核大小), 标准差)
cv2.imshow('高斯模糊', blurred_gauss)
cv2.waitKey(0)
cv2.destroyAllWindows()

# 中值模糊 (对椒盐噪声效果好)
blurred_median = cv2.medianBlur(img_color, 5) # (图像, 核大小)
cv2.imshow('中值模糊', blurred_median)
cv2.waitKey(0)
cv2.destroyAllWindows()

4.3 边缘检测

  • Canny 边缘检测

    1
    2
    3
    4
    edges = cv2.Canny(img_gray, 100, 200) # (灰度图, 低阈值, 高阈值)
    cv2.imshow('Canny 边缘', edges)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

4.4 形态学操作

基于图像形状的非线性操作,常用于二值图像。

  • 腐蚀 (Erosion):缩小前景物体
  • 膨胀 (Dilation):增大前景物体
1
2
3
4
5
6
7
8
kernel = np.ones((5, 5), np.uint8)
eroded_img = cv2.erode(img_gray, kernel, iterations=1)
dilated_img = cv2.dilate(img_gray, kernel, iterations=1)

cv2.imshow('腐蚀', eroded_img)
cv2.imshow('膨胀', dilated_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

五、高级计算机视觉功能

5.1 物体检测 (Haar 级联分类器)

OpenCV 内置了 Haar 级联分类器,可以用于人脸、眼睛等预训练物体的检测。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 下载预训练模型
# 可以从 https://github.com/opencv/opencv/tree/master/data/haarcascades 下载
# 例如:haarcascade_frontalface_default.xml

# face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
# gray_img = cv2.cvtColor(img_color, cv2.COLOR_BGR2GRAY)

# if face_cascade.empty():
# print("错误: 无法加载 Haar 级联分类器。请检查文件路径。")
# else:
# faces = face_cascade.detectMultiScale(gray_img, 1.3, 5)
# for (x, y, w, h) in faces:
# cv2.rectangle(img_color, (x, y), (x+w, y+h), (255, 0, 0), 2) # 在检测到的人脸周围画矩形

# cv2.imshow('人脸检测', img_color)
# cv2.waitKey(0)
# cv2.destroyAllWindows()

5.2 实时视频处理

OpenCV 可以轻松访问摄像头或处理视频文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# cap = cv2.VideoCapture(0) # 0 表示默认摄像头,也可以是视频文件路径 'video.mp4'

# if not cap.isOpened():
# print("错误: 无法打开摄像头。")
# else:
# while True:
# ret, frame = cap.read() # ret 是布尔值,frame 是捕获到的帧

# if not ret:
# print("无法读取帧,退出...")
# break

# # 将每一帧转换为灰度图
# gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

# cv2.imshow('实时灰度视频', gray_frame)

# if cv2.waitKey(1) & 0xFF == ord('q'): # 等待 1ms,如果按下 'q' 键则退出
# break

# cap.release() # 释放摄像头资源
# cv2.destroyAllWindows()

5.3 深度学习模块 (DNN)

OpenCV 的 dnn 模块支持加载和运行各种深度学习模型(如 TensorFlow, Caffe, PyTorch 导出的模型),用于物体检测(SSD, YOLO)、图像分类等任务。

工作流程 (概念)

  1. 加载模型cv2.dnn.readNetFromCaffe()cv2.dnn.readNetFromTensorflow() 等。
  2. 准备输入:将图像调整为模型所需的尺寸和格式,通常通过 cv2.dnn.blobFromImage()
  3. 前向传播:将处理后的图像输入模型进行推理。
  4. 解析输出:根据模型的输出格式提取检测结果或分类概率。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
graph TD
A[图像/视频输入] --> B[预处理 (灰度化, 缩放, 归一化)]
B --> C{图像基本操作}
C --> D[滤波器 (高斯, 中值)]
C --> E[边缘检测 (Canny, Sobel)]
C --> F[形态学操作 (腐蚀, 膨胀)]
D --> G[增强/分割/特征提取]
E --> G
F --> G
G --> H{高级计算机视觉}
H --> I[对象检测 (Haar级联, DNN)]
H --> J[特征匹配 (SIFT, SURF, ORB)]
H --> K[图像拼接/全景图]
H --> L[姿态估计]
H --> M[机器学习/深度学习 (通过DNN模块)]
J --> N[图像识别/检索]
K --> N
L --> N
M --> N
N --> P[应用 (自动驾驶, 人脸识别, AR/VR, 医疗影像)]

六、OpenCV 与 NumPy、Matplotlib 的协作

  • OpenCV 图像即 NumPy 数组:这意味着你可以直接在 OpenCV 图像上使用 NumPy 的所有强大功能进行数学运算、切片、重塑等。
  • Matplotlib 进行图像显示:虽然 OpenCV 有自己的 imshow,但 Matplotlib 提供了更灵活的绘图选项和专业的图像显示效果,特别是需要同时显示多张图像、添加标题、坐标轴时。记得 OpenCV 是 BGR 格式,而 Matplotlib 是 RGB 格式,需要进行颜色空间转换 (cv2.cvtColor(img, cv2.COLOR_BGR2RGB))。

七、总结与进阶

OpenCV 是计算机视觉领域的基石,它不仅提供了底层图像处理能力,也集成了许多先进的算法。对于 Python 开发者而言,opencv-python 是进入计算机视觉世界的理想入口。

进阶方向:

  • 特征检测与描述 (SIFT, SURF, ORB):用于图像配准、目标跟踪、全景图拼接等。
  • 目标跟踪 (Tracking):如 KCF、CSRT 跟踪器。
  • 图像分割 (Segmentation):如 GrabCut 算法。
  • 图像识别与机器学习:结合 Scikit-learn 或 TensorFlow/PyTorch 等更强大的机器学习框架。
  • 更深入的 DNN 应用:学习如何在 OpenCV 中加载和使用主流的深度学习模型进行高级任务。
  • 性能优化:对于实时应用,了解如何利用多线程、并行计算以及 OpenCV 的优化技术。

通过不断实践和探索,你将能够利用 OpenCV-Python 在各种计算机视觉项目中发挥出无限的创造力。