opencv学习:利用帧差法实现对视频移动物体的识别、帧差法的优缺点及完整代码实现

基本概念

帧差法是视频处理和计算机视觉领域中用于移动检测的一种简单而有效的方法。它主要依赖于连续视频帧之间的像素差异来识别场景中的移动对象。

帧差法

  • 定义:帧差法通过比较连续的视频帧之间的差异来检测移动对象。基本思想是移动对象会在连续的帧之间产生显著的位置变化,而静止背景则变化不大。

代码步骤

  1. 读取视频 :使用cv2.VideoCapture函数读取视频文件test.avi

    python 复制代码
    cap=cv2.VideoCapture('test.avi')
    kernel=cv2.getStructuringElement(cv2.MORPH_CROSS,(3,3))
  2. 创建背景减除器 :使用cv2.createBackgroundSubtractorMOG2创建一个MOG2背景减除器对象。

    python 复制代码
    # 创建一个背景减除器对象
    fgbg=cv2.createBackgroundSubtractorMOG2()
  3. 逐帧处理视频 :通过无限循环读取视频的每一帧,并使用背景减除器处理当前帧,得到前景掩码。

    python 复制代码
    # 开始一个无限循环,用于逐帧处理视频。
    while (True):
        # ret是一个布尔值,表示是否成功读取帧,frame是读取的帧图像。
        ret,frame=cap.read()
        cv2.imshow('1',frame)
        # 使用背景减除器处理当前帧,得到前景掩码。
        fgmask=fgbg.apply(frame)
  4. 形态学开运算 :对前景掩码应用形态学开运算,以去除小的噪点和分离粘连的物体。

    python 复制代码
    # 对前景掩码应用形态学开运算,以去除小的噪点和分离粘连的物体。
        fgmask_new=cv2.morphologyEx(fgmask,cv2.MORPH_OPEN,kernel)
        cv2.imshow('3',fgmask_new)
  5. 查找轮廓 :在处理后的前景掩码中查找轮廓。

    python 复制代码
    # 在处理后的前景掩码中查找轮廓。_是用于忽略返回值的占位符,contours是找到的轮廓列表,h是轮廓的层次结构。
        _,contours,h=cv2.findContours(fgmask_new,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
  6. 轮廓筛选 :遍历所有找到的轮廓,计算轮廓的周长,如果周长大于188,则认为是一个移动对象,并计算其边界矩形,在原始帧上绘制一个绿色矩形框以标识移动对象。

    python 复制代码
        for c in contours:#遍历所有找到的轮廓。
            perimeter=cv2.arcLength(c,True)#计算当前轮廓的周长
            if perimeter>188:
                x,y,w,h=cv2.boundingRect(c)
                #在原始帧上绘制一个绿色矩形框
                fgmask_new_rect=cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,0),2)
        cv2.imshow('4',fgmask_new_rect)
        k=cv2.waitKey(60)
  7. 退出条件 :按下ESC键(ASCII码为27)跳出循环。

    python 复制代码
    # 按下ESC键(ASCII码为27),则跳出循环
        if k==27:
            break

运行结果

帧差法优缺点

优点

  1. 简单高效:算法简单,易于实现,计算量小,适合实时处理。
  2. 实时性能:由于计算量小,帧差法可以快速处理视频帧,适用于实时视频监控系统。
  3. 无需背景模型:不需要预先学习或建模背景,直接比较连续帧的差异。
  4. 适应性:对于视频中的动态变化,如移动对象的出现和消失,帧差法能够快速响应。
  5. 易于调整:通过调整阈值,可以控制检测的灵敏度,以适应不同的监控环境和需求。

缺点

  1. 光照敏感:光照变化(如由于天气或时间变化导致的光照变化)可能会影响帧差法的性能,导致错误的移动检测。
  2. 阴影问题:移动对象的阴影可能被错误地检测为移动物体,引起误报。
  3. 背景变化:如果背景发生变化(如植物的生长、人流的变化),帧差法可能无法正确区分背景和移动对象。
  4. 摄像头抖动:摄像头的微小移动可能导致帧差法检测到错误的移动。
  5. 动态背景:在有动态背景(如水面、旗帜)的场景中,帧差法可能难以区分背景的自然运动和真正的移动对象。
  6. 相似颜色:如果移动对象的颜色与背景颜色相似,帧差法可能无法检测到。
  7. 快速移动对象:对于快速移动的对象,由于帧率的限制,可能会发生漏检。
  8. 遮挡问题:当一个移动对象被另一个对象遮挡时,帧差法可能无法检测到被遮挡的部分。
  9. 分辨率限制:在分辨率较低的视频中,重要的细节可能会丢失,导致帧差法的性能下降。
  10. 噪声敏感:图像噪声可能会增加帧差图像中的假阳性,尤其是在低对比度区域。

完整代码

python 复制代码
cap=cv2.VideoCapture('test.avi')
kernel=cv2.getStructuringElement(cv2.MORPH_CROSS,(3,3))

# 创建一个背景减除器对象
fgbg=cv2.createBackgroundSubtractorMOG2()
# 开始一个无限循环,用于逐帧处理视频。
while (True):
    # ret是一个布尔值,表示是否成功读取帧,frame是读取的帧图像。
    ret,frame=cap.read()
    cv2.imshow('1',frame)
    # 使用背景减除器处理当前帧,得到前景掩码。
    fgmask=fgbg.apply(frame)
    # 对前景掩码应用形态学开运算,以去除小的噪点和分离粘连的物体。
    fgmask_new=cv2.morphologyEx(fgmask,cv2.MORPH_OPEN,kernel)
    cv2.imshow('3',fgmask_new)

    # 在处理后的前景掩码中查找轮廓。_是用于忽略返回值的占位符,contours是找到的轮廓列表,h是轮廓的层次结构。
    _,contours,h=cv2.findContours(fgmask_new,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
    for c in contours:#遍历所有找到的轮廓。
        perimeter=cv2.arcLength(c,True)#计算当前轮廓的周长
        if perimeter>188:
            x,y,w,h=cv2.boundingRect(c)
            #在原始帧上绘制一个绿色矩形框
            fgmask_new_rect=cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,0),2)
    cv2.imshow('4',fgmask_new_rect)
    k=cv2.waitKey(60)
    # 按下ESC键(ASCII码为27),则跳出循环
    if k==27:
        break
相关推荐
thesky12345610 小时前
27届大模型岗面试准备(十四):多模态大模型 VLM——从视觉编码器到多模态推理的完整链路
人工智能·ai·大模型
一根数据线10 小时前
BIM建模效率低?试试和AI工具配合使用
人工智能·ai·3d建模·3d模型·bim·ai建模·造形家
怕浪猫10 小时前
2840亿参数只卖白菜价:DeepSeek V4 Flash 正式版上线,Agent 能力暴涨6倍
人工智能·算法
不爱记笔记10 小时前
多模态AI如何理解视频内容?从视觉、语音到语义的三层技术拆解
人工智能·自然语言处理·nlp·音视频·多模态
让学习成为一种生活方式10 小时前
苄基异喹啉生物碱糖基转移酶UGT74AN1晶体--Journal of Agricultural and Food Chemistry
人工智能·算法
早睡早起身体好12310 小时前
为什么 Network 中会出现两个同名请求?——CORS 预检请求学习笔记
网络·笔记·学习·网络安全
菩提树下的打坐10 小时前
测试左移的更深一层:用 DDD 战术设计反推测试边界
学习
犀利豆10 小时前
Claude code tools 研究系列(二)EnterPlanMode
人工智能·后端
sponge'10 小时前
《以场景为中心的无监督视频全景分割》论文框架讲解
人工智能·深度学习
陕西企来客10 小时前
2026年7月西安GEO优化哪家好?实战对比评估
人工智能·西安geo优化哪家好