OpenCV 计算机视觉完全教程 / 第 01 章 — OpenCV 概述:历史、模块与架构
第 01 章 — OpenCV 概述
1.1 OpenCV 历史与演进
OpenCV(Open Source Computer Vision Library)是全球使用最广泛的开源计算机视觉库。
| 时间 | 里程碑 | 说明 |
|---|---|---|
| 1999 | 项目启动 | Intel 俄罗斯研究院发起,Gary Bradski 主导 |
| 2000 | 首次开源 | 在 CVPR 会议上公开,BSD 许可证 |
| 2006 | 1.0 发布 | 支持 C/C++,核心功能稳定 |
| 2009 | 2.0 | 引入 C++ 接口,Mat 类替代 IplImage |
| 2012 | 2.4 | 成熟的稳定版本,社区广泛采用 |
| 2014 | 3.0 | 重大重构:模块化架构、T-API、DNN 模块 |
| 2018 | 4.0 | C++17、ONNX 支持、G-API 流式处理 |
| 2022 | 4.7+ | CUDA DNN、Vulkan 后端、Python 类型提示 |
| 2025 | 5.0 (dev) | 新一代 API 设计、性能大幅提升 |
注意: 目前生产环境推荐使用 OpenCV 4.10.x 稳定版,5.x 尚处于开发阶段。
1.2 核心模块一览
OpenCV 采用模块化架构,每个模块负责一个特定领域:
opencv/
├── core ← 核心数据结构 (Mat, Vec, Scalar)
├── imgproc ← 图像处理 (滤波, 变换, 颜色转换)
├── imgcodecs ← 图像编解码 (JPEG, PNG, TIFF)
├── highgui ← 窗口显示与交互 (imshow, waitKey)
├── videoio ← 视频 I/O (摄像头, 编解码器)
├── video ← 视频分析 (光流, 背景减除, 追踪)
├── calib3d ← 相机标定与 3D 视觉
├── features2d ← 2D 特征检测与匹配
├── objdetect ← 目标检测 (HOG, 级联分类器)
├── dnn ← 深度学习推理引擎
├── ml ← 机器学习算法
├── photo ← 计算摄影 (去噪, HDR, 修补)
├── stitching ← 图像拼接 (全景)
├── flann ← 快速最近邻搜索
├── face ← 人脸相关 (contrib)
├── cuda* ← GPU 加速模块 (需 CUDA 编译)
└── gapi ← 图处理 API (流式管线)
模块依赖关系(简化)
┌─────────────────────────────────────────────┐
│ 应用层 (Application) │
├──────┬──────┬──────┬──────┬──────┬──────────┤
│dnn │video │calib │objdet│photo │stitching │
├──────┴──────┴──────┴──────┴──────┴──────────┤
│ imgproc (图像处理) │
├─────────────────────────────────────────────┤
│ core (核心基础) │
├─────────────────────────────────────────────┤
│ imgcodecs / videoio (I/O 层) │
├─────────────────────────────────────────────┤
│ 高层 GUI: highgui / gapi │
└─────────────────────────────────────────────┘
1.3 OpenCV 架构设计
3.1 核心数据结构:Mat
Mat 是 OpenCV 最核心的类,用于表示多维稠密数组:
import cv2
import numpy as np
# 创建 Mat(在 Python 中就是 numpy.ndarray)
img = np.zeros((480, 640, 3), dtype=np.uint8)
print(f"类型: {type(img)}") # <class 'numpy.ndarray'>
print(f"形状: {img.shape}") # (480, 640, 3)
print(f"数据类型: {img.dtype}") # uint8
print(f"总元素数: {img.size}") # 921600
#include <opencv2/opencv.hpp>
int main() {
// C++ 中的 Mat
cv::Mat img(480, 640, CV_8UC3, cv::Scalar(0, 0, 0));
std::cout << "形状: " << img.rows << "x" << img.cols
<< "x" << img.channels() << std::endl;
std::cout << "连续: " << img.isContinuous() << std::endl;
return 0;
}
3.2 函数命名规范
| 前缀/后缀 | 含义 | 示例 |
|---|---|---|
cv:: | 命名空间 | cv::imread() |
*Convert | 颜色空间转换 | cvtColor() |
*Blur | 滤波操作 | GaussianBlur() |
*Threshold | 阈值处理 | threshold() |
find* | 查找操作 | findContours() |
draw* | 绘制操作 | drawContours() |
*Filter | 滤波器 | bilateralFilter() |
*Transform | 变换 | warpAffine() |
1.4 与主流视觉库对比
功能对比表
| 特性 | OpenCV 4.x | Pillow | scikit-image | torchvision | VIPS |
|---|---|---|---|---|---|
| 语言 | C++/Python | Python | Python | Python/C++ | C |
| 速度 | ★★★★★ | ★★☆☆☆ | ★★★☆☆ | ★★★★☆ | ★★★★☆ |
| 功能广度 | ★★★★★ | ★★☆☆☆ | ★★★☆☆ | ★★★☆☆ | ★★☆☆☆ |
| GPU 支持 | ✅ CUDA | ❌ | ❌ | ✅ CUDA | ❌ |
| DNN 推理 | ✅ 多框架 | ❌ | ❌ | ✅ PyTorch | ❌ |
| 视频处理 | ✅ 完整 | ❌ | ❌ | ✅ 基础 | ❌ |
| 3D 视觉 | ✅ 完整 | ❌ | ❌ | ❌ | ❌ |
| 实时性 | ✅ 优秀 | ❌ | ⚠️ 一般 | ✅ 良好 | ⚠️ 一般 |
| 学习曲线 | 中等 | 低 | 低 | 中等 | 高 |
| 许可证 | Apache 2.0 | PIL | BSD 3 | BSD | LGPL |
| GitHub Stars | 82k+ | 12k+ | 3k+ | 22k+ | 2k+ |
性能基准测试(1080p 图像操作)
| 操作 | OpenCV | Pillow | scikit-image |
|---|---|---|---|
| 读取 JPEG | 8ms | 25ms | 30ms |
| 高斯模糊 (k=5) | 2ms | 15ms | 12ms |
| Canny 边缘 | 5ms | N/A | 35ms |
| 调整大小 (50%) | 1ms | 8ms | 10ms |
| 旋转 45° | 3ms | 12ms | 18ms |
注意: 数据为典型桌面 CPU 环境,实际性能因硬件和图像尺寸而异。
1.5 适用场景指南
场景选型决策树
需要处理图像/视频?
├─ 仅简单图片格式转换/缩放
│ └─ → Pillow(轻量、简单)
├─ 需要科学图像分析(测量、形态学)
│ └─ → scikit-image(API 优雅,与 NumPy 生态集成好)
├─ 实时视频处理 / 摄像头输入
│ └─ → OpenCV(videoio + 优化算法)
├─ 需要 GPU 加速
│ └─ → OpenCV CUDA 或 PyTorch/torchvision
├─ 深度学习模型训练
│ └─ → PyTorch / TensorFlow(OpenCV 用于推理部署)
├─ 工业级目标检测/OCR/人脸识别
│ └─ → OpenCV DNN + 深度学习模型
├─ 3D 视觉 / AR / 相机标定
│ └─ → OpenCV calib3d(几乎唯一选择)
└─ 高吞吐量服务器端图像处理
└─ → libvips(内存效率高)或 OpenCV
典型业务场景
| 行业 | 场景 | OpenCV 角色 |
|---|---|---|
| 安防监控 | 人脸识别、入侵检测 | 图像预处理 + DNN 推理 |
| 自动驾驶 | 车道线、障碍物检测 | 边缘检测 + 特征匹配 |
| 工业质检 | 缺陷检测、尺寸测量 | 形态学 + 轮廓分析 |
| 医疗影像 | CT/MRI 分割 | 阈值处理 + 连通域 |
| AR/VR | 姿态估计、标记检测 | ArUco + solvePnP |
| 农业 | 作物病害识别 | 颜色空间 + DNN |
| 文档处理 | OCR 预处理、透视校正 | 变换 + 二值化 |
1.6 生态系统与扩展
OpenCV 生态全景
┌─────────────────┐
│ OpenCV Core │
└────────┬────────┘
┌─────────┬──────┼──────┬──────────┐
▼ ▼ ▼ ▼ ▼
┌──────────┐ ┌──────┐ ┌───┐ ┌────┐ ┌──────────┐
│opencv-con│ │DNN │ │G- │ │ML │ │opencv- │
│trib │ │模块 │ │API│ │模块 │ │python │
└──────────┘ └──────┘ └───┘ └────┘ └──────────┘
│ │
┌──────┴──┐ ┌───┴────┐
│face │ │ONNX │
│aruco │ │TensorFl│
│xfeatures│ │PyTorch │
│ximgproc │ │Caffe │
└─────────┘ └────────┘
常用第三方集成
| 工具 | 用途 | 集成方式 |
|---|---|---|
| NumPy | 数组操作 | OpenCV Python 底层数据格式 |
| Matplotlib | 结果可视化 | cv2.cvtColor → RGB 转换后显示 |
| ONNX Runtime | 高性能推理 | OpenCV DNN 后端 |
| TensorRT | GPU 推理加速 | OpenCV DNN CUDA 后端 |
| MediaPipe | 人脸/手势/姿态 | 独立使用或与 OpenCV 协作 |
| Ultralytics | YOLO 系列 | 基于 OpenCV DNN 部署 |
1.7 第一个程序
让我们用 OpenCV 完成一个简单的图像处理流水线:
"""
01-hello-opencv.py — OpenCV 第一个程序
功能:读取图像 → 转灰度 → 高斯模糊 → Canny 边缘 → 显示
"""
import cv2
import numpy as np
# 1. 创建一个示例图像(如果没有实际图片)
img = np.random.randint(0, 256, (480, 640, 3), dtype=np.uint8)
# 画一个白色圆作为测试目标
cv2.circle(img, (320, 240), 100, (255, 255, 255), -1)
# 2. 转灰度
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 3. 高斯模糊降噪
blurred = cv2.GaussianBlur(gray, (5, 5), 1.0)
# 4. Canny 边缘检测
edges = cv2.Canny(blurred, 50, 150)
# 5. 显示结果
print(f"原始图像尺寸: {img.shape}")
print(f"灰度图像尺寸: {gray.shape}")
print(f"边缘图像尺寸: {edges.shape}")
# 6. 保存结果
cv2.imwrite("original.png", img)
cv2.imwrite("edges.png", edges)
print("处理完成,结果已保存。")
// 01-hello-opencv.cpp
#include <opencv2/opencv.hpp>
#include <iostream>
int main() {
// 1. 创建示例图像
cv::Mat img(480, 640, CV_8UC3, cv::Scalar(100, 100, 100));
cv::circle(img, cv::Point(320, 240), 100,
cv::Scalar(255, 255, 255), -1);
// 2. 转灰度
cv::Mat gray;
cv::cvtColor(img, gray, cv::COLOR_BGR2GRAY);
// 3. 高斯模糊
cv::Mat blurred;
cv::GaussianBlur(gray, blurred, cv::Size(5, 5), 1.0);
// 4. Canny 边缘检测
cv::Mat edges;
cv::Canny(blurred, edges, 50, 150);
// 5. 输出信息
std::cout << "原始: " << img.size() << " " << img.channels() << "ch" << std::endl;
std::cout << "边缘: " << edges.size() << " " << edges.channels() << "ch" << std::endl;
// 6. 保存
cv::imwrite("original.png", img);
cv::imwrite("edges.png", edges);
std::cout << "处理完成" << std::endl;
return 0;
}
1.8 扩展阅读
| 资源 | 链接 | 说明 |
|---|---|---|
| OpenCV 官方教程 | docs.opencv.org/4.x/d6/d00/tutorial_py_root.html | Python 官方教程 |
| OpenCV C++ 教程 | docs.opencv.org/4.x/db/d61/tutorial_c… | C++ 完整教程 |
| LearnOpenCV | learnopencv.com | 高质量实战教程 |
| OpenCV 之旅 (书籍) | GitHub 上的开源书籍 | 中文社区翻译 |
| 下一章 | 第 02 章 — 安装与环境配置 | pip / 编译 / GPU |
本章小结: 了解了 OpenCV 20+ 年的发展历程、模块化架构设计、与同类库的差异,以及在不同行业场景中的选型策略。下一章我们将搭建开发环境。