人工智能之视觉领域 计算机视觉 第十三章 视频背景减除

人工智能之视觉领域 计算机视觉

第十三章 视频背景减除


文章目录

  • [人工智能之视觉领域 计算机视觉](#人工智能之视觉领域 计算机视觉)
  • [前言:视频背景减除(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. 核心思想:建模背景 + 检测变化

算法会:

  1. 学习前若干帧,建立"背景模型"
  2. 对每一新帧,比较当前像素与背景模型
  3. 若差异大 → 判定为前景(运动物体)
  4. 动态更新背景模型(适应光照变化、树叶晃动等)

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》

相关推荐
你的论文学长1 小时前
对抗知网的 N-Gram 算法:基于语义解耦的【文本重构】与【事实性核验】架构设计
人工智能·算法·重构
一水鉴天1 小时前
关于“整体设计定稿” 的高阶表述 20260222
人工智能·架构
美酒没故事°1 小时前
mac电脑安装OpenClaw步骤
人工智能·macos
沪漂阿龙1 小时前
大模型幻觉深度解析:成因、检测与工程缓解策略
人工智能·深度学习·机器学习
果冻虾仁2 小时前
vllm使用plugin集成外部模型结构
人工智能·后端
一马平川的大草原2 小时前
基于n8n构建企业内部知识库
人工智能·知识库·n8n
新缸中之脑2 小时前
AI 包装器的消亡
人工智能
紫微AI2 小时前
文件系统就是新的数据库:我是如何为 AI Agent 构建个人操作系统的
数据库·人工智能
l1t2 小时前
利用DeepSeek辅助把幻灯片markdown文件转换成pdf
人工智能·pdf