Skip to content

传统计算机视觉与 OpenCV

传统计算机视觉(CV)依赖手工设计的特征和经典算法来完成图像处理与分析任务;OpenCV 是这一领域最核心的开源库。理解传统方法,既能应对嵌入式、实时、小数据等场景,也有助于深入理解深度学习方法的优势与局限。前置阅读:CNN 主线、目标检测与 YOLO。

把图像处理想象成”暗房冲洗照片”——你用一系列确定的手工操作(调色、遮罩、冲洗、显影)逐步从原始底片得到想要的结果:

  • 传统 CV = 你亲手设计每一步:用 Sobel 算子”描边”、用高斯模糊”磨皮”、用 Haar 特征”找眼睛”、用 SVM 分类。每一步的数学含义都清清楚楚,但每换一个任务就要重新设计一套流程。
  • 深度学习 CV = 你把一堆照片和标签丢给 CNN,让它自己摸索出”该怎么处理”。精度通常更高,但过程是黑箱——你很难说清第 7 层卷积核到底学到了什么。
  • OpenCV = 传统 CV 的”万能工具箱”——从读图到特征匹配,几千个函数覆盖了几乎所有经典操作,一台普通 CPU 就能跑,是嵌入式和工业场景的常驻选择。

两种范式在方法论上根本不同:

维度传统 CV深度学习 CV
特征来源人工设计(SIFT、HOG、Haar)自动学习(卷积核)
流程结构多阶段管线,每步独立调参端到端,整体优化
数据需求少量即可,有时无需训练需大量标注数据
硬件要求CPU 即可,无需 GPU通常需 GPU 才实用
可解释性每一步都有明确数学含义黑箱,难以解释
精度上限复杂任务上受限SOTA 精度
泛化能力对光照/视角变化敏感数据多样时泛化更强
部署成本轻量,嵌入式友好模型大,推理开销高

OpenCV 提供了传统 CV 的完整工具链,核心模块包括:

  • 图像读写:imread / imwrite 支持 JPEG、PNG、TIFF 等常见格式,读取后默认为 BGR 格式的 NumPy 数组。
  • 色彩空间转换(cvtColor):BGR ↔ RGB、BGR ↔ GRAY、BGR ↔ HSV、BGR ↔ LAB。HSV 空间常用于基于颜色的目标检测(如追踪红色物体),因为色相(H)与亮度解耦。
  • 几何变换:缩放(resize)、旋转(getRotationMatrix2D + warpAffine)、仿射变换(getAffineTransform)、透视变换(getPerspectiveTransform + warpPerspective)。
  • 图像滤波:盒式滤波、高斯模糊(GaussianBlur)、中值滤波(medianBlur,有效去椒盐噪声)、双边滤波(bilateralFilter,保边平滑)。
  • 边缘检测:Sobel 算子(一阶梯度)、Laplacian(二阶梯度)、Canny(多阶段边缘检测,工业标准)。
  • 形态学操作:腐蚀(erode)、膨胀(dilate)、开运算、闭运算、形态学梯度——用于去噪、填充孔洞、提取边界。
  • 直方图:calcHist 统计像素分布,equalizeHist 直方图均衡化以增强对比度。
  • 轮廓检测:findContours 提取二值图中的连通区域,drawContours 绘制,可计算面积、周长、外接矩形。
  • 特征检测与匹配:ORB、SIFT(专利已于 2020 年过期,现免费使用)、AKAZE 等特征点检测与描述子,BFMatcher / FlannBasedMatcher 做特征匹配。

传统 CV 大量操作本质上是卷积(convolution)——一个小的权重矩阵(卷积核/滤波器)在图像上滑动,逐位置做点积。你可以把它想象成”拿一个放大镜在照片上逐像素滑动,每到一个位置就用镜片上的权重模板和底下的像素做加权求和,输出一个新的像素值”。

二维卷积的数学定义(严格地说,以下写的是互相关 cross-correlation,深度学习框架和 OpenCV 的”卷积”通常指这个):

(I∗K)(x,y)=∑i=−aa∑j=−bbI(x+i, y+j)⋅K(i,j)(I * K)(x, y) = \sum_{i=-a}^{a} \sum_{j=-b}^{b} I(x+i,\, y+j) \cdot K(i, j)

其中 II 是输入图像,KK 是大小为 (2a+1)×(2b+1)(2a+1) \times (2b+1) 的卷积核。输出图像每个像素 = 核覆盖区域内像素与核权重的逐元素乘积之和。

卷积核权重采样自二维高斯函数:

G(x,y)=12πσ2 e−x2+y22σ2G(x, y) = \frac{1}{2\pi\sigma^2} \, e^{-\frac{x^2+y^2}{2\sigma^2}}

σ\sigma 越大,模糊越强。OpenCV 的 GaussianBlur(img, ksize, sigmaX) 中,当 sigmaX=0 时会根据核大小自动推算 σ≈0.3×((ksize−1)×0.5−1)+0.8\sigma \approx 0.3 \times ((ksize-1)\times0.5 - 1) + 0.8。一个 5×55\times5、σ=1.0\sigma=1.0 的归一化高斯核大约长这样:

[[ 0.003, 0.013, 0.022, 0.013, 0.003],
[ 0.013, 0.060, 0.098, 0.060, 0.013],
[ 0.022, 0.098, 0.162, 0.098, 0.022],
[ 0.013, 0.060, 0.098, 0.060, 0.013],
[ 0.003, 0.013, 0.022, 0.013, 0.003]]

中心权重大、四角接近 0,效果是平滑图像、抑制高频噪声。类比:就像音频里的低通滤波器,只留下”低频”(变化缓慢的大块区域),去掉”高频”(噪声和细节)。

两个方向(水平 SxS_x、垂直 SyS_y)的卷积核分别检测横向和纵向的灰度突变。标准 3×33\times3 Sobel 核:

Sx=[−101−202−101],Sy=[−1−2−1000121]S_x = \begin{bmatrix} -1 & 0 & 1 \\ -2 & 0 & 2 \\ -1 & 0 & 1 \end{bmatrix}, \quad S_y = \begin{bmatrix} -1 & -2 & -1 \\ 0 & 0 & 0 \\ 1 & 2 & 1 \end{bmatrix}

梯度幅值 G=Sx2+Sy2G = \sqrt{S_x^2 + S_y^2},梯度方向 θ=arctan⁡(Sy/Sx)\theta = \arctan(S_y / S_x)。中间行/列权重为 2 是为了给中心行/列更高权重(类似平滑),减少噪声干扰。

Laplacian 核近似图像的拉普拉斯算子 ∇2I=∂2I∂x2+∂2I∂y2\nabla^2 I = \frac{\partial^2 I}{\partial x^2} + \frac{\partial^2 I}{\partial y^2},对噪声更敏感,常用于检测零交叉点:

L=[0101−41010]L = \begin{bmatrix} 0 & 1 & 0 \\ 1 & -4 & 1 \\ 0 & 1 & 0 \end{bmatrix}

在高斯模糊 + Sobel 梯度的基础上,加入非极大值抑制(Non-Maximum Suppression, NMS:沿梯度方向只保留局部最大像素,把粗边”削薄”成单像素)和双阈值滞后(hysteresis:高于高阈值的标为强边缘,低于低阈值的丢弃,介于两者之间的只有与强边缘连通时才保留),输出细而连续的单像素边缘——是传统边缘检测的黄金标准。Canny 本质上是一个多阶段流水线(高斯模糊 → 梯度 → NMS → 滞后阈值),每一步都有明确数学含义,这也是传统方法”可解释性”的典型代表。

卷积核中心为正值、四邻为负值,本质是增强高频分量:

Sharpen=[0−10−15−10−10]\text{Sharpen} = \begin{bmatrix} 0 & -1 & 0 \\ -1 & 5 & -1 \\ 0 & -1 & 0 \end{bmatrix}

类比:把图像减去一个模糊版本(即”非锐化掩蔽 Unsharp Masking”),差别越大说明这里细节越多,加回去就强化了细节。

这些手工卷积核启发了 CNN——CNN 只是把”人工设计卷积核”变成”从数据中学习卷积核”。一个关键洞察是:Sobel、高斯等手工核都是 3×33\times3 或 5×55\times5 的小核在局部区域做加权求和,与 CNN 第一层卷积在数学形式上完全一致。区别只在于权重从”人凭经验设定”变成”通过反向传播从数据中优化”。

手工特征是传统 CV 的灵魂,以下是主要方法的完整谱系:

  • Harris 角点(1988):通过局部自相关函数检测角点——在角点处,沿任意方向移动窗口灰度都剧烈变化。计算快,但只是检测器(不提供描述子)。
  • SIFT(1999/2004):尺度不变特征变换。在多尺度空间检测极值点,为每个关键点生成 128 维梯度方向直方图描述子。对旋转、缩放、光照变化具有不变性,是传统特征匹配的里程碑。
  • SURF(2006):SIFT 的加速版,用积分图像和 Haar 小波近似,速度快 3-5 倍,但长期有专利限制。
  • ORB(2011):FAST 角点检测 + BRIEF 描述子的旋转不变改进版,速度极快且无专利限制,是 OpenCV 默认的实时特征匹配方法。
  • HOG(2005):方向梯度直方图。将图像分成小 cell,统计每个 cell 内的梯度方向分布,拼接成高维特征向量。配合 SVM 分类器,曾是行人检测的标杆方案。
  • Haar 特征(2001):黑白矩形模板,计算覆盖区域的亮度差。配合级联分类器(AdaBoost),是 Viola-Jones 人脸检测的基础——开创了实时目标检测时代。
  • LBP(1996):局部二值模式。对每个像素,比较它与 8 邻域的大小关系生成 8 位二进制码,统计直方图作为纹理描述。常用于人脸识别和纹理分类。

深度学习之前,目标检测依赖手工特征 + 经典分类器的组合:

  • Viola-Jones / Haar 级联(2001):使用 Haar 特征 + AdaBoost 级联分类器。核心创新是级联结构——前几级用少量特征快速排除大部分非目标窗口,只有通过所有级的窗口才判为目标。实现了首个实时人脸检测系统,数码相机人脸对焦即基于此。
  • HOG + SVM / DPM(2008-2010):HOG 特征 + 线性 SVM 做行人检测;DPM(可变形部件模型)在此基础上将目标分解为多个部件,用弹簧模型约束部件间关系,是 PASCAL VOC 时代的 SOTA。相比 Viola-Jones,能处理更复杂的多类别目标。

传统方法需要人工设计多阶段流程,深度学习则端到端学习:

从读取图像到轮廓检测的完整传统 CV 流程:

import cv2
import numpy as np
# 1. 读取图像并转灰度
img = cv2.imread("objects.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 2. 高斯模糊去噪(5x5 卷积核)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
# 3. Canny 边缘检测(低阈值50,高阈值150)
edges = cv2.Canny(blurred, 50, 150)
# 4. 查找轮廓并按面积排序,取前5个
contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = sorted(contours, key=cv2.contourArea, reverse=True)[:5]
# 5. 绘制外接矩形并显示
for c in contours:
x, y, w, h = cv2.boundingRect(c)
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.imshow("Contours", img)
cv2.waitKey(0)

用 SIFT 检测两幅图像的关键点并进行特征匹配:

import cv2
# 读取两张图(如同一物体的不同角度)
img1 = cv2.imread("scene_a.jpg", cv2.IMREAD_GRAYSCALE)
img2 = cv2.imread("scene_b.jpg", cv2.IMREAD_GRAYSCALE)
# SIFT 检测关键点 + 计算描述子
sift = cv2.SIFT_create()
kp1, des1 = sift.detectAndCompute(img1, None)
kp2, des2 = sift.detectAndCompute(img2, None)
# 用 FLANN 匹配器做快速近似最近邻匹配
flann = cv2.FlannBasedMatcher()
matches = flann.knnMatch(des1, des2, k=2)
# Lowe 比率检验:过滤掉歧义匹配,只保留高质量匹配点
good = [m for m, n in matches if m.distance < 0.7 * n.distance]
result = cv2.drawMatches(img1, kp1, img2, kp2, good, None)
cv2.imshow("SIFT Matches", result)
cv2.waitKey(0)
  • 先灰度再处理:大多数特征提取(SIFT、HOG、边缘检测)只需灰度图。彩色信息对颜色检测(HSV 追踪)有用,但会徒增计算量。
  • 高斯模糊几乎是必做的预处理:在做边缘检测或阈值分割前先模糊,能有效抑制噪声产生的假边缘。核大小(5x5、7x7)取决于噪声水平。
  • Canny 的双阈值很关键:低阈值/高阈值之比建议 1:2 或 1:3。阈值过高会漏检边缘,过低会产生大量碎片。
  • 形态学操作处理二值图:阈值分割后的二值图常有孔洞和毛刺,用闭运算(先膨胀后腐蚀)填孔洞,用开运算(先腐蚀后膨胀)去噪点。
  • 传统方法在纹理/结构稳定的工业场景极强:因为光照、角度可控,手工特征反而比深度学习更稳定、更快、更省资源。
  • 不要用过时的 Haar 级联做人脸检测:精度远不如深度学习方案(如 MTCNN、RetinaFace)。Haar 级联更适合无 GPU 的嵌入式兜底场景。
  • 工业质检:PCB 焊点缺陷检测、零件尺寸测量——产线光照固定,传统视觉算法(边缘 + 轮廓 + 模板匹配)稳定可靠,无需 GPU。
  • 实时目标跟踪:无人机视觉跟踪、球类追踪——基于颜色(HSV)或特征点(ORB/KCF 跟踪器)的方案在嵌入式设备上可达 60+ FPS。
  • 医学影像预处理:CT/MRI 图像增强、配准、分割——直方图均衡、形态学操作是放射科流水线的标准预处理。
  • 移动端轻量视觉:文档扫描(边缘检测 + 透视矫正)、二维码识别、身份证裁剪——用 OpenCV 在手机 CPU 上即可实时完成。
  • 全景图拼接:手机全景拍照本质是 SIFT/ORB 特征匹配 + 单应性矩阵估计 + 图像融合,OpenCV 的 Stitcher 类封装了完整流程。
类库语言说明
OpenCVC++/Python/Java传统 CV 的标准库,5000+ 函数,覆盖图像处理、特征、几何、视频等全领域
scikit-imagePython基于 SciPy 的图像处理库,API 更 Pythonic,适合科研和原型
MahotasPython紧凑的图像处理库,侧重传统特征(Haralick 纹理、Zernike 矩等)
VLFeatC/MATLABSIFT、超向量编码等经典算法的参考实现,科研常用
SimpleCVPythonOpenCV 的简化封装,降低入门门槛
MediaPipeC++/PythonGoogle 的跨平台视觉管线框架,集成传统方法与轻量深度学习
术语英文解释
卷积核Kernel / Filter一个小的权重矩阵,在图像上滑动做点积,用于提取边缘、纹理等局部特征
高斯模糊Gaussian Blur使用高斯函数加权平均的平滑滤波,抑制高频噪声
Canny 边缘检测Canny Edge Detector多阶段边缘检测算法(高斯模糊→梯度→NMS→双阈值),传统边缘检测标准
形态学操作Morphological Operations基于集合论的二值图像操作(腐蚀、膨胀、开闭运算),用于去噪和形状分析
SIFTScale-Invariant Feature Transform尺度不变特征变换,对旋转缩放光照不变的局部特征描述子
HOGHistogram of Oriented Gradients方向梯度直方图,统计局部梯度方向分布的全局特征,行人检测经典
Haar 特征Haar-like Features黑白矩形模板的亮度差特征,配合 AdaBoost 级联做人脸检测
LBPLocal Binary Pattern局部二值模式,比较邻域像素大小关系的纹理描述子
级联分类器Cascade Classifier多级分类器串联,前级快速排除非目标,Viola-Jones 的核心结构
透视变换Perspective Transform将图像从一个平面投影到另一个平面,用于文档矫正和车道检测
HSV 色彩空间HSV Color Space色相-饱和度-明度表示法,将颜色与亮度解耦,便于颜色分割
  • Bradski,「The OpenCV Library」(2000):OpenCV 初始发布论文,介绍了这个改变了整个 CV 领域的开源库。
  • Lowe,「Distinctive Image Features from Scale-Invariant Keypoints」(IJCV 2004):SIFT 原始论文,传统特征匹配的里程碑,引用量 7 万+。
  • Dalal & Triggs,「Histograms of Oriented Gradients for Human Detection」(CVPR 2005):HOG 行人检测论文,传统目标检测的标杆方案。
  • Viola & Jones,「Rapid Object Detection using a Boosted Cascade of Simple Features」(CVPR 2001):Haar 级联人脸检测论文,首个实时目标检测系统。
  • Szeliski,「Computer Vision: Algorithms and Applications」(2nd ed., 2022):传统 CV 的经典教材,免费在线,系统覆盖经典方法全貌。