3、图像处理基础回顾:色彩空间、滤波、边缘检测与特征点提取

各位同学,欢迎来到第三章。在正式进入视频行为识别之前,咱们得先把图像处理的老底子翻出来晒一晒。你想想看,视频说白了就是一帧一帧的图像在快速播放。如果连单张图像的基本操作都搞不定,那视频分析就是空中楼阁。

这一章,我会带你快速过一遍四个核心模块:色彩空间、图像滤波、边缘检测、特征点提取。嗯,都是老面孔了,但咱们这次换个视角——从「视频行为识别」的角度重新审视它们。

3.1 色彩空间:RGB 与 HSV

先说色彩空间。RGB 大家最熟了,红绿蓝三通道叠加。但说实话,在视频分析里,RGB 有时候并不好用。为什么?因为 RGB 对光照变化太敏感了。你想想看,同一个动作,白天和晚上拍出来的 RGB 值可能天差地别。

我个人习惯在行为识别任务中,优先尝试 HSV 色彩空间。H 是色调,S 是饱和度,V 是明度。把亮度信息单独拎出来,这样算法就不容易被光照干扰了。

核心区别:

  • RGB:面向硬件显示,三通道强相关,光照敏感
  • HSV:面向人类视觉感知,色调和亮度分离,光照鲁棒

我在项目中遇到过这样一个场景:做室内跌倒检测,白天效果很好,一到晚上灯光偏黄,RGB 模型直接崩了。后来我把输入转成 HSV,只取 H 和 S 通道,效果立马稳住了。

# OpenCV 中 RGB 转 HSV
import cv2
import numpy as np

img_bgr = cv2.imread('frame.jpg')  # OpenCV 默认是 BGR
img_hsv = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2HSV)

# 提取色调和饱和度,忽略明度
hue = img_hsv[:, :, 0]
sat = img_hsv[:, :, 1]
val = img_hsv[:, :, 2]  # 这个可以扔掉,或者做归一化

小技巧:OpenCV 里 HSV 的 H 范围是 0-179,不是 0-359。别问我为什么,问就是历史遗留问题。我第一次用的时候踩过这个坑,调了半天颜色阈值都不对。

3.2 图像滤波:高斯滤波与中值滤波

滤波说白了就是去噪。视频里噪声太多了,传感器噪声、压缩噪声、运动模糊……不滤波直接做检测,结果会很难看。

3.2.1 高斯滤波

高斯滤波是线性滤波,用高斯核做卷积。它对高斯噪声(比如传感器热噪声)效果很好。但有个问题——它会模糊边缘。你想想看,边缘信息对行为识别多重要,模糊了还怎么判断姿势?

# 高斯滤波
blurred = cv2.GaussianBlur(img, (5, 5), sigmaX=1.5)

参数 (5,5) 是核大小,sigmaX 是标准差。核越大越模糊,sigma 越大也越模糊。我建议在视频预处理中,核大小不要超过 5,否则细节丢太多。

3.2.2 中值滤波

中值滤波是非线性的。它取窗口内所有像素的中位数,而不是平均值。这玩意儿对椒盐噪声(就是那种黑白点噪声)简直是克星。

我曾经在工厂监控视频里做异常检测,画面里经常有电火花产生的椒盐噪声。用高斯滤波根本去不干净,换成中值滤波,世界清净了。

# 中值滤波
median = cv2.medianBlur(img, 5)  # 核大小必须是奇数

注意:中值滤波计算量比高斯滤波大,尤其是核窗口大的时候。实时视频处理要权衡一下。我一般用 3x3 或 5x5,再大就扛不住了。

3.3 边缘检测:Canny 算子

边缘检测是行为识别的基石。人体轮廓、肢体边缘、物体边界……这些信息对理解「人在做什么」至关重要。

Canny 算子是目前最经典的边缘检测算法,没有之一。它分四步走:

  1. 高斯滤波去噪——先模糊一下,避免噪声被当成边缘
  2. 计算梯度幅值和方向——用 Sobel 算子算一下
  3. 非极大值抑制——只保留梯度方向上的局部最大值,把粗边缘变细
  4. 双阈值检测——高阈值确定强边缘,低阈值连接弱边缘

嗯,这里要注意:双阈值是 Canny 的精髓。高阈值设太高,边缘断断续续;设太低,一堆假边缘。我一般设高阈值 100-150,低阈值 50-75,具体看场景调。

# Canny 边缘检测
edges = cv2.Canny(img, threshold1=50, threshold2=150)

在视频行为识别中,我经常把 Canny 结果作为额外的输入通道,跟 RGB 一起喂给网络。效果嘛,谁用谁知道。

避坑指南:我曾经在低光照视频上直接用 Canny,结果全是噪声。后来发现要先做一次直方图均衡化,把对比度拉起来,Canny 才能正常工作。

3.4 特征点提取:SIFT 与 ORB

特征点提取,说白了就是找图像里「与众不同」的点。角点、斑点、纹理突变处……这些点在视频帧之间相对稳定,可以用来做匹配、跟踪、甚至动作识别。

3.4.1 SIFT(尺度不变特征变换)

SIFT 是经典中的经典。它提取的特征点对旋转、尺度缩放、光照变化都有很强的鲁棒性。但缺点也很明显——慢,而且有专利保护(虽然过期了)。

# SIFT 特征提取
sift = cv2.SIFT_create()
keypoints, descriptors = sift.detectAndCompute(img, None)

# 绘制特征点
img_with_kp = cv2.drawKeypoints(img, keypoints, None)

每个 SIFT 特征点有 128 维的描述子。在视频里,你可以用这些描述子做帧间匹配,判断运动是否异常。比如,正常行走时特征点的运动轨迹是有规律的,突然乱飞可能就是异常。

个人经验:SIFT 在纹理丰富的场景下表现极好,但在纯色墙面、光滑地面这种「没纹理」的地方,特征点会很少。这时候别硬用,换个方法。

3.4.2 ORB(定向 FAST 和旋转 BRIEF)

ORB 是 SIFT 的「轻量替代品」。它结合了 FAST 角点检测和 BRIEF 描述子,速度比 SIFT 快一个数量级。在实时视频处理中,我几乎首选 ORB。

# ORB 特征提取
orb = cv2.ORB_create(nfeatures=500)
keypoints, descriptors = orb.detectAndCompute(img, None)

# ORB 描述子是二进制,可以用汉明距离匹配
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
matches = bf.match(descriptors1, descriptors2)

ORB 的缺点是对尺度变化比较敏感。如果视频里人忽远忽近,ORB 匹配效果会下降。这时候我可能会用 SIFT,或者对图像做多尺度处理。

性能对比:

算法 速度 鲁棒性 适用场景
SIFT 高(尺度、旋转、光照) 离线分析、高精度匹配
ORB 中(旋转好,尺度差) 实时视频、移动端

3.5 本章小结

好,这一章咱们把图像处理的老底子翻了一遍。色彩空间、滤波、边缘检测、特征点提取——这四个模块在视频行为识别里各有各的用处。

我个人建议,在实际项目中不要死磕某一个方法。RGB 不行就换 HSV,高斯不行就换中值,SIFT 太慢就换 ORB。灵活组合才是王道。

下一章,咱们会正式进入视频处理的核心——光流法与帧差法。到时候你会发现,今天讲的这些基础,全都会用上。

一句话总结:图像处理是视频分析的「地基」。地基不稳,楼盖得再高也得塌。