← 返回博客列表

一、什么是 OpenCV

OpenCV(Open Source Computer Vision Library)是一个开源、跨平台的计算机视觉与机器学习库。它由 Intel 于 1999 年发起,如今由非营利组织 OpenCV.org 维护,已经成为全球使用最广泛的视觉库——从学术研究到工业产线、从无人机到自动驾驶,几乎一切"让机器看见"的场景都有它的身影。

OpenCV 的设计哲学可以用三个词概括:

一句话理解 OpenCV
如果说 TensorFlow / PyTorch 是"大脑"(做推理),那 OpenCV 就是"眼睛 + 视觉皮层"——它负责把图像"读进来、看清楚、提取特征",再把结果喂给大脑。
OpenCV 在视觉系统中的定位 相机 / 摄像头 采集图像 CCD / CMOS OpenCV(眼睛 + 视觉皮层) 图像读取/编码 预处理/滤波 特征检测 几何变换 相机标定 DNN 推理 图像 → 矩阵 → 处理 → 特征/决策 AI 框架 PyTorch / TF 高级推理/决策
OpenCV 负责"看见"和"理解",AI 框架负责"决策"

二、OpenCV 能力矩阵

OpenCV 的能力覆盖了从底层像素操作到高层语义理解的完整链路,可归纳为六大能力域:

OpenCV 六大能力域 1. 图像 I/O 与编解码 imread / imwrite / imshow JPEG / PNG / WebP / TIFF 视频捕获 VideoCapture RTSP / USB / CSI 相机 2. 图像处理与滤波 高斯/中值/双边滤波 直方图均衡化 形态学操作 几何变换/透视 3. 特征检测与描述 角点:Harris / Shi-Tomasi 描述子:SIFT / SURF / ORB 特征匹配:BFMatcher / FLANN 光流:LK / Farneback 4. 几何与标定 相机标定 calibrateCamera 畸变校正 undistort 对极几何 findFundamentalMat 立体视觉 StereoBM/SGBM 5. 目标检测与识别 传统:Haar 级联 / HOG+SVM 深度学习:YOLO / SSD / Mask R-CNN 人脸检测 / 识别 二维码 / 条码检测 6. 深度学习推理 readNet (ONNX / Caffe / TF) 后端:OpenCV / CUDA / OpenVINO NMS / resize / 归一化前处理 分类 / 检测 / 分割 / 姿态 OpenCV 模块包 core(核心) imgproc imgcodecs videoio dnn features2d calib3d video objdetect photo stitching xfeatures2d
OpenCV 六大能力域与主要模块包
能力域代表 API一句话描述
I/O 与编解码imread / VideoCapture把图像/视频从磁盘或相机读入内存
图像处理GaussianBlur / Canny对像素矩阵做滤波、增强、检测
特征检测ORB / SIFT从图像中提取" distinctive"关键点
几何与标定calibrateCamera算出相机内参、畸变、3D 重建
目标检测CascadeClassifier / DNN在图像中框出人脸/物体
深度学习readNetFromONNX加载训练好的模型做推理

三、核心原理:图像即矩阵

OpenCV 的所有处理都建立在一个基本事实之上:一张图像就是一个数值矩阵。灰度图是二维矩阵,彩色图是三维矩阵(H × W × C)。

图像 = 像素值矩阵(灰度图 4×4 示意) 像素图 每个格子的灰度 = 一个 0~255 的数值 imread Mat 对象(cv::Mat) [ [ 0, 64, 128, 192], [ 64, 128, 192, 224], [128, 192, 224, 240], [192, 224, 240, 255] , ] ] rows=4, cols=4, type=CV_8UC1 彩色图 = 三通道矩阵(BGR) B 通道 G 通道 R 通道 → 叠加 → BGR 彩色 H×W×3
OpenCV 用 cv::Mat 表达图像:灰度图是 H×W 矩阵,彩色图是 H×W×3 张量

cv::Mat 是 OpenCV 的核心数据结构,它有几个关键属性:

关键记忆点
OpenCV 默认的色彩顺序是 BGR 而非 RGB!这是因为 OpenCV 早期采用 BGR 顺序(匹配当时相机的传感器输出格式)。用 cvtColor(src, dst, COLOR_BGR2RGB) 可转换为 RGB 顺序后再送入其他库。

四、色彩空间与转换

不同色彩空间适合不同的任务。cv::cvtColor 是色彩空间转换的万能函数。

常见色彩空间与适用场景 BGR 三通道 B+G+R 叠加 适用: imread 默认 imwrite 默认 imshow 显示 通道顺序:B, G, R 每个 0~255 Gray(灰度) 单通道 亮度信息 适用: 边缘检测 人脸检测 二维码识别 公式:0.299R+0.587G +0.114B HSV H 色调 0~180 S 饱和度 适用: 颜色追踪 阈值分割 光照鲁棒 颜色 = H 角度 对光照变化不敏感 LAB L 亮度 a 红→绿 适用: 色彩差异比较 图像拼接 色彩校正 感知均匀空间 色差 = 欧氏距离
四大常用色彩空间:BGR(存储/显示)、Gray(检测)、HSV(颜色分割)、LAB(色差比较)
// 色彩空间转换示例
cv::Mat bgr = cv::imread("photo.jpg");      // 默认 BGR 三通道
cv::Mat gray, hsv, lab;
cv::cvtColor(bgr, gray, cv::COLOR_BGR2GRAY);    // BGR → 灰度
cv::cvtColor(bgr, hsv,  cv::COLOR_BGR2HSV);     // BGR → HSV
cv::cvtColor(bgr, lab,  cv::COLOR_BGR2Lab);     // BGR → CIE-LAB

五、图像滤波与卷积

卷积是图像处理最核心的操作:用一个小的卷积核(Kernel)在图像上滑动,每到一个位置,就把核覆盖区域与核做"逐元素乘法再求和",得到输出像素值。

卷积运算:核滑动 + 加权求和 输入图像 (5×5) 1020304050 2030405060 3040506070 4050607080 5060708090 卷积核 (3×3) 10-1 20-2 10-1 Sobel 竖直边缘核 = 输出像素 计算过程: 10×1+20×0+30×(-1) +20×2+30×0+40×(-2) +30×1+40×0+50×(-1) = 10+0-30+40+0-80 +30+0-50 = -80 核在图像上逐像素滑动,每个位置算出一个输出值 → 得到"卷积结果图" 不同核 = 不同效果:模糊核(全1/N)→平滑 · 锐化核(中心大、四周负)→增强 · Sobel核 →边缘 · 高斯核→加权模糊 API: filter2D(src, dst, ddepth, kernel) 通用卷积 | GaussianBlur / blur / medianBlur 专用快捷函数
3×3 Sobel 核在图像上滑动,每个位置加权求和得到一个输出像素

OpenCV 提供了多种现成滤波器,无需手动构造核:

滤波器API效果典型用途
均值滤波blur()取邻域均值快速去噪
高斯滤波GaussianBlur()加权均值(中心权重大)通用平滑(最常用)
中值滤波medianBlur()取邻域中位数椒盐噪声去除
双边滤波bilateralFilter()保边平滑(考虑像素差)美颜/卡通化
自定义卷积filter2D()任意核锐化/边缘/Sobel

六、边缘检测

边缘是图像中亮度变化最剧烈的地方,是物体轮廓的直接描述。Canny 边缘检测是最经典的边缘提取算法,它分四步完成:

Canny 边缘检测四步流水线 1. 高斯滤波 GaussianBlur 目的: 抑制噪声 避免伪边缘 5×5 高斯核 2. 梯度计算 Sobel 算子 目的: 算 Gx, Gy 梯度幅值+方向 G=√(Gx²+Gy²) 3. 非极大值抑制 NMS 目的: 细化边缘 只保留局部 最大梯度点 粗边缘 → 细线 4. 双阈值检测 Hysteresis 高阈值:确定 低阈值:候选 候选连接到 确定→保留 抑制孤立弱边缘 二值 边缘图 255=边缘 Canny(img, edges, threshold1=100, threshold2=200) — 一行代码完成四步
Canny 四步流水线:滤波→梯度→细化→双阈值连接

七、形态学操作

形态学操作作用于二值图像(黑白图),用一个小结构元素(通常 3×3)在图像上扫描,对前景像素做膨胀或收缩。

膨胀 vs 腐蚀:最基础的两种形态学操作 原始二值图 膨胀(Dilate) 前景向外扩张→断口弥合 腐蚀(Erode) 前景向内收缩→去除噪点 膨胀:核覆盖区域有前景→输出前景 | 腐蚀:核覆盖区域全为前景→才输出前景
膨胀扩张前景、腐蚀收缩前景;两者组合可得到开运算(去噪)和闭运算(填洞)
操作API组合方式用途
膨胀dilate()—连接断裂区域、加粗边缘
腐蚀erode()—去除小白点噪声、细化
开运算morphologyEx(MORPH_OPEN)先腐蚀再膨胀去除前景上的小颗粒
闭运算morphologyEx(MORPH_CLOSE)先膨胀再腐蚀填充前景上的小黑洞

八、特征检测与匹配

特征(Feature)是图像中"独特"的点——如果你在两张不同角度拍摄的同一场景照片中找对应关系,这些点最能被匹配上。

特征检测与匹配流程 图 A 检测关键点 图 B(不同角度) 检测关键点 描述子计算 关键点邻域 → 128/256维向量 特征匹配 BFMatcher / FLANN 描述子计算 关键点邻域 → 向量 比率过滤 Lowe ratio < 0.7 输出:匹配对列表 → 单应性矩阵 H → 图像拼接 / 物体识别 / 3D 定位 主流算法:SIFT(专利过期,精度高) · ORB(免费快速,SLAM 首选) · AKAZE(平衡型)
特征检测→描述→匹配→过滤→几何验证,完整特征匹配链路

九、相机标定

真实相机镜头有制造误差,拍出的图像存在畸变(桶形/枕形)。标定就是通过拍棋盘格,算出相机内参矩阵和畸变系数,从而"把弯曲拉直"。

相机标定原理:从棋盘格到内参矩阵 拍棋盘格 10~20 张不同角度 findChessboardCorners 检测内角点 cornerSubVis 亚像素精化 → 像素坐标集 calibrateCamera 输入:像素点 + 3D 世界点 求解:内参 K + 畸变系数 D + 外参 R, t undistort 去畸变 内参矩阵 K: [ fx 0 cx ] [ 0 fy cy ] [ 0 0 1 ] 畸变系数 D = [k1,k2,p1,p2,k3]
标定四步:拍棋盘格→找角点→求解内外参→去畸变

十、深度学习模块 DNN

OpenCV 从 3.3 版开始内置 dnn 模块,它不是训练框架,而是一个推理引擎——加载 PyTorch / TensorFlow / Caffe / ONNX 导出的模型,在 CPU / CUDA / OpenVINO 上高效推理。

DNN 模块推理流水线 模型文件 ONNX/Caffe/TFLite readNet 解析图+权重 blob 前处理 resize+归一化 forward 推理 CPU/CUDA/OpenVINO 后处理 NMS+画框 支持的目标检测模型 YOLO v3/v4/v5 SSD Faster R-CNN Mask R-CNN ResNet/VGG EfficientNet ...
DNN 推理五步:读模型→解析→blob 预处理→forward→后处理输出

十一、核心特性

特性说明
开源免费BSD 协议,学术与商用均无限制,无需公开源码
跨平台Windows / Linux / macOS / Android / iOS 全平台支持
多语言绑定C++ 原生 API,Python / Java / MATLAB / C# 绑定齐全,Python 绑定最流行
SIMD 加速核心循环自动利用 SSE/AVX(x86)和 NEON(ARM),无需改代码
GPU 加速OpenCL / CUDA 后端(cuda 模块),DNN 模块支持 CUDA + cuDNN
模块化按需链接:只用 imgproc 就不必链接 dnn/calib3d,嵌入式部署体积可控
UMat 统一内存UMat 透明地在 CPU/GPU 间迁移数据,同一套代码跨设备运行
硬件加速后端DNN 模块支持 OpenVINO(Intel)、Vulkan、CUDA、Halide 后端
OpenCV vs 其他视觉库对比 维度 OpenCV Pillow (PIL) scikit-image 定位 全栈视觉库 图像 I/O 学术算法 语言 C++ 核心 纯 Python 纯 Python 性能 ★★★★★ ★★ ★★★ DNN 内置 无 无 硬件加速 SIMD/CUDA/OpenVINO 无 有限
OpenCV 是唯一覆盖全栈、内置 DNN、多硬件后端的视觉库

十二、应用场景全景

OpenCV 应用场景全景 OpenCV 2500+ 算法 工业视觉检测 尺寸测量/缺陷检测 对位/引导 OCR 读码 自动驾驶 车道线检测 目标检测 多摄像头拼接 机器人 SLAM 视觉里程计 特征点地图 抓取定位 人脸识别 人脸检测 表情/活体 AR 滤镜 安防监控 运动检测 车牌识别 行为分析 医疗影像 CT/MRI 分割 细胞计数 病灶检测 智慧农业 果实计数 病害识别 杂草分类 AR / VR 标记追踪 姿态估计 场景重建
OpenCV 八大应用领域:工业/自动驾驶/机器人/人脸/安防/医疗/农业/AR

十三、最简示例

13.1 C++ 版:读图 → 灰度化 → Canny → 显示

// main.cpp — 编译: g++ main.cpp -o main $(pkg-config --cflags --libs opencv4)
#include <opencv2/opencv.hpp>

int main() {
    // 1. 读取图像(默认 BGR 三通道)
    cv::Mat img = cv::imread("test.jpg");
    if (img.empty()) return -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.5);

    // 4. Canny 边缘检测
    cv::Mat edges;
    cv::Canny(blurred, edges, 100, 200);

    // 5. 显示结果
    cv::imshow("原始", img);
    cv::imshow("边缘", edges);
    cv::waitKey(0);  // 按任意键关闭
    return 0;
}

13.2 Python 版:等价五行代码

# main.py — 运行: python main.py
import cv2 as cv

img   = cv.imread("test.jpg")          # 1. 读图
gray  = cv.cvtColor(img, cv.COLOR_BGR2GRAY)  # 2. 灰度
blur  = cv.GaussianBlur(gray, (5,5), 1.5)     # 3. 模糊
edges = cv.Canny(blur, 100, 200)          # 4. 边缘
cv.imshow("edge", edges); cv.waitKey(0)   # 5. 显示

13.3 进阶:YOLOv5 目标检测推理(DNN 模块)

import cv2 as cv
import numpy as np

# 1. 加载 ONNX 模型
net = cv.dnn.readNetFromONNX("yolov5s.onnx")
net.setPreferableBackend(cv.dnn.DNN_BACKEND_CUDA)
net.setPreferableTarget(cv.dnn.DNN_TARGET_CUDA)

# 2. 图像预处理 → blob(resize + 归一化 + 通道交换)
img = cv.imread("street.jpg")
blob = cv.dnn.blobFromImage(img, 1/255.0, (640,640), swapRB=True)

# 3. 前向推理
net.setInput(blob)
detections = net.forward()

# 4. 后处理(NMS + 画框,此处省略)
# detections → [x, y, w, h, conf, class_id] → 过滤 → 画框
cv.imshow("det", img); cv.waitKey(0)
新手最快上手路径
1. 安装:pip install opencv-python(Python 版,开箱即用)
2. 跑 13.2 节五行代码,看到边缘图 = 入门成功
3. 把 Canny 换成 threshold、HoughCircles 等函数,逐步探索更多能力

十四、总结

OpenCV 核心要点速查

  • 定位:计算机视觉"瑞士军刀",2500+ 算法覆盖从 I/O 到 DNN 推理的全链路
  • 核心数据结构:cv::Mat —— 图像即矩阵,灰度 H×W,彩色 H×W×3(BGR)
  • 六大能力域:I/O → 图像处理 → 特征检测 → 几何标定 → 目标检测 → 深度学习推理
  • 色彩空间:BGR(存储/显示)、Gray(检测)、HSV(颜色分割)、LAB(色差比较)
  • 经典流程:读图→灰度→滤波→边缘/特征→检测/匹配→输出
  • DNN 模块:ONNX/Caffe/TF → blob → forward → NMS,一行 readNetFromONNX 搞定推理
  • 加速:SIMD 自动 + CUDA/OpenVINO 可选,同一套代码跨设备
  • 生态:工业检测、自动驾驶、机器人 SLAM、人脸识别、安防监控、医疗影像、AR/VR

— 全文完 —