跳转到内容

OpenCV — 计算机视觉库

待复核

OpenCV 是一个把图片和视频变成可计算数据的开源计算机视觉库。 日常类比:它像一套厨房工具箱,刀、锅、滤网、秤都放在一起;你可以先洗菜切菜,也可以直接把食材送进高级料理机。

在视觉任务里,“食材”就是图像像素,“工具”就是滤波、边缘、特征点、几何变换、目标跟踪和 DNN 推理。 OpenCV 的价值不在某一个神奇模型,而在于把这些基础工具放进同一套 C++/Python/Java API 里。

最小例子:

import cv2 as cv
img = cv.imread("input.jpg")
assert img is not None, "路径错了时 imread 会返回 None"
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
edges = cv.Canny(gray, 80, 160)
cv.imwrite("edges.png", edges)

这段代码完成三件事:读图、转灰度、找边缘。 如果你第一次看到”机器看懂图像”,OpenCV 是最容易摸到的入口。

不理解 OpenCV,下面这些事都没法解释:

  • 为什么很多 CV 教程从 cv.imreadcv.GaussianBlurcv.Canny 开始,而不是直接上深度学习
  • 为什么机器人、工业相机、安防视频和手机 AR 都需要同一批”几何 + 图像处理”基础件
  • 为什么深度学习模型上线前后仍要做 resize、颜色转换、NMS、可视化框等工程处理
  • 为什么一个库能同时服务课堂作业、原型验证、工厂质检和 DNN 推理

OpenCV 可以拆成 三层心智模型

  1. 像素清洗层:滤波、阈值、形态学、边缘检测。类比:拍照前先擦镜头、调亮度、去噪点;图像干净了,后面的判断才不会被灰尘骗。
  2. 几何理解层:特征点、匹配、相机标定、单应矩阵、光流和跟踪。类比:你拿地图找同一个路口,不能只看颜色,还要看路口之间的相对位置。
  3. 模型推理层cv.dnn 能加载 Caffe、TensorFlow、Darknet、ONNX 等模型做分类或检测。类比:前两层像准备材料,DNN 像请专家判断,但输入尺寸、颜色顺序和后处理仍要你准备对。

这三层组合起来,解释了 OpenCV 为什么像”视觉工程瑞士军刀”。 它不是只会一种算法,而是把从摄像头到结果图的流水线都接了起来。

官方滤波教程把图像平滑讲成低通滤波:先把局部像素平均掉,再减少噪声对边缘检测的干扰。 一个入门脚本可以这样写:

Terminal window
python -m pip install opencv-python numpy
python denoise_edges.py
import cv2 as cv
img = cv.imread("receipt.jpg")
assert img is not None
blurred = cv.GaussianBlur(img, (5, 5), 0)
gray = cv.cvtColor(blurred, cv.COLOR_BGR2GRAY)
edges = cv.Canny(gray, 60, 180)
cv.imwrite("receipt_edges.png", edges)

逐部分解释

  • GaussianBlur 用高斯核平滑图片,适合先压掉相机噪声
  • cvtColor 把 BGR 彩色图转成灰度图,边缘检测只需要亮度变化
  • Canny 输出黑白边缘图,后续可以接轮廓、直线检测或 OCR 预处理

这个案例常见于票据、白板、纸张边界和工业零件轮廓。 它不需要训练模型,靠的是经典图像处理。

案例 2:在杂乱照片里找到同一个物体

Section titled “案例 2:在杂乱照片里找到同一个物体”

官方特征匹配教程用 SIFT + FLANN + findHomography 找盒子:先找两张图里的稳定点,再估计一个透视变换。 缩短后的 Python 版本如下:

import cv2 as cv
import numpy as np
query = cv.imread("box.png", cv.IMREAD_GRAYSCALE)
scene = cv.imread("box_in_scene.png", cv.IMREAD_GRAYSCALE)
sift = cv.SIFT_create()
kq, dq = sift.detectAndCompute(query, None)
ks, ds = sift.detectAndCompute(scene, None)
matcher = cv.FlannBasedMatcher(dict(algorithm=1, trees=5), dict(checks=50))
pairs = matcher.knnMatch(dq, ds, k=2)
good = [m for m, n in pairs if m.distance < 0.7 * n.distance]
src = np.float32([kq[m.queryIdx].pt for m in good]).reshape(-1, 1, 2)
dst = np.float32([ks[m.trainIdx].pt for m in good]).reshape(-1, 1, 2)
H, mask = cv.findHomography(src, dst, cv.RANSAC, 5.0)

逐部分解释

  • SIFT_create 找角点和纹理点,尽量选旋转、缩放后还稳定的特征
  • knnMatch 给每个查询特征找两个候选,0.7 比值测试过滤模糊匹配
  • findHomography 用 RANSAC 排除离群点,估计”这张平面图被拍歪后在哪里”

这个案例适合海报识别、包装定位、AR 标记和相机姿态估计的入门版本。 关键不是”像素完全相同”,而是”局部特征和几何关系能对上”。

案例 3:用 DNN 模块跑一个图片分类模型

Section titled “案例 3:用 DNN 模块跑一个图片分类模型”

OpenCV 的 DNN 教程展示过用 GoogLeNet 对图片分类:模型来自 Caffe,OpenCV 负责读模型、预处理、前向推理和显示结果。 命令行形态大致是:

Terminal window
python samples/dnn/classification.py \
--model=bvlc_googlenet.caffemodel \
--config=bvlc_googlenet.prototxt \
--width=224 --height=224 \
--classes=classification_classes_ILSVRC2012.txt \
--input=space_shuttle.jpg \
--mean="104 117 123"

如果自己写最小代码,核心步骤是:

import cv2 as cv
net = cv.dnn.readNet("model.onnx")
frame = cv.imread("dog.jpg")
blob = cv.dnn.blobFromImage(frame, 1 / 255.0, (224, 224), swapRB=True)
net.setInput(blob)
scores = net.forward()

逐部分解释

  • readNet 只负责加载推理图,不训练模型
  • blobFromImage 把普通图片变成模型期望的 NCHW 四维输入
  • forward 做一次前向推理,输出还要按任务解释成类别、框或分割图

这个案例适合把现成模型塞进传统视觉流水线里。 例如先用 OpenCV 切出候选区域,再用 DNN 判断类别。

  1. imread 失败不是抛异常:路径错、中文路径或权限问题时常返回 None,后面函数才爆出难懂错误。
  2. OpenCV 默认 BGR,不是 RGB:Matplotlib、Pillow 和多数深度学习模型常按 RGB 解释,颜色顺序错会让红蓝互换。
  3. 坐标顺序容易混:图像数组常是 row, col,绘图函数常要 x, y,把高宽当宽高会让框画到奇怪位置。
  4. pip install opencv-python 不等于完整源码构建:CUDA、contrib、GUI、视频编解码能力取决于 wheel 或 CMake 选项。

适用

  • 快速验证图像处理、特征匹配、相机几何和视频读写思路
  • 需要把摄像头、图片、传统算法和 DNN 推理串成一条工程流水线
  • 工业质检、机器人、AR、教学实验这类要看中间结果的任务
  • 需要跨平台 API:C++ 主干,Python 快速试验,Java/Android 做应用集成

不适用

  • 大规模深度学习训练 → 用 PyTorch、JAX 或 TensorFlow 更合适
  • 只做批量图片格式转换 → ImageMagick / libvips 命令行更直接
  • 只做视频转码和封装 → FFmpeg 是更底层也更完整的媒体工具
  • 需要端到端产品标注、训练、部署平台 → OpenCV 只是库,不替你做 MLOps
  • 1999 年前后:Intel Research 开始推动 OpenCV,希望机器视觉不要停在论文和私有代码里。
  • 2000 年 6 月:OpenCV 对外发布,后来官方也把 “Since June 2000” 写进项目介绍。
  • 2008 年前后:Willow Garage 等机器人社区深度使用它,OpenCV 和 ROS 时代的机器人视觉绑得很紧。
  • 2015-2018 年:OpenCV 3 到 OpenCV 4 逐步稳定,cv.dnn 让它能承接深度学习推理。
  • 今天:OpenCV 仍是很多课程、样例和工程原型的共同语言,星标约 81k。
  1. OpenCV 的核心不是某个模型,而是一条视觉流水线:读图、预处理、几何、跟踪、推理、显示都在同一套 API 里。
  2. 经典 CV 仍然有用:滤波、边缘、特征点和单应矩阵在可解释、少数据、实时场景里常比盲目训练更稳。
  3. DNN 推理离不开工程细节:尺寸、均值、颜色、NMS、可视化和性能后端都会影响最后结果。
  4. 会用 OpenCV 等于会拆问题:先把”看懂图片”拆成输入、清洗、几何关系、模型判断和输出验证。
  • imagemagick —— 更偏命令行批处理,和 OpenCV 的算法流水线互补
  • ffmpeg —— 视频解码、转码和封装常放在 OpenCV 流水线前后
  • halide —— 同样关心图像处理性能,但把算法和调度拆得更激进
  • scikit-learn —— 传统机器学习工具箱,和 OpenCV 的 ml 模块在入门分类上有交集
  • pytorch —— 深度学习训练主力,训练后的模型常通过 ONNX 或 DNN 模块接入 OpenCV
  • clip —— 现代图文模型代表,和 OpenCV 的传统视觉路线形成对照
  • colmap —— COLMAP — 多视图 SfM/MVS 重建
  • cvat —— CVAT — 视频帧标注与半自动追踪的开源王者
  • dlib —— dlib — C++ 机器学习 / CV 工具箱
  • insightface —— InsightFace — 人脸识别 / 检测 SOTA 工具箱
  • mediapipe —— MediaPipe — Google ML 多模态流水线
  • pillow —— Pillow — Python 图像处理
  • sam2 —— SAM 2 — 图像和视频都能抠轮廓的通用分割模型
  • ultralytics —— Ultralytics — YOLOv8/v11 易用 SDK