人工智能之视觉领域 计算机视觉
第十三章 视频背景减除
文章目录
- [人工智能之视觉领域 计算机视觉](#人工智能之视觉领域 计算机视觉)
- [前言:视频背景减除(Background Subtraction)](#前言:视频背景减除(Background Subtraction))
- [1. 通俗理解:什么是背景减除?](#1. 通俗理解:什么是背景减除?)
- [2. 核心思想:建模背景 + 检测变化](#2. 核心思想:建模背景 + 检测变化)
- [3. OpenCV 两大主流算法](#3. OpenCV 两大主流算法)
- [3.1 MOG2(高斯混合模型)](#3.1 MOG2(高斯混合模型))
- [3.2 KNN(K近邻背景减除)](#3.2 KNN(K近邻背景减除))
- [4. 完整工作流程(Mermaid 图)](#4. 完整工作流程(Mermaid 图))
- [5. 配套代码实战](#5. 配套代码实战)
- [示例 1:基础背景减除(MOG2)](#示例 1:基础背景减除(MOG2))
- [示例 2:完整运动物体检测(含去噪 + 轮廓绘制)](#示例 2:完整运动物体检测(含去噪 + 轮廓绘制))
- [示例 3:对比 MOG2 与 KNN 效果](#示例 3:对比 MOG2 与 KNN 效果)
- [6. 关键参数调优指南](#6. 关键参数调优指南)
- [7. 常见问题与解决方案](#7. 常见问题与解决方案)
- [❓ 问题1:前景全是噪点?](#❓ 问题1:前景全是噪点?)
- [❓ 问题2:运动物体被"掏空"(中间变黑)?](#❓ 问题2:运动物体被“掏空”(中间变黑)?)
- [❓ 问题3:背景缓慢变化(如云飘过)导致误检?](#❓ 问题3:背景缓慢变化(如云飘过)导致误检?)
- [❓ 问题4:如何只检测特定区域(如门口)?](#❓ 问题4:如何只检测特定区域(如门口)?)
- [8. 应用场景扩展](#8. 应用场景扩展)
- [✅ 本章总结](#✅ 本章总结)
- [✅ 本章总结](#✅ 本章总结)
- 资料关注
前言:视频背景减除(Background Subtraction)
学习目标:掌握使用 OpenCV 的 MOG2 和 KNN 背景减除器,从视频中自动分离出运动前景物体,去除静态背景,为监控、行为分析等任务提供基础。
1. 通俗理解:什么是背景减除?
想象你在看一段固定摄像头拍摄的街道视频:
- 路面、建筑、树木是静止的(背景)
- 行人、汽车是移动的(前景)
✅ 背景减除 = 自动"抠出"视频中所有运动的物体
输出是一张二值图:白色 = 运动物体,黑色 = 静态背景
这是智能监控、人流统计、入侵检测的第一步!
2. 核心思想:建模背景 + 检测变化
算法会:
- 学习前若干帧,建立"背景模型"
- 对每一新帧,比较当前像素与背景模型
- 若差异大 → 判定为前景(运动物体)
- 动态更新背景模型(适应光照变化、树叶晃动等)
3. OpenCV 两大主流算法
3.1 MOG2(高斯混合模型)
- 全称:Mixture of Gaussians v2
- 原理:每个像素用多个高斯分布建模,适应复杂场景
- 优点:对阴影鲁棒(可选是否检测阴影)
- 缺点:计算量稍大
python
bg_subtractor = cv2.createBackgroundSubtractorMOG2(
history=500, # 背景模型历史长度(帧数)
varThreshold=50, # 像素与模型匹配的阈值(越大越不敏感)
detectShadows=True # 是否检测阴影(True 会慢,但更准)
)
3.2 KNN(K近邻背景减除)
- 全称:K-Nearest Neighbors
- 原理:基于像素历史值的 K 近邻距离判断
- 优点:对光照突变适应性强
- 缺点:参数较敏感
python
bg_subtractor = cv2.createBackgroundSubtractorKNN(
history=500,
dist2Threshold=400, # 距离平方阈值
detectShadows=True
)
💡 初学者推荐 :先用
MOG2,效果稳定且支持阴影处理。
4. 完整工作流程(Mermaid 图)
是
否
打开视频/摄像头
创建背景减除器
cv2.createBackgroundSubtractorMOG2()
循环读取每一帧
fg_mask = subtractor.apply(frame)
是否需要后处理?
形态学去噪
morphologyEx()
直接使用 fg_mask
查找轮廓 findContours()
过滤小面积物体
绘制边界框或保存结果
5. 配套代码实战
示例 1:基础背景减除(MOG2)
python
import cv2
# 1. 创建 MOG2 背景减除器
subtractor = cv2.createBackgroundSubtractorMOG2(
history=500,
varThreshold=50,
detectShadows=True # 设为 False 可加速
)
# 2. 打开视频(可用摄像头 0 或视频文件)
cap = cv2.VideoCapture('street.mp4') # 或 0
while True:
ret, frame = cap.read()
if not ret:
break
# 3. 应用背景减除
fg_mask = subtractor.apply(frame)
# 4. 显示原始帧和前景掩码
cv2.imshow('Original Frame', frame)
cv2.imshow('Foreground Mask', fg_mask)
if cv2.waitKey(30) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
🔍 观察:
- 初始几秒画面全白(正在学习背景)
- 稳定后,只有行人/车是白色
- 阴影可能呈灰色(若
detectShadows=True)
示例 2:完整运动物体检测(含去噪 + 轮廓绘制)
python
import cv2
import numpy as np
# 创建背景减除器(关闭阴影检测以提速)
subtractor = cv2.createBackgroundSubtractorMOG2(
history=500,
varThreshold=50,
detectShadows=False
)
# 打开视频
cap = cv2.VideoCapture('people.mp4')
# 定义形态学核(用于去噪)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
while True:
ret, frame = cap.read()
if not ret:
break
# 背景减除
fg_mask = subtractor.apply(frame)
# 后处理:去除噪声
fg_mask = cv2.morphologyEx(fg_mask, cv2.MORPH_OPEN, kernel) # 开运算去白噪点
fg_mask = cv2.morphologyEx(fg_mask, cv2.MORPH_CLOSE, kernel) # 闭运算填黑洞
# 查找轮廓
contours, _ = cv2.findContours(fg_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 绘制有效运动物体
for cnt in contours:
area = cv2.contourArea(cnt)
if area > 500: # 过滤小噪点
x, y, w, h = cv2.boundingRect(cnt)
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
# 显示
cv2.imshow('Motion Detection', frame)
cv2.imshow('Foreground Mask (Cleaned)', fg_mask)
if cv2.waitKey(30) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
示例 3:对比 MOG2 与 KNN 效果
python
import cv2
# 创建两个减除器
mog2 = cv2.createBackgroundSubtractorMOG2(detectShadows=False)
knn = cv2.createBackgroundSubtractorKNN(detectShadows=False)
cap = cv2.VideoCapture('office.mp4')
while True:
ret, frame = cap.read()
if not ret:
break
mask_mog2 = mog2.apply(frame)
mask_knn = knn.apply(frame)
# 拼接显示
combined = np.hstack((frame,
cv2.cvtColor(mask_mog2, cv2.COLOR_GRAY2BGR),
cv2.cvtColor(mask_knn, cv2.COLOR_GRAY2BGR)))
cv2.putText(combined, 'Original | MOG2 | KNN', (10, 30),
cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2)
cv2.imshow('MOG2 vs KNN Comparison', combined)
if cv2.waitKey(30) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
6. 关键参数调优指南
| 参数 | 作用 | 调整建议 |
|---|---|---|
history |
背景模型记忆长度 | 场景变化慢 → 增大(1000)场景变化快 → 减小(200) |
varThreshold (MOG2) |
像素匹配灵敏度 | 噪点多 → 增大(100)漏检多 → 减小(20) |
dist2Threshold (KNN) |
KNN 距离阈值 | 同上 |
detectShadows |
是否保留阴影 | 需要精确轮廓 → False需保留完整人体 → True |
7. 常见问题与解决方案
❓ 问题1:前景全是噪点?
✅ 解决:
- 增大
varThreshold - 添加形态学开运算 (
MORPH_OPEN)去除孤立白点
❓ 问题2:运动物体被"掏空"(中间变黑)?
✅ 解决:
- 添加形态学闭运算 (
MORPH_CLOSE)填充内部孔洞 - 或使用
cv2.dilate()膨胀前景
❓ 问题3:背景缓慢变化(如云飘过)导致误检?
✅ 解决:
- 增大
history(如 1000) - 使用 KNN(对缓慢变化更鲁棒)
❓ 问题4:如何只检测特定区域(如门口)?
✅ 解决 :使用掩码(Mask)
python
# 创建 ROI 掩码(白色=检测区域)
mask_roi = np.zeros(frame.shape[:2], dtype=np.uint8)
cv2.rectangle(mask_roi, (100, 100), (400, 400), 255, -1)
# 应用掩码
fg_mask = cv2.bitwise_and(fg_mask, fg_mask, mask=mask_roi)
8. 应用场景扩展
| 应用 | 实现要点 |
|---|---|
| 人流统计 | 结合轮廓中心点 + 虚拟线计数 |
| 遗留物检测 | 检测"突然出现并长期不动"的物体 |
| 车辆违停 | 检测在禁停区持续存在的前景 |
| 智能家居 | 检测是否有人进入房间 |
✅ 本章总结
| 步骤 | 操作 | 函数 |
|---|---|---|
| 1. 创建减除器 | 选择 MOG2 或 KNN | cv2.createBackgroundSubtractorXXX() |
| 2. 应用减除 | 获取前景掩码 | subtractor.apply(frame) |
| 3. 后处理 | 去噪、补洞 | morphologyEx() |
| 4. 分析前景 | 轮廓检测、计数 | findContours() |
🌟 现在可以:
- 把监控视频中的行人"抠"出来
- 实现一个简单的"有人闯入"报警系统
- 为后续的目标跟踪 或行为识别提供干净的前景输入!
✅ 本章总结
| 步骤 | 操作 | 函数 |
|---|---|---|
| 1. 选目标 | 手动画框 or 自动检测 | cv2.selectROI() / detectMultiScale() |
| 2. 创建跟踪器 | 选择算法 | cv2.TrackerXXX_create() |
| 3. 初始化 | 第一帧设定位置 | tracker.init(frame, bbox) |
| 4. 更新 | 每帧获取新位置 | success, bbox = tracker.update(frame) |
| 5. 可视化 | 画框 + 状态提示 | cv2.rectangle() |
🌟 你现在可以:
- 用鼠标框住视频中的任意物体,让它被"锁定"
- 结合人脸检测,实现自动人脸跟踪
- 为智能监控、AR互动等项目打下基础!
资料关注
咚咚王
《Python编程:从入门到实践》
《利用Python进行数据分析》
《算法导论中文第三版》
《概率论与数理统计(第四版) (盛骤) 》
《程序员的数学》
《线性代数应该这样学第3版》
《微积分和数学分析引论》
《(西瓜书)周志华-机器学习》
《TensorFlow机器学习实战指南》
《Sklearn与TensorFlow机器学习实用指南》
《模式识别(第四版)》
《深度学习 deep learning》伊恩·古德费洛著 花书
《Python深度学习第二版(中文版)【纯文本】 (登封大数据 (Francois Choliet)) (Z-Library)》
《深入浅出神经网络与深度学习+(迈克尔·尼尔森(Michael+Nielsen)》
《自然语言处理综论 第2版》
《Natural-Language-Processing-with-PyTorch》
《计算机视觉-算法与应用(中文版)》
《Learning OpenCV 4》
《AIGC:智能创作时代》杜雨+&+张孜铭
《AIGC原理与实践:零基础学大语言模型、扩散模型和多模态模型》
《从零构建大语言模型(中文版)》
《实战AI大模型》
《AI 3.0》