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

相关文章

使用 sql-research-assistant进行 SQL 数据库研究的实战指南(代码实现演示)

《使用sql-research-assistant进行SQL数据库研究的实战指南(代码实现演示)》本文介绍了sql-research-assistant工具,该工具基于LangChain框架,集... 目录技术背景介绍核心原理解析代码实现演示安装和配置项目集成LangSmith 配置(可选)启动服务应用场景

css渐变色背景|<gradient示例详解

《css渐变色背景|<gradient示例详解》CSS渐变是一种从一种颜色平滑过渡到另一种颜色的效果,可以作为元素的背景,它包括线性渐变、径向渐变和锥形渐变,本文介绍css渐变色背景|<gradien... 使用渐变色作为背景可以直接将渐China编程变色用作元素的背景,可以看做是一种特殊的背景图片。(是作为背

在Java中使用ModelMapper简化Shapefile属性转JavaBean实战过程

《在Java中使用ModelMapper简化Shapefile属性转JavaBean实战过程》本文介绍了在Java中使用ModelMapper库简化Shapefile属性转JavaBean的过程,对比... 目录前言一、原始的处理办法1、使用Set方法来转换2、使用构造方法转换二、基于ModelMapper

Java实战之自助进行多张图片合成拼接

《Java实战之自助进行多张图片合成拼接》在当今数字化时代,图像处理技术在各个领域都发挥着至关重要的作用,本文为大家详细介绍了如何使用Java实现多张图片合成拼接,需要的可以了解下... 目录前言一、图片合成需求描述二、图片合成设计与实现1、编程语言2、基础数据准备3、图片合成流程4、图片合成实现三、总结前

nginx-rtmp-module构建流媒体直播服务器实战指南

《nginx-rtmp-module构建流媒体直播服务器实战指南》本文主要介绍了nginx-rtmp-module构建流媒体直播服务器实战指南,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有... 目录1. RTMP协议介绍与应用RTMP协议的原理RTMP协议的应用RTMP与现代流媒体技术的关系2

C语言小项目实战之通讯录功能

《C语言小项目实战之通讯录功能》:本文主要介绍如何设计和实现一个简单的通讯录管理系统,包括联系人信息的存储、增加、删除、查找、修改和排序等功能,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录功能介绍:添加联系人模块显示联系人模块删除联系人模块查找联系人模块修改联系人模块排序联系人模块源代码如下

Golang操作DuckDB实战案例分享

《Golang操作DuckDB实战案例分享》DuckDB是一个嵌入式SQL数据库引擎,它与众所周知的SQLite非常相似,但它是为olap风格的工作负载设计的,DuckDB支持各种数据类型和SQL特性... 目录DuckDB的主要优点环境准备初始化表和数据查询单行或多行错误处理和事务完整代码最后总结Duck

Java中的Opencv简介与开发环境部署方法

《Java中的Opencv简介与开发环境部署方法》OpenCV是一个开源的计算机视觉和图像处理库,提供了丰富的图像处理算法和工具,它支持多种图像处理和计算机视觉算法,可以用于物体识别与跟踪、图像分割与... 目录1.Opencv简介Opencv的应用2.Java使用OpenCV进行图像操作opencv安装j

Python中的随机森林算法与实战

《Python中的随机森林算法与实战》本文详细介绍了随机森林算法,包括其原理、实现步骤、分类和回归案例,并讨论了其优点和缺点,通过面向对象编程实现了一个简单的随机森林模型,并应用于鸢尾花分类和波士顿房... 目录1、随机森林算法概述2、随机森林的原理3、实现步骤4、分类案例:使用随机森林预测鸢尾花品种4.1

Golang使用minio替代文件系统的实战教程

《Golang使用minio替代文件系统的实战教程》本文讨论项目开发中直接文件系统的限制或不足,接着介绍Minio对象存储的优势,同时给出Golang的实际示例代码,包括初始化客户端、读取minio对... 目录文件系统 vs Minio文件系统不足:对象存储:miniogolang连接Minio配置Min