OpenCV计算机视觉实战 - Task7 - 背景建模 光流估计

2023-12-22 15:38

本文主要是介绍OpenCV计算机视觉实战 - Task7 - 背景建模 光流估计,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

###############################################################
纸上得来终觉浅,绝知此事要躬行
B站视频
新课件:https://pan.baidu.com/s/1frWHqCVGR2VTn5QBtW4lPA 提取码:xh02
老课件:https://pan.baidu.com/s/1Wi31FxSPBqWiuJX9quX-jA 提取码:bbfg
##############################################################

一、背景建模

法1:帧差法

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

帧差法非常简单,但是会引入噪音 和 空洞问题

法2:混合高斯模型

在进行前景检测前,先对背景进行训练,对图像中每个背景采用一个混合高斯模型进行模拟,每个背景的混合高斯的个数可以自适应。
然后在测试阶段,对新来的像素进行GMM(高斯混合模型)匹配,如果该像素值能够匹配其中一个高斯,则认为是背景,否则认为是前景
由于整个过程GMM模型在不断更新学习中,所以对动态背景有一定的鲁棒性。最后通过对一个有树枝摇摆的动态背景进行前景检测,取得了较好的效果。

在视频中对于像素点的变化情况应当是符合高斯分布
在这里插入图片描述
背景的实际分布应当是多个高斯分布混合在一起每个高斯模型也可以带有权重
在这里插入图片描述

混合高斯模型学习方法1.首先初始化每个高斯模型矩阵参数。	
2.取视频中T帧数据图像用来训练高斯混合模型。来了第一个像素之后用它来当做第一个高斯分布。	
3.当后面来的像素值时,与前面已有的高斯的均值比较,如果该像素点的值与其模型均值差在3倍的方差内,则属于该分布,并对其进行参数更新。
4.如果下一次来的像素不满足当前高斯分布,用它来创建一个新的高斯分布。

混合高斯模型测试方法

在测试阶段,对新来像素点的值与混合高斯模型中的每一个均值进行比较,如果其差值在2倍的方差之间的话,则认为是背景,否则认为是前景。将前景赋值为255,背景赋值为0。这样就形成了一副前景二值图。

在这里插入图片描述

import numpy as np
import cv2# 经典的测试视频
cap = cv2.VideoCapture('test.avi')
# 形态学操作需要使用
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3))
# 创建混合高斯模型用于背景建模
fgbg = cv2.createBackgroundSubtractorMOG2()while(True):ret, frame = cap.read()fgmask = fgbg.apply(frame)  # 应用到每一帧中提取背景# 形态学开运算去噪点fgmask = cv2.morphologyEx(fgmask, cv2.MORPH_OPEN, kernel)# 寻找视频中的轮廓contours, hierarchy = cv2.findContours(fgmask, 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)# 画出这个矩形cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,0),2)    cv2.imshow('frame',frame)cv2.imshow('fgmask', fgmask)k = cv2.waitKey(150) & 0xffif k == 27:breakcap.release()
cv2.destroyAllWindows()

缺点:不适用于复杂背景

二、光流估计

光流是空间运动物体在观测成像平面上的像素运动的 “瞬时速度”,根据各个像素点的速度矢量特征,可以对图像进行动态分析,例如目标跟踪。

  1. 亮度恒定:同一点随着时间的变化,其亮度不会发生改变。

  2. 小运动:随着时间的变化不会引起位置的剧烈变化,只有小运动情况下才能用前后帧之间单位位置变化引起的灰度变化去近似灰度对位置的偏导数。

  3. 空间一致:一个场景上邻近的点投影到图像上也是邻近点,且邻近点速度一致。因为光流法基本方程约束只有一个,而要求x,y方向的速度,有两个未知变量。所以需要连立n多个方程求解。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    如何求解方程组呢?看起来一个像素点根本不够,在物体移动过程中还有哪些特性呢?
    在这里插入图片描述

  • cv2.calcOpticalFlowPyrLK():
    参数:
    prevImage 前一帧图像
    nextImage 当前帧图像
    prevPts 待跟踪的特征点向量
    winSize 搜索窗口的大小
    maxLevel 最大的金字塔层数

    返回:
    nextPts 输出跟踪特征点向量
    status 特征点是否找到,找到的状态为1,未找到的状态为0

  • cv2.goodFeaturesToTrack:去跟踪好的特征
    feature_params
    qualityLevel 品质因子越大,得到的角点越少
    maxLevel 在这个距离范围内,哪个品质因子最强

import numpy as np
import cv2cap = cv2.VideoCapture('test.avi')# 角点检测所需参数
feature_params = dict( maxCorners = 100,qualityLevel = 0.3,minDistance = 7)# lucas kanade参数
lk_params = dict( winSize  = (15,15),maxLevel = 2)# 随机颜色条
color = np.random.randint(0,255,(100,3))# 拿到第一帧图像
ret, old_frame = cap.read()
old_gray = cv2.cvtColor(old_frame, cv2.COLOR_BGR2GRAY)
# 返回所有检测特征点,需要输入图像,角点最大数量(效率),品质因子(特征值越大的越好,来筛选)
# 距离相当于这区间有比这个角点强的,就不要这个弱的了
p0 = cv2.goodFeaturesToTrack(old_gray, mask = None, **feature_params) # 第一帧的角点# 创建一个mask
mask = np.zeros_like(old_frame)while(True):ret,frame = cap.read()frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)# 需要传入前一帧和当前图像以及前一帧检测到的角点p1, st, err = cv2.calcOpticalFlowPyrLK(old_gray, frame_gray, p0, None, **lk_params)# st=1表示good_new = p1[st==1]good_old = p0[st==1]# 绘制轨迹for i,(new,old) in enumerate(zip(good_new,good_old)):a,b = new.ravel()c,d = old.ravel()mask = cv2.line(mask, (a,b),(c,d), color[i].tolist(), 2)frame = cv2.circle(frame,(a,b),5,color[i].tolist(),-1)img = cv2.add(frame,mask)cv2.imshow('frame',img)k = cv2.waitKey(150) & 0xffif k == 27:break# 更新old_gray = frame_gray.copy() # 当前帧作为old帧p0 = good_new.reshape(-1,1,2)cv2.destroyAllWindows()
cap.release()

缺点:

  1. 前一帧检测不到的角点(st=0),下一帧(及后续帧)也都检测不到。
  2. 以视频的第一帧为背景,后面出现的新目标也检测不到

这篇关于OpenCV计算机视觉实战 - Task7 - 背景建模 光流估计的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/524509

相关文章

Python版本信息获取方法详解与实战

《Python版本信息获取方法详解与实战》在Python开发中,获取Python版本号是调试、兼容性检查和版本控制的重要基础操作,本文详细介绍了如何使用sys和platform模块获取Python的主... 目录1. python版本号获取基础2. 使用sys模块获取版本信息2.1 sys模块概述2.1.1

Python爬虫HTTPS使用requests,httpx,aiohttp实战中的证书异步等问题

《Python爬虫HTTPS使用requests,httpx,aiohttp实战中的证书异步等问题》在爬虫工程里,“HTTPS”是绕不开的话题,HTTPS为传输加密提供保护,同时也给爬虫带来证书校验、... 目录一、核心问题与优先级检查(先问三件事)二、基础示例:requests 与证书处理三、高并发选型:

Oracle Scheduler任务故障诊断方法实战指南

《OracleScheduler任务故障诊断方法实战指南》Oracle数据库作为企业级应用中最常用的关系型数据库管理系统之一,偶尔会遇到各种故障和问题,:本文主要介绍OracleSchedul... 目录前言一、故障场景:当定时任务突然“消失”二、基础环境诊断:搭建“全局视角”1. 数据库实例与PDB状态2

Git进行版本控制的实战指南

《Git进行版本控制的实战指南》Git是一种分布式版本控制系统,广泛应用于软件开发中,它可以记录和管理项目的历史修改,并支持多人协作开发,通过Git,开发者可以轻松地跟踪代码变更、合并分支、回退版本等... 目录一、Git核心概念解析二、环境搭建与配置1. 安装Git(Windows示例)2. 基础配置(必

MyBatis分页查询实战案例完整流程

《MyBatis分页查询实战案例完整流程》MyBatis是一个强大的Java持久层框架,支持自定义SQL和高级映射,本案例以员工工资信息管理为例,详细讲解如何在IDEA中使用MyBatis结合Page... 目录1. MyBATis框架简介2. 分页查询原理与应用场景2.1 分页查询的基本原理2.1.1 分

使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解

《使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解》本文详细介绍了如何使用Python通过ncmdump工具批量将.ncm音频转换为.mp3的步骤,包括安装、配置ffmpeg环... 目录1. 前言2. 安装 ncmdump3. 实现 .ncm 转 .mp34. 执行过程5. 执行结

SpringBoot 多环境开发实战(从配置、管理与控制)

《SpringBoot多环境开发实战(从配置、管理与控制)》本文详解SpringBoot多环境配置,涵盖单文件YAML、多文件模式、MavenProfile分组及激活策略,通过优先级控制灵活切换环境... 目录一、多环境开发基础(单文件 YAML 版)(一)配置原理与优势(二)实操示例二、多环境开发多文件版

Three.js构建一个 3D 商品展示空间完整实战项目

《Three.js构建一个3D商品展示空间完整实战项目》Three.js是一个强大的JavaScript库,专用于在Web浏览器中创建3D图形,:本文主要介绍Three.js构建一个3D商品展... 目录引言项目核心技术1. 项目架构与资源组织2. 多模型切换、交互热点绑定3. 移动端适配与帧率优化4. 可

从原理到实战解析Java Stream 的并行流性能优化

《从原理到实战解析JavaStream的并行流性能优化》本文给大家介绍JavaStream的并行流性能优化:从原理到实战的全攻略,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的... 目录一、并行流的核心原理与适用场景二、性能优化的核心策略1. 合理设置并行度:打破默认阈值2. 避免装箱

Maven中生命周期深度解析与实战指南

《Maven中生命周期深度解析与实战指南》这篇文章主要为大家详细介绍了Maven生命周期实战指南,包含核心概念、阶段详解、SpringBoot特化场景及企业级实践建议,希望对大家有一定的帮助... 目录一、Maven 生命周期哲学二、default生命周期核心阶段详解(高频使用)三、clean生命周期核心阶