OpenCV图像处理——基于背景减除实现多目标追踪

1. 基本运动检测

基本运动检测方法的核心在于计算视频帧之间的差异,或者是将某一帧设定为“背景”,然后将其与后续的帧进行比较。这个过程在概念上非常简单:首先保存视频的第一帧作为背景参考,随后将这一帧与新接收到的帧进行逐像素的比较。通过简单的图像相减操作,理论上可以将移动对象从静止背景中分离出来。

然而,这种方法虽然实现起来速度较快,但在实际应用中存在明显的局限性。因为需要将某一帧固定作为背景,而实际情况中背景往往是不断变化的。例如,在汽车检测的场景中,由于汽车和其他物体的移动,以及光照条件的不断变化,这种静态的背景设定很快就会变得不再适用。如果将第一帧设为背景,而其中包含了三辆汽车,那么一秒钟后,这些汽车的位置可能已经发生了变化,原本的背景图像就不再准确。这样一来,算法的准确性就会受到影响,尤其是在那些环境变化迅速的场合。

观察实际的检测图像,可以看到,尽管基本运动检测算法能够捕捉到一些移动对象,但其结果并不精确。在图像的左侧,甚至可以看到一些毫无意义的区域被错误地标记为移动对象。这是因为视频中的背景几乎每秒钟都在变化,而算法中的背景却是固定不变的。
在这里插入图片描述
在这里插入图片描述

2. 背景减除

背景减除的目的是从视频序列中分离出移动对象。这项技术通过对比每一帧与一个背景模型,来识别出那些与背景有显著差异的区域,这些区域通常就是前景对象。这些前景信息随后可以用对象的检测和跟踪。

2.1 解决背景问题

在背景减除的过程中,背景图像并不是静态不变的。由于光照条件的变化、物体的移动以及场景的动态变化等多种因素的影响,背景是随时间不断变化的。因此,背景减除算法需要能够自适应地对背景模型进行建模和更新,以便在环境发生变化时仍能准确地检测到前景对象。通过这种动态更新的方式,背景减除技术能够有效地解决背景问题。

在OpenCV提供了多种背景减除器,可以检测并排除阴影,从而提高对象检测的准确性。这一点非常重要,因为如果阴影没有被正确处理,它们可能会被错误地识别为独立的移动对象。

OpenCV中的背景减除器主要有以下几种:

  1. K-最近邻 (KNN):这是一种基于像素邻域的背景减除方法,它通过计算像素与其K个最近邻像素的差异来进行背景建模和更新。

  2. 高斯混合 (MOG2):这种方法通过将背景建模为多个高斯分布的混合来实现背景的动态更新。每个像素都有一个对应的高斯混合模型,该模型会根据每一帧的新数据进行调整。

2.2 MOG2背景减除器

混合高斯模型(GMM)作为背景建模的经典算法,在目标检测和跟踪等领域有着广泛的应用。自从提出以来,围绕GMM的改进和应用已经产生了大量研究论文。
OpenCV中的BackgroundSubtractorMOG是GMM算法的一个基本实现。这个版本的算法通过创建一个背景模型来实现背景减除,该模型由多个高斯分布组成,每个高斯分布对应图像中的一个像素。这些高斯分布的参数(均值、方差和权重)会根据视频帧中的像素值动态更新,以便更好地适应场景的变化。这种方法能够有效地适应各种背景变化,如光照变化和动态背景。
BackgroundSubtractorMOG2是GMM算法的一个改进版本,它在BackgroundSubtractorMOG的基础上进行了优化和增强。改进的主要点包括:

阴影检测:BackgroundSubtractorMOG2增加了对阴影的检测能力。通过分析像素的HSV值,算法能够区分出阴影和前景物体,从而避免将阴影错误地识别为前景物体。

算法效率提升:BackgroundSubtractorMOG2在运行时间上进行了优化,通过多线程并行执行,提高了算法的处理速度。这使得BackgroundSubtractorMOG2在实时应用中更加高效。

BackgroundSubtractorMOG2的源代码位于OpenCV的源代码目录中,具体位置为opencv\sources\modules\video\src\bgfg_gaussmix2.cpp。源码中详细实现了GMM的参数更新、背景模型的构建、阴影检测等关键功能。

实现步骤:

  • 初始化:在开始处理视频之前,首先初始化K个高斯分布的混合模型,用来模拟场景的背景。每个像素都有一个由高斯分布组成的背景模型,K是预先设定的参数。

  • 适应:随着视频的进行,每个像素的背景模型会根据新接收到的帧数据进行更新,调整高斯分布的参数以适应场景的变化。

  • 前景检测:对于每个像素,根据其高斯混合模型计算它属于背景的概率。那些概率较低的像素会被判定为前景对象。

  • 更新背景:对于那些被判定为背景的像素,更新它们的高斯分布模型,以包含新的观察数据,并继续适应场景的变化。

  • 后处理:在得到初步的前景掩码后,通过应用形态学操作(如腐蚀和膨胀)或其他技术来进一步优化掩码,去除噪声,从而得到更准确的前景对象信息。

在实际的代码实现中,通过复制和运行示例代码,可以观察到每一帧处理后的结果。通过背景减除、阈值处理和形态学膨胀等步骤,可以得到清晰的前景对象检测结果。这些技术在视频监控、自动驾驶车辆、人流统计等领域有着广泛的应用。

代码实现

# 导入库
import cv2
import numpy as np# KNN
KNN_subtractor = cv2.createBackgroundSubtractorKNN(detectShadows = True)# MOG2
MOG2_subtractor = cv2.createBackgroundSubtractorMOG2(detectShadows = True)bg_subtractor=MOG2_subtractorcamera = cv2.VideoCapture("resources/run.mp4")while True:ret, frame = camera.read()# 每一帧既用于计算前景掩码,也用于更新背景。foreground_mask = bg_subtractor.apply(frame)# 如果大于240像素,则阈值设为255,如果小于则设为0    # 创建二值图像,它只包含白色和黑色像素ret , treshold = cv2.threshold(foreground_mask.copy(), 120, 255, cv2.THRESH_BINARY)# 膨胀扩展或加厚图像中的兴趣区域。dilated = cv2.dilate(treshold, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3)), iterations = 2)# 查找轮廓contours, hier = cv2.findContours(dilated, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)# 检查每个轮廓是否超过某个值,如果超过则绘制边界框for contour in contours:if cv2.contourArea(contour) > 50:(x,y,w,h) = cv2.boundingRect(contour)cv2.rectangle(frame, (x,y), (x+w, y+h), (255,255,0), 2)cv2.imshow("Subtractor", foreground_mask)cv2.imshow("threshold", treshold)cv2.imshow("detection", frame)if cv2.waitKey(30) & 0xff == 27:break
camera.release()
cv2.destroyAllWindows()

在这里插入图片描述

在这里插入图片描述

BackgroundSubtractorMOG2作为GMM算法的改进版本,在保持原有优点的基础上,通过增加阴影检测和提高算法效率,使得它在处理复杂场景时更加鲁棒和高效。

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

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

相关文章

肖恩带你学C语言·文件操作(上)

1. 为什么使用文件 如果没有文件,我们写的程序的数据是存储在电脑的内存中,如果程序退出,内存回收,数据就丢失了,等再次运行程序,是看不到上次程序的数据的,如果要将数据进行持久化的保存&…

【攻防世界】FlatScience

dirsearch 扫描发现四个文件 在login.php 中发现 输入 http://61.147.171.105:61912/login.php/?debug 发现源码 <?php if(isset($_POST[usr]) && isset($_POST[pw])){$user $_POST[usr];$pass $_POST[pw];$db new SQLite3(../fancy.db);$res $db->query(…

Android 360度全景图功能

方法一&#xff1a;OpenGL ES 1.在build.gradle文件中添加依赖 allprojects {repositories {maven { url https://jitpack.io }} } 高版本AS中settings.gradle.kts&#xff1a; dependencyResolutionManagement {repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_RE…

蜂窝物联:智慧大田解决方案

蜂窝物联智慧大田解决方案集成了传感器、自动化控制、农情监测、物联网、无线通讯等技术&#xff0c;对与农作物生长及其物候期观测密切相关的土壤、空气、光照、热量等环境因子进行实时监测&#xff0c;智能预警&#xff1b;对田间灌溉电磁阀、水肥一体机进行远程智能自动化控…

9-浏览器必备插件

9-浏览器必备插件 1.Flash Copilot 浏览器超级助手 解决收藏夹 以及使用的办法 2.fehelper 本身还集成插件&#xff0c;满足开发使用 3.SuperCopy 超级复制 SuperCopy 超级复制 一键破解禁止右键、破解禁止选择、破解禁止复制、破解禁止粘贴&#xff0c;启用复制&#xff0c;…

SpringBoot | Spring Boot“整合Redis“

目录: 1. Redis 介绍2. Redis 下载安装3. Redis “服务开启”和“连接配置”4. Spring Boot整合Redis的“前期准备” :① 编写实体类② 编写Repository 接口③ 在“全局配置文件”中添加 “Redis数据库” 的 “相关配置信息” 5. Spring Boot整合“Redis” (案例展示) 作者简介…

Linux网卡与公网IP地址:一个不可随意配置的世界

在Linux系统的网络配置中&#xff0c;IP地址的配置是基础也是关键。许多人可能好奇&#xff1a;为何不能随意为Linux网卡配置公网IP地址&#xff0c;而私网IP地址似乎就可以随心所欲呢&#xff1f;本文将解开这些问题的答案&#xff0c;探索公网IP地址被严格管控的原因&#xf…

【UnityRPG游戏制作】Unity_RPG项目之界面面板分离和搭建

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;Uni…

深度学习500问——Chapter05: 卷积神经网络(CNN)(4)

文章目录 5.18 卷积神经网络凸显共性的方法 5.18.1 局部连接 5.18.2 权值共享 5.18.3 池化操作 5.19 全连接、局部连接、全卷积与局部卷积 5.20 局部卷积的应用 5.21 NetVLAD池化 参考文献 5.18 卷积神经网络凸显共性的方法 5.18.1 局部连接 我们首先了解一个概念&#xff0c…

vue 打包 插槽 inject reactive draggable 动画 foreach pinia状态管理

在Vue项目中&#xff0c;当涉及到打包、插槽&#xff08;Slots&#xff09;、inject/reactive、draggable、transition、foreach以及pinia时&#xff0c;这些都是Vue框架的不同特性和库&#xff0c;它们各自在Vue应用中有不同的用途。下面我将逐一解释这些概念&#xff0c;并说…

8、滑动窗口-无重复字符的最长子串

解析&#xff1a; 遍历 判断map是否包含当前字符&#xff0c;如果包含&#xff1a; 获取重复的index下标在哪里获取len长度重新设置L指针,其中L指针不回退&#xff0c;也就是如果这个重复值在L前面那就忽略&#xff0c;如果是在后面那就设置为index1。 代码如下&#xff1a; …

二叉树算法练习day.2

102.二叉树的层序遍历 链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 题目描述&#xff1a; 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。 示例 1&#xff1a; 输入&a…

小米手机澎湃OS,不Root查看电池健康

首先&#xff0c;在键盘拨号界面&#xff0c;输入*#*#284#*#*&#xff0c;会调用问题反馈APP来生成当前系统的故障日志&#xff0c;如果提示你需要授权什么就点确认 稍等几分钟&#xff0c;会得到一个压缩包&#xff0c;保存在目录MIUI/debug_log下 这里为了方便&#xff0c;我…

Shell编程初识

Shell初识 ShellShell 脚本Shell 环境第一个shell脚本实例 运行 Shell 脚本方法&#xff1a;1、作为可执行程序2、作为解释器参数3.使用 . (空格)脚本名称来执行4.使用 source 来执行(主要用于生效配置文件)区别1.关于执行权限2.关于是否开启子shell线程 脚本排错及问题判断she…

LLM推理参数(top_k,top_p, temperature, num_beams)

正常LLM做 next token predicate 时&#xff0c;对输出的 logits 做 softmax&#xff0c;选择概率最大的token。 num_beams &#xff1a;当我们设置 num_beams2 后&#xff0c;就使用了 beam search 的方法&#xff0c;每次不是只直接选择概率最大的 token&#xff0c;而是保留…

三子棋游戏----C语言版【超级详细 + 视频演示 + 完整源码】

㊙️小明博客主页&#xff1a;➡️ 敲键盘的小明 ㊙️ ✅关注小明了解更多知识☝️ 文章目录 前言一、三子棋的实现思路二、三子棋的实现步骤2.1 先显示游戏的菜单2.2 游戏的具体实现2.2.1 棋盘的初始化2.2.2 展示棋盘2.2.3 下棋&#x1f534;玩家下棋&#x1f534;电脑下棋2.2…

申请SSL证书

有很多方法可以确保您的网站安全。添加SSL证书可针对恶意攻击提供额外且关键的保护层。 即使网站不接受交易&#xff0c;您仍然需要保护用户的登录详细信息、地址和其他个人信息。 没有SSL证书的网站使用HTTP&#xff08;一种基于文本的协议&#xff09;&#xff0c;这意味着…

网络编程套接字应用分享【Linux C/C++ 】【UDP应用 | TCP应用 | TCP线程池小项目】

目录 前提知识 1. 理解源ip&#xff0c;目的ip和Macip 2. 端口号 3. 初识TCP&#xff0c;UDP协议 4. 网络字节序 5. socket 编程 sockaddr类型 一&#xff0c;基于udp协议编程 1. socket——创建套接字 2. bind——将套接字强绑定 3. recvfrom——接受数据 4. s…

AI跟踪报道第36期-新加坡内哥谈技术-这周的AI新闻铺天盖地

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

从多模态生物图数据中学习Gene的编码-MuSeGNN

由于数据的异质性&#xff0c;在不同的生物医学背景下发现具有相似功能的基因对基因表示学习提出了重大挑战。在本研究中&#xff0c;作者通过引入一种称为多模态相似性学习图神经网络的新模型来解决这个问题&#xff0c;该模型结合了多模态机器学习和深度图神经网络&#xff0…