12月21日 OpenCV 实战基础学习笔记——背景建模、光流估计

news2024/11/20 6:14:21

文章目录

  • 前言
  • 一、背景建模
    • 1、帧差法
    • 2、混合高斯模型
  • 二、光流估计


前言

本文为12月21日 OpenCV 实战基础学习笔记,分为两个章节:

  • 背景建模;
  • 光流估计。

一、背景建模

1、帧差法

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

1

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

2、混合高斯模型

先对背景进行训练,对图像中每个背景用一个混合高斯模型进行模拟,每个背景的混合高斯的个数可以自适应。

在测试阶段,对新来的像素进行 GMM 匹配,如果该像素值能够匹配其中一个高斯,则认为是背景,否则认为是前景。由于整个过程 GMM 模型在不断更新学习中,所以对动态背景有一定的鲁棒性。

最后通过对一个有树枝摇摆的动态背景进行前景检测,取得较好效果。

2
背景的实际分布应当是多个高斯分布混合在一起,每个高斯模型也可以带有权重。

3

  • 混合高斯模型学习方法:

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

import numpy as np
import cv2 as cv

# 测试视频
cap = cv.VideoCapture('./背景建模与光流估计/test.avi')

# 形态学操作: 去除噪音
kernel = cv.getStructuringElement(cv.MORPH_ELLIPSE, (3, 3))

# 创建混合高斯模型用于背景建模
fgbg = cv.createBackgroundSubtractorMOG2()

while(True):
    ret, frame = cap.read()
    fgmask = fgbg.apply(frame)
    
    # 形态学开运算去噪点
    fgmask = cv.morphologyEx(fgmask, cv.MORPH_OPEN, kernel)
    
    # 寻找视频中的轮廓
    contours, hierachy = cv.findContours(fgmask, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
    
    #计算各轮廓的周长
    for c in contours:
        perimetre = cv.arcLength(c, True)
        if perimetre > 188:
            # 找到一个直矩形(不会旋转)
            x, y, w, h = cv.boundingRect(c)
            # 画出这个矩形
            cv.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)
            
    cv.imshow('Frame', frame)
    cv.imshow('fgmask', fgmask)
    k = cv.waitKey(150) & 0xff
    if k == 27:
        break
        
cap.release()
cv.destroyAllWindows()

4

二、光流估计

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

5

  • Lucas-Kanade 算法:
    I ( x , y , t ) = I ( x + d x , y + d y , t + d t ) = I ( x , y , t ) + ∂ I ∂ x d x + ∂ I ∂ y d y + ∂ I ∂ t d t I x d x + I y d y + I t d t = 0 I x u + I y v = − I t → [ I x   I y ] ⋅ [ u v ] I(x, y, t) = I(x+dx, y+dy, t+dt) = I(x, y, t) + \frac{\partial I}{\partial x}dx + \frac{\partial I}{\partial y}dy + \frac{\partial I}{\partial t}dt\\ I_xdx + I_ydy + I_tdt = 0\\ I_xu + I_y v = - I_t → \begin{bmatrix} I_x\ I_y \end{bmatrix}\cdot \begin{bmatrix} u \\ v \end{bmatrix} I(x,y,t)=I(x+dx,y+dy,t+dt)=I(x,y,t)+xIdx+yIdy+tIdtIxdx+Iydy+Itdt=0Ixu+Iyv=It[Ix Iy][uv]
    6

  • cv2.calcOpticalFlowPyrLK()

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

    返回:

    • nextPts 输出跟踪特征点向量;
    • status 特征点是否找到,找到的状态为1,未找到的状态为0。
import numpy as np
import cv2 as cv

cap = cv.VideoCapture('./背景建模与光流估计/test.avi')

# 角点检测所需参数
feature_paras = dict( maxCorners=100,
                      qualityLevel=0.3,
                      minDistance=7)

# lucas kanade参数
lk_paras = dict( winSize=(15, 15),
                 maxLevel=2)

# 随机颜色条
color = np.random.randint(0, 255, (100, 3))

# 拿到第一帧图像
ret, old_frame = cap.read()
old_gray = cv.cvtColor(old_frame, cv.COLOR_BGR2GRAY)

# 返回所有检测特征点,需要输入图像
# 角点最大数量(效率),品质因子(特征值越大的越好,来筛选)
# 距离相当于这区间有比这个角点强的,就不要这个弱的了
p0 = cv.goodFeaturesToTrack(old_gray, mask=None, **feature_paras)

# 创建一个mask
mask = np.zeros_like(old_frame)

while(True):
    ret, frame = cap.read()
    frame_gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
    
    # 需要传入前一帧和当前图像以及前一帧检测到的角点
    p1, st, err = cv.calcOpticalFlowFarneback(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 = cv.line(mask, (a, b), (c, d), color[i].tolist(), 2)
        frame = cv.circle(frame, (a, b), 5, color[i].tolist(), -1)
    img = cv.add(frame, mask)
    
    cv.imshow('Frame', img)
    k = cv.waitKey(150) & 0xff
    if k == 27:
        break
        
    # 更新
    old_gray = frame_gray.copy()
    p0 = good_new.reshape(-1, 1, 2)
    
cv.destroyAllWindows()
cv.release()

7


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

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

相关文章

Redis哨兵机制以及发布订阅

Redis哨兵机制1 哨兵Sentinel机制2 哨兵架构原理3 搭建哨兵架构4 通过springboot操作哨兵Redis发布订阅1 哨兵Sentinel机制 Sentinel(哨兵)是Redis 的高可用性解决方案:由一个或多个Sentinel 实例组成的Sentinel 系统可以监视任意多个主服务…

海格里斯HEGERLS深度解析|重型四向穿梭车的轨道换向组件及轨道系统

随着自动化仓储物流系统的广泛应用,物流设备也更趋于多样化,比如在货架轨道上可四向行走的穿梭车应运而生,重型四向穿梭车作为一种新型的物流存储设备,通常在轨道平面上有行走方向相互垂直的两个行走系统,通过两个行走…

gRPC学习Go版(一)

文章目录微服务入门gRPC是什么proto 服务定义gRPC 优势gRPC入门简单使用一元RPC服务流RPC客户流RPC双工流RPCgRPC底层原理RPC流长度前缀的消息分帧请求消息响应信息通信模式下的消息流微服务入门 现在的软件很少是一个孤立的单体应用运行的,相反更多是通过互联网连接…

玩以太坊链上项目的必备技能(错误处理以及异常-Solidity之旅十四)

错误处理 作为开发者的我们知道,我们所编写出来的程序难免会出现 bug ,而要做的是捕获异常,给用户抛出一个友好地错误提示。 而在 Solidity 中,根据状态恢复异常来处理错误,该异常将撤销在当前调用中对状态所做的所有…

[思维模式-9]:《如何系统思考》-5- 认识篇 - 改变开环、组合逻辑的线性思考,实施闭环、时序逻辑的动态思考。

目录 第1章 因果关系 1.1 因果关系 1.2 因果关系的特点 1.3 因果关系的类型 第2章 线性思考遇到的问题:开环思维、组合逻辑 2.1 开环系统 2.2 组合逻辑 2.3 线性关系 2.4 什么是线性思维:线性因果关系 2.5 线性思维的数学本质 2.6 线性思维的…

自动化药房出药升降机选型设计

一、 运动规划、运动参数的确定 1、 运动参数计算 运动参数主要通过速度规划确定,速度规划采用直线速度特性,如图所示。 运动方程为: 2、 X方向的速度和加速度的估算 已知参数: X方向行程:1…

stream_component_open函数分析

stream_component_open() 函数主要作用是打开 音频流或者视频流 对应的解码器,开启解码线程去解码。 流程图如下: stream_component_open() 的函数定义如下: /* open a given stream. Return 0 if OK */ static int stream_component_open(…

K8S知识点及dashboard操作

1.什么是K8S? K8S是一组服务器集群,可以在集群的各个节点上运行特定的容器。 K8S所管理的是:集群节点上的容器 特性: 自我修复,弹性伸缩(根据实时服务器的并打情况,增加或收缩容器数量&…

网络编程套接字Socket(通过两个用例,逐行注释,详细理解)干活满满建议收藏

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录前言1.分类1.流套接字2.数据报套接字3.原始套接字2.Socket通信模型 3.UDP套接字编程1. DatagramSocket API1.构造方法1.DatagramSocket()2.DatagramSocket(int port)…

C语言之复合类型上卷(十八)(阴阳两极)

上一篇: C语言之内存管理(十七)(转世灵童现世) 逐梦编程,让中华屹立世界之巅。 简单的事情重复做,重复的事情用心做,用心的事情坚持做; 文章目录前言一、什么是结构体?二、结构体的定义及初始化…

USB TO SPI(上海同旺电子)调试器调试MCP3201 A/D 转换器

所需设备: 1、USB TO SPI(上海同旺电子); 2、MCP3201 12 位A/D 转换器; 特性 • 12 位分辨率 • 1 LSB DNL (最大值) • 1 LSB INL (最大值)(MCP3201-B) • 2 LSB INL &#xff…

pdf文件太大怎么变小,如何压缩pdf大小

pdf文件太大怎么变小?如果你是Windows电脑,可以使用PDF编辑器来减小PDF文件的大小,比如这款出色的PDF压缩工具-易我PDF编辑器,它的“压缩”功能提供了两种减小文件大小的方法,这使得它既适合那些只想获得更小的PDF的人…

【vscode】c++程序的自动编译及调试(环境centos)

目录1.新增配置文件(1)c_cpp_properties.json(2)files.associations(3)tasks.json(4)CMakeLists.txt2.断点调试1.新增配置文件 VS Code的配置文件一般是指特定目录下的JSON文件。所谓JSON是一种文本格式&a…

LCF-ATEPC(2020 Elsevier)面向中文的方面级提取和分类

论文题目(Title):A Multi-task Learning Model for Chinese-oriented Aspect Polarity Classification and Aspect Term Extraction (面向中文的方面极性分类和方面项提取的多任务学习模型) 研究问题(Question&#…

适用于 Windows 10/11 电脑 的 5 大好用的离线录屏软件

屏幕录制应用程序可以数字记录出现在任何设备或 PC 屏幕上的内容,并同时以高清流式传输音频和视频。 因此,他们帮助创建营销视频、跟踪客户行为、设计产品演示、监控员工活动、录制教育内容、网络研讨会内容和业务会议内容。 现在您已经意识到屏幕录…

VS系列多通道振弦传感器无线采发仪的数据发送说明

每次设备启动后会将采集到的传感器数据进行内部存储,并在设置好的时间间隔将数据发送出去,通过修改“数据发送方式”参数,监测数据可由数据接口输出也可经由无线网络发送。在发送监测数据时,可通过修改“数据包协议”参数来设置所…

函数和数组习题

个人主页:平行线也会相交 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 平行线也会相交 原创 收录于专栏【C语言基础习题】 文章目录知识点习题2.实现一个整型数组的冒泡排序(编程体)。3.编程题:创建一个整型…

springcloud,springboot各个版本之间的关系

1 版本关系 在实际的开发中如果要自己搭建矿建,发现springcloud,springboot的版本可能是首先需要确定的,那么他们之间的关系是什么呢?看官网,地址 Spring Cloud 左侧是cloud的版本,右侧是对应的文档&…

Splunk Window 客户端迁移

最近客户的Splunk deployment server 要迁移,伴随着client 端的配置也要相应的调整: 先看一下架构: 看一下主要的参数: Summary of key terminology Heres a recap of the key definitions: TermMeaningdeployment serverA Splunk Enterprise instance that acts as a c…

Java中的日期与时间

Java中的日期与时间\huge{Java中的日期与时间}Java中的日期与时间 JavaJavaJava中有很多类是专门用于描述日期类的。 Date类 DateDateDate类:用于表示当前所在系统的日期时间信息。 Date类的构造器 示例: Date d new Date(); System.out.println(d);…