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

基本概念

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

帧差法

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

代码步骤

  1. 读取视频:使用cv2.VideoCapture函数读取视频文件test.avi
    cap=cv2.VideoCapture('test.avi')
    kernel=cv2.getStructuringElement(cv2.MORPH_CROSS,(3,3))
  2. 创建背景减除器:使用cv2.createBackgroundSubtractorMOG2创建一个MOG2背景减除器对象。
    # 创建一个背景减除器对象
    fgbg=cv2.createBackgroundSubtractorMOG2()
  3. 逐帧处理视频:通过无限循环读取视频的每一帧,并使用背景减除器处理当前帧,得到前景掩码。
    # 开始一个无限循环,用于逐帧处理视频。
    while (True):# ret是一个布尔值,表示是否成功读取帧,frame是读取的帧图像。ret,frame=cap.read()cv2.imshow('1',frame)# 使用背景减除器处理当前帧,得到前景掩码。fgmask=fgbg.apply(frame)
  4. 形态学开运算:对前景掩码应用形态学开运算,以去除小的噪点和分离粘连的物体。
    # 对前景掩码应用形态学开运算,以去除小的噪点和分离粘连的物体。fgmask_new=cv2.morphologyEx(fgmask,cv2.MORPH_OPEN,kernel)cv2.imshow('3',fgmask_new)
  5. 查找轮廓:在处理后的前景掩码中查找轮廓。
    # 在处理后的前景掩码中查找轮廓。_是用于忽略返回值的占位符,contours是找到的轮廓列表,h是轮廓的层次结构。_,contours,h=cv2.findContours(fgmask_new,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
  6. 轮廓筛选:遍历所有找到的轮廓,计算轮廓的周长,如果周长大于188,则认为是一个移动对象,并计算其边界矩形,在原始帧上绘制一个绿色矩形框以标识移动对象。
        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)跳出循环。
    # 按下ESC键(ASCII码为27),则跳出循环if k==27:break

运行结果

帧差法优缺点

优点

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

缺点

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

完整代码

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/55672.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Android 源码分析】Activity生命周期之onDestroy

忽然有一天,我想要做一件事:去代码中去验证那些曾经被“灌输”的理论。                                                                                  – 服装…

五十、架构设计经验与技巧(架构设计基本原则)

架构设计的基本原则是指导架构师在设计和实施系统时的重要参考。这些原则不仅影响系统的质量、可维护性和可扩展性,也直接影响到项目的成功与否。以下是几大基本原则及其在实践中的应用: 1. 可扩展性(Scalability) 定义:系统在负载增加时,能够通过增加资源(如服务器、…

信息学奥赛使用的编程IDE:Dev-C++ 安装指南

信息学奥赛(NOI)作为全国性的编程竞赛,要求参赛学生具备扎实的编程能力,而熟练使用适合的编程工具则是学习与竞赛的基础。在众多编程环境中,Dev-C IDE 因其简洁、轻量、支持C编程等特点,成为许多参赛者的常…

Android阶段学习思维导图

前言 记录下自己做的一个对Android原生应用层的思维导图,方便个人记忆扩展;这里只露出二级标题。 后语 虽然有些内容只是初步了解,但还是记录了下来;算是对过去一段学习的告别。

Linux Cent7 已安装MySQL5.7.X,再安装MYSQL8.4.2

一、 下载安装 检查Linux系统的glibc版本rpm -qa | grep glibc结果:glibc-common-2.17-260.el7_6.6.x86_64 glibc-2.17-260.el7_6.6.x86_64 glibc-headers-2.17-260.el7_6.6.x86_64 glibc-devel-2.17-260.el7_6.6.x86_64访问MySQL官网,下载对应版本数据…

JavaSE——面向对象6.1:继承知识点补充(虚方法表等)

目录 一、子类到底能继承父类中的哪些内容? 二、继承内存图 三、继承中:成员变量和成员方法的访问特点 (一)成员变量的访问特点 (二)成员方法的访问特点 1.this与super访问成员方法的特点 2.方法重写 2.1方法重写的本质:子类覆盖了从…

shell脚本写代码

用简单的test语句来判断是否闰年 #! /bin/bash read -p "sd " yearif [ $((year%4)) -eq 0 -a $((year%100)) -ne 0 -o $((year%400)) -eq 0 ]thenecho "是润年"elseecho "不是闰年" fi判断一个数是否为偶数 #! /bin/bash read -p "…

vue源码解析(源码解析学习大纲)

文章目录 Vue源码解析入手方向大纲1.核心概念1-1.响应式系统1-2. 组件1-3. 虚拟DOM1-4. 指令1-5. 生命周期钩子 2.虚拟DOM2-1. 概念2-2. 工作流程2-3. 示例2-4.总结 3.组件系统3-1. 组件的定义3-2. 组件的创建3-3. 组件的模板3-4. 生命周期3-5. 事件处理3-6. 插槽(S…

服务器虚拟化的详细学习顺序

服务器虚拟化的详细学习顺序可以遵循以下步骤,这些步骤旨在帮助学习者系统地掌握虚拟化技术: 1. 理解基本概念与原理 定义与原理:首先,需要明确服务器虚拟化的定义和基本原理,即如何将物理服务器资源转化为虚拟服务器…

【C语言】猜数字小游戏

😂个人主页: 起名字真南 🤣个人专栏:【数据结构初阶】 【C语言】 【C】 目录 1 随机数的生成1.1 rand1.2 srand1.3 time1.4 设置随机数范围 2 猜数字游戏实现 前言:我们学习完前面的循环以后可以写一个猜数字小游戏 1 随机数的生成 想要完成…

Java 中的 LinkedHashMap

让我们从一个简单的 Java 代码片段开始,演示如何在 Java 中创建和使用 LinkedHashMap。 import java.util.LinkedHashMap; public class LinkedHashMapCreation { public static void main(String[] args) { // Create a LinkedHashMap of S…

django的路由分发

前言: 在前面我们已经学习了基础的Django了,今天我们将继续学习,我们今天学习的是路由分发: 路由分发是Web框架中的一个核心概念,它指的是将不同的URL请求映射到对应的处理函数(视图)的过程。…

Ambari搭建Hadoop集群 — — 问题总结

Ambari搭建Hadoop集群 — — 问题总结 一、部署教程: 参考链接:基于Ambari搭建大数据分析平台-CSDN博客 二、问题总结: 1. VMwear Workstation 查看网关 2. 资源分配 参考: 硬盘:master(29 GB&#xff…

手机使用技巧:8 个 Android 锁屏移除工具 [解锁 Android]

有时候,您会被锁定在自己的 Android 设备之外,而且似乎不可能重新进入。 一个例子就是你买了一部二手手机,后来发现无法使用。另一种情况是你忘记了屏幕锁定密码和用于验证密码的 Google 帐户凭据。这种情况很少见,但确实会发生&…

15分钟学 Python 第35天 :Python 爬虫入门(一)

Day 35 : Python 爬虫简介 1.1 什么是爬虫? 网页爬虫(Web Crawler)是自动访问互联网并提取所需信息的程序。爬虫的主要功能是模拟用户通过浏览器访问网页的操作,从而实现对网页内容的批量访问与信息提取。它们广泛应用于数据收集…

RTEMS面试题汇总及参考答案

目录 RTEMS是什么?它在嵌入式系统中扮演什么角色? RTEMS的全称是什么? RTEMS的主要特点有哪些? RTEMS支持哪些处理器架构? RTEMS的可剥夺型内核和不可剥夺型内核有何不同? RTEMS 的微内核设计及其优势 RTEMS 如何实现多任务处理和调度 RTEMS 的任务调度策略有哪…

Unity各个操作功能+基本游戏物体创建与编辑+Unity场景概念及文件导入导出

各个操作功能 部分功能 几种操作游戏物体的方式: Center:有游戏物体父子关系的时候,中心点位置 Global/Local:世界坐标系方向/自身坐标系方向 :调试/暂停/下一帧 快捷键 1.Alt鼠标左键:可以实现巡游角度查看场景 2.鼠标滚轮…

MySQL从0到1基础语法笔记(上)

博客主页:誓则盟约系列专栏:Java Web关注博主,后期持续更新系列文章如果有错误感谢请大家批评指出,及时修改感谢大家点赞👍收藏⭐评论✍ 目录 MySQL笔记: 一、注释: 二、SQL四大类&#xff…

leetcode 刷题day36动态规划Part05 背包问题(完全背包、518. 零钱兑换 II、377. 组合总和 Ⅳ、70. 爬楼梯 (进阶))

完全背包 完全背包的每件商品都有无限个,和01背包的一不同主要体现在遍历顺序上。为了保证每个物品仅被添加一次,01背包内嵌的循环是从大到小遍历。而完全背包的物品是可以添加多次的,所以要从小到大去遍历。 518. 零钱兑换 II 思路&#…

、并发请求

初始化 const axios require(axios) const apis [url1, url2, url3] // 模拟 http apis并发函数 /*** param {Array<string>} apis* param {number} maxNum 最大并发量* returns {Promise}*//*** param {Array<string>} apis 请求的API集* param {number} maxN…