计算机视觉——Opencv(背景建模实现目标检测)

一、背景建模是是什么

指在计算机视觉中,从视频序列中提取出静态背景的一种技术。在视频中,背景通常被定义为相对稳定的部分,例如墙壁、地面或天空等。

背景建模的目标是将动态的前景对象与静态的背景进行分离,以便进一步分析和处理。

二、背景建模的目的

通过背景建模,我们可以实现很多应用,例如运动检测、目标跟踪

三、背景建模的方法

1、帧差法backgroundSubtractor

2、基于K近邻的背景/前景分割算法BackgroundSubtractorKNN

3、基于高斯混合的背景/前景分割算法BackgroundSubtractorMOG2

帧差法的原理

由于场景中的目标在运动,目标的影像在不同图像帧中的位置不同。该类算法对时间上连续的两帧图像进行差分运算,不同帧对应的像素点相减,判断灰度差的绝对值,当绝对值超过一定阈值时,即可判断为运动目标,从而实现目标的检测功能。

帧差法的优缺点

帧差法非常简单,但是会引入噪音和空洞(人物中间是黑色的)问题

四、核心技术原理

1、混合高斯模型(MOG2):背景建模与前景提取

视频由一帧帧连续的图像组成,运动目标检测的本质是区分 "静止背景" 和 "运动前景"

混合高斯模型(Gaussian Mixture Model, GMM)是实现这一目标的经典算法,OpenCV 封装的createBackgroundSubtractorMOG2是其优化版本,核心优势如下:

  • 自适应背景更新:能自动学习并更新背景模型,适应光线变化、背景轻微扰动(如树叶晃动)等场景;

  • 前景掩码输出:处理后会生成一张黑白掩码图(前景掩码),白色区域代表运动目标,黑色区域代表背景;

  • 无需手动标注:无需提前采集背景帧,可直接对视频流进行实时处理。

2、形态学开运算:去除噪点干扰

通过 MOG2 提取的前景掩码通常会包含大量细小噪点(如光线突变、视频压缩噪声),这些噪点会干扰后续的轮廓检测。形态学开运算(先腐蚀后膨胀)能有效解决这个问题:

  • 腐蚀:消除小的亮区域(噪点),收缩前景目标的边界;

  • 膨胀:恢复前景目标的原始大小,弥补腐蚀造成的边界收缩;

  • 组合效果:保留大面积的运动目标,去除零散的小噪点,让前景轮廓更规整。

3、轮廓检测与筛选:精准定位运动目标

在处理后的前景掩码基础上,通过轮廓检测找到所有连通的前景区域,再通过轮廓周长 / 面积筛选,排除小的无效区域,最终用矩形框标出真正的运动目标,实现 "检测 - 定位" 一体化

五、完整代码与解析

python 复制代码
import cv2

# 1. 读取测试视频文件(替换为你的视频路径)
cap = cv2.VideoCapture(r"E:\xwechat_files\wxid_qi43v1w2nqcb12_e432\msg\file\2026-01\test(1).avi")

# 2. 创建形态学运算卷积核(十字形,3x3)
# MORPH_CROSS:十字形核,适合保留目标的边缘特征;ksize=(3,3):核大小,越小越精细
kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, ksize=(3, 3))

# 3. 初始化混合高斯背景建模器
# createBackgroundSubtractorMOG2:默认参数已适配大多数场景,可添加detectShadows=False去除阴影检测
fgbg = cv2.createBackgroundSubtractorMOG2()

# 4. 循环处理视频每一帧
while True:
    # 读取当前帧:ret为布尔值(是否读取成功),frame为帧图像(BGR格式)
    ret, frame = cap.read()
    if not ret:  # 读取失败(如视频结束),退出循环
        break

    # 显示原始视频帧
    cv2.imshow('Original Frame', frame)

    # 5. 应用背景建模,提取前景掩码
    # fgmask:8位灰度图,白色(255)为前景(运动目标),黑色(0)为背景
    fgmask = fgbg.apply(frame)
    cv2.imshow('Foreground Mask (Raw)', fgmask)

    # 6. 形态学开运算:去除噪点,优化前景掩码
    # MORPH_OPEN:开运算(腐蚀→膨胀),消除小噪点,保留大的运动区域
    fgmask_new = cv2.morphologyEx(fgmask, cv2.MORPH_OPEN, kernel)
    cv2.imshow('Foreground Mask (Processed)', fgmask_new)

    # 7. 轮廓检测:查找前景掩码中的所有轮廓
    # RETR_EXTERNAL:只检索最外层轮廓,减少计算量;CHAIN_APPROX_SIMPLE:压缩轮廓点,节省内存
    contours, hierarchy = cv2.findContours(fgmask_new, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    # 8. 遍历轮廓,筛选并绘制运动目标矩形框
    for c in contours:
        # 计算轮廓周长,用于筛选小的无效区域
        perimeter = cv2.arcLength(c, closed=True)
        # 周长阈值(188):可根据视频分辨率/目标大小调整,过滤小噪点轮廓
        if perimeter > 188:
            # 计算轮廓的外接矩形:x(左)、y(上)、w(宽)、h(高)
            x, y, w, h = cv2.boundingRect(c)
            # 在原始帧上绘制绿色矩形框(BGR格式:(0,255,0))
            cv2.rectangle(frame, pt1=(x, y), pt2=(x + w, y + h), color=(0, 255, 0), thickness=2)

    # 显示绘制了目标框的视频帧
    cv2.imshow('Motion Detection Result', frame)

    # 9. 按键控制:等待60ms,按ESC键(27)退出
    k = cv2.waitKey(60) & 0xFF  # 0xFF解决跨平台按键兼容问题
    if k == 27:
        break

# 10. 释放资源:关闭视频流,销毁所有窗口
cap.release()
cv2.destroyAllWindows()

形态学卷积核创建:

python 复制代码
kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, ksize=(3, 3))
  • cv2.MORPH_CROSS:十字形卷积核,相比矩形核,能更好地保留目标的边缘细节,适合细长型运动目标(如行人、车辆);

  • ksize=(3,3):核的大小为 3×3,是平衡去噪效果和计算效率的常用值;若噪点较多,可改为(5,5),但会增加计算量。

混合高斯模型初始化

python 复制代码
fgbg = cv2.createBackgroundSubtractorMOG2()

该函数默认开启阴影检测(detectShadows=True),阴影区域会显示为灰色(值为 127),若不需要检测阴影,可改为:

python 复制代码
fgbg = cv2.createBackgroundSubtractorMOG2(detectShadows=False)

前景掩码提取与优化

python 复制代码
fgmask = fgbg.apply(frame)
fgmask_new = cv2.morphologyEx(fgmask, cv2.MORPH_OPEN, kernel)
  • fgbg.apply(frame):对当前帧进行背景建模,输出的fgmask是灰度图,白色区域为运动目标;

  • cv2.morphologyEx(..., cv2.MORPH_OPEN, kernel):开运算先腐蚀后膨胀,核心作用是 "去小留大"------ 消除面积小于卷积核的噪点,同时不改变大目标的整体形状。

轮廓检测与筛选

python 复制代码
contours, hierarchy = cv2.findContours(fgmask_new, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for c in contours:
    perimeter = cv2.arcLength(c, closed=True)
    if perimeter > 188:
        x, y, w, h = cv2.boundingRect(c)
        cv2.rectangle(frame, (x,y), (x+w,y+h), (0,255,0), 2)
  • cv2.findContours:返回所有轮廓的列表,每个轮廓是一组点的坐标;

  • cv2.arcLength(c, True):计算轮廓的闭合周长,阈值188是经验值 ------ 需根据视频分辨率调整(如 720P 视频可设为 100,4K 视频可设为 300);

  • cv2.boundingRect(c):为每个符合条件的轮廓生成最小外接矩形,用cv2.rectangle绘制在原始帧上,实现目标可视化。

运行结果

运行代码,会弹出 4 个窗口:

Original Frame:原始视频帧;

Foreground Mask (Raw):MOG2 提取的原始前景掩码(含噪点);

Foreground Mask (Processed):开运算处理后的前景掩码(无噪点);

Motion Detection Result:绘制了绿色矩形框的最终检测结果;

相关推荐
Microvision维视智造1 小时前
小龙虾包装前缺陷智能视觉检测方案:告别人工分选,实现高效标准化品控
人工智能·计算机视觉·视觉检测·检测设备
CoovallyAIHub2 小时前
ICLR 2026 | 慕尼黑工大院士Navab团队联合MVTec提出FoundAD,用基础视觉编码器实现少样本异常检测
人工智能·算法·计算机视觉
我材不敲代码2 小时前
OpenCV的核心图像处理方法——图像边界处理、图像算术运算、阈值分割、噪声与滤波
图像处理·人工智能·opencv
AI人工智能+2 小时前
融合计算机视觉与自然语言处理的特种行业许可证识别技术,解决传统人工录入的效率瓶颈
人工智能·计算机视觉·自然语言处理
輕華2 小时前
OpenCV 图像处理实战(上):阈值、平滑滤波与形态学操作从原理到代码
图像处理·人工智能·opencv
CoovallyAIHub3 小时前
纯合成数据训练,真实图像Pose mAP达0.97:亚琛工大用YOLOv11实现风电关键点检测
深度学习·算法·计算机视觉
子夜江寒3 小时前
YOLO目标检测算法简介
算法·yolo·目标检测
MoRanzhi12033 小时前
Pillow 图像算术运算与通道计算
图像处理·人工智能·python·计算机视觉·pillow·图像差异检测·图像算术运算
WangUnionpub3 小时前
别只盯着MDPI,又贵还卡单位,平替SCI/EI,免收版面费,这本15天录用!
大数据·人工智能·深度学习·物联网·计算机视觉