当前位置: 首页 > news >正文

【OpenCV】计算视频的光流并跟踪物体calcOpticalFlowPyrLK

 一、介绍

        计算光流可以使用OpenCV的calcOpticalFlowPyrLK方法,cv2.calcOpticalFlowPyrLK是OpenCV库中的一个函数,用于计算稀疏光流。它实现的是Lucas-Kanade方法,这是一种常用的光流计算方法。

        光流是图像中物体运动的近似表示,它描述了图像中每个像素点在连续两帧之间的移动。Lucas-Kanade方法假设图像中的一个小邻域内的所有像素在运动上是一致的(即具有相同的光流)。

二、原理

        以下是cv2.calcOpticalFlowPyrLK的基本工作原理:

        1. 选择特征点:在第一帧图像中选择一些特征点。这些特征点通常是角点,因为角点具有在所有方向上的变化,更容易被跟踪。

        2. 窗口:对于每一个特征点,定义一个周围的窗口。

        3. 光流:对于每一个窗口,假设所有像素具有相同的光流,然后通过最小化该窗口内像素在第一帧和第二帧之间的亮度差异,来求解光流。

        4. 金字塔:实际上,由于运动可能在不同的尺度上发生,所以cv2.calcOpticalFlowPyrLK实际上在图像的多个尺度(金字塔的每一层)上重复以上步骤。这就是所谓的金字塔Lucas-Kanade方法。

        需要注意的是,由于Lucas-Kanade方法假设一个窗口内的所有像素具有相同的光流,所以它只能处理小的和平滑的运动。对于大的或复杂的运动,需要使用更复杂的方法,如Horn-Schunck方法 

三、代码实现

        下面这段代码实现了识别特征点,并跟踪这些特征点,画出每个点的移动轨迹

import numpy as np
import cv2src_path = r'input.mp4'
target_path = r'output.mp4'fps = 25
cap = cv2.VideoCapture(src_path)# ShiTomasi corner detection的参数
feature_params = dict(maxCorners=300,qualityLevel=0.3,minDistance=7,blockSize=7)
# 光流法参数
# maxLevel 未使用的图像金字塔层数
lk_params = dict(winSize=(10, 10),maxLevel=2,criteria=(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))ret, old_frame = cap.read()                             # 取出视频的第一帧
old_gray = cv2.cvtColor(old_frame, cv2.COLOR_BGR2GRAY)  # 灰度化
p0 = cv2.goodFeaturesToTrack(old_gray, mask=None, **feature_params)
mask = np.zeros_like(old_frame)                         # 为绘制创建掩码图片
h, w, _ = old_frame.shape
target_video = cv2.VideoWriter(target_path,cv2.VideoWriter_fourcc(*"H264"), fps, (w, h))
while True:res, frame = cap.read()if not res:breakframe_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)# 计算光流以获取点的新位置p1, st, err = cv2.calcOpticalFlowPyrLK(old_gray, frame_gray, p0, None, **lk_params)# 选择good pointsgood_new = p1[st == 1]good_old = p0[st == 1]good_new1 = good_new.copy()for i, (new, old) in enumerate(zip(good_new, good_old)):a, b = new.ravel()c, d = old.ravel()mask = cv2.line(mask, (int(a), int(b)), (int(c), int(d)), (0,255,0), 3)frame = cv2.circle(frame, (int(a), int(b)), 5, (0,255,0), -1)img = cv2.add(frame, mask)target_video.write(img)old_gray = frame_gray.copy()p0 = good_new1.reshape(-1, 1, 2)target_video.release()
cv2.destroyAllWindows()
cap.release()

四、参数解释

1.calcOpticalFlowPyrLK输入参数解释

1. prevImg:上一帧输入图像。

2. nextImg:本轮输入图像。

3. prevPts:从上一帧图像中提取的特征点(2D点向量)。

4. nextPts:从本轮图像中提取的点(2D点向量),包含计算得到的新位置。

5. winSize:每一级金字塔的搜索窗口大小。默认值是Size(21,21)。

        图像金字塔是通过对原始图像进行连续的下采样操作得到的一系列图像,每一层的图像都比上一层的图像小。这就像一个金字塔,底部是原始的大图像,顶部是最小的图像。图像金字塔被用于处理不同尺度的运动。这是因为在实际的图像中,物体的运动可能在不同的尺度上发生。例如,远离摄像头的物体在图像中的运动可能比较小,而靠近摄像头的物体在图像中的运动可能比较大。通过在图像金字塔的每一层上计算光流,可以处理这种不同尺度的运动。

6. maxLevel:基于0的最大金字塔等级数;如果设置为0,则不使用金字塔(单级),如果设置为1,则使用两级等。默认值是3。

        在构建图像金字塔时,从原始图像开始,每一层图像的尺寸都是上一层图像尺寸的一半,maxLevel就是这个金字塔的最大层数。maxLevel=0表示只使用原始图像,maxLevel=1表示原始图像和它的一半尺寸的图像,maxLevel=2表示原始图像、一半尺寸的图像和四分之一尺寸的图像,以此类推。

7. criteria:criteria是一个重要的参数,需要详细说一下,该参数是一个指定迭代搜索算法的终止准则的元组。它包含三个元素:
        (1) cv2.TERM_CRITERIA_EPS 或 cv2.TERM_CRITERIA_COUNT 或两者的组合。这些是终止准则的类型:
- cv2.TERM_CRITERIA_EPS:达到指定的精度epsilon时,迭代就会停止。
- cv2.TERM_CRITERIA_COUNT:达到指定的最大迭代次数时,迭代就会停止。
- cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT:当任一上述条件满足时,迭代就会停止。
        (2) 最大迭代次数。在这个例子中,最大迭代次数是10。
        (3)epsilon,即所需的精度。在这个例子中,epsilon是0.03。
例如,criteria=(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03)意味着迭代将在达到10次迭代或误差精度达到0.03时停止,以先到达的条件为准 

8. flags:操作标志。可以设置为

        (1)0:没有特殊行为。

        (2)cv2.OPTFLOW_USE_INITIAL_FLOW:如果设置了这个标志,那么函数会使用nextPts参数中的点作为初始近似值,然后进行优化。否则,它会直接使用prevPts参数中的点作为初始值。
         (3)cv2.OPTFLOW_LK_GET_MIN_EIGENVALS:如果设置了这个标志,那么函数会计算每个点的最小特征值并将它们存储在err参数中。

        0,cv2.OPTFLOW_USE_INITIAL_FLOW或cv2.OPTFLOW_LK_GET_MIN_EIGENVALS。

        例如,如果你想使用nextPts中的点作为初始近似值,你可以这样调用函数:

p1, st, err = cv2.calcOpticalFlowPyrLK(old_gray, frame_gray, p0, None, flags=cv2.OPTFLOW_USE_INITIAL_FLOW, **lk_params)

9. minEigThreshold:最小特征值的阈值。默认值是1e-4。

这个函数的主要目的是使用Lucas-Kanade方法在两个图像之间跟踪一些特征点(prevPts)。这些特征点的新位置被存储在nextPts中。如果一个点不能被跟踪(例如,因为它走出了图像),那么status向量的相应元素就会被设置为0 

2.calcOpticalFlowPyrLK输出参数解释

1. nextPts:这是一个数组,包含了在下一帧图像中找到的输入特征点的新位置。

2. status:这是一个数组,和输入的特征点数组大小相同。如果status[i]为1,表示找到了第i个特征点的新位置,如果为0,表示没有找到。

3. err:这是一个数组,和输入的特征点数组大小相同。err[i]表示第i个特征点的新位置和原位置之间的误差,这个误差是基于窗口大小的。

这三个输出参数可以用于理解和评估光流的计算结果。例如,你可以检查status数组来看哪些特征点在下一帧图像中被成功找到,或者查看err数组来评估光流的计算精度 

        calcOpticalFlowPyrLK的用法就简单介绍到这,关注不迷路(#^.^#)

相关文章:

【OpenCV】计算视频的光流并跟踪物体calcOpticalFlowPyrLK

一、介绍 计算光流可以使用OpenCV的calcOpticalFlowPyrLK方法,cv2.calcOpticalFlowPyrLK是OpenCV库中的一个函数,用于计算稀疏光流。它实现的是Lucas-Kanade方法,这是一种常用的光流计算方法。 光流是图像中物体运动的近似表示&#…...

C语言进阶

数组 在基础篇说过,数组实际上是构造类型之一,是连续存放的。 一维数组 定义 定义格式:[存储类型] 数据类型 数组名标识符[下标]; 下面分模块来介绍一下数组的定义部分的内容。 1、初始化和元素引用: 可以看到数组是连续存储…...

Linux之gdb

gdb就是一个Linux的调试工具,类似与vs里面的调试 可执行程序也有格式,不是简单的二进制堆砌...

100天精通风控建模(原理+Python实现)——第3天:风控建模中如何处理缺失值?

风控模型已在各大银行和公司都实际运用于业务,用于营销和风险控制等。    之前已经阐述了100天精通风控建模(原理+Python实现)——第1天:什么是风控建模?    100天精通风控建模(原理+Python实现)——第2天:风控建模有什么目的?    接下来看下100天精通风控建模(原理…...

Leetcode—680.验证回文串II【简单】

2023每日刷题&#xff08;二十七&#xff09; Leetcode—680.验证回文串II 实现代码 class Solution { public:bool judgeFunc(string s, int left, int right) {while(left < right) {if(s[left] ! s[right]) {return false;}left;right--;}return true;}bool validPalin…...

Redis五种数据类型及命令操作(二)

&#x1f388;个人公众号:&#x1f388; :✨✨✨ 可为编程✨ &#x1f35f;&#x1f35f; &#x1f511;个人信条:&#x1f511; 知足知不足 有为有不为 为与不为皆为可为&#x1f335; &#x1f349;本篇简介:&#x1f349; 本篇记录Redis五种数据类型及命令操作&#xff0c;如…...

低代码信创开发核心技术(三):MDA模型驱动架构及元数据系统设计

前言 写最后一篇文章的时候&#xff0c;我本人其实犹豫了半年&#xff0c;在想是否发布出这篇文章&#xff0c;因为可能会动了很多人的利益。所以这篇文章既是整个低代码信创开发的高度总结&#xff0c;也是最为精华的一部分&#xff0c;它点明了低代码中最为核心的技术。虽然…...

HslCommunication模拟西门子读写数据

导入HslCommunication C#端代码&#xff08;上位机&#xff09; 这里要注意的是上位机IP用的当前电脑的IP。 using HslCommunication; using HslCommunication.Profinet.Siemens; using System; using System.Collections.Generic; using System.ComponentModel; using Syste…...

多测师肖sir_高级金牌讲师_ui自动化po框架版本02

ui自动化po框架版本02 一、 pages下的BasePage.py模块 此模块是封装所有用例的基类 比如说&#xff1a;所有用例要用到的元素定位&#xff0c;以及输入框输入&#xff0c;点击&#xff0c;下拉等等公共方法import unittest #导入unittest 框架 from time import *# 调试代码…...

线性判别分析(Linear Discriminant Analysis,LDA)

Linear Discriminant Analysis&#xff08;LDA&#xff09; 输入&#xff1a; 原始数据$D((x_1,y_1),(x_2,y_2),...,(x_m,y_m)$ 、​ 类别标签$Y[y_1,y_2,...,y_n]$、​ 降维到的维度d输出&#xff1a; 投影矩阵W、投影后的样本$Z$、算法步骤&#xff1a; 1.计算类内散度…...

git的分支及标签使用及情景演示

目录 一. 环境讲述 二.分支 1.1 命令 1.2情景演练 三、标签 3.1 命令 3.2 情景演示 ​编辑 一. 环境讲述 当软件从开发到正式环境部署的过程中&#xff0c;不同环境的作用如下&#xff1a; 开发环境&#xff1a;用于开发人员进行软件开发、测试和调试。在这个环境中…...

深度解析找不到msvcp120.dll相关问题以及解决方法

​在计算机使用过程中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中之一就是“msvcp120.dll丢失”。这个错误通常会导致某些应用程序无法正常运行&#xff0c;给用户带来很大的困扰。那么&#xff0c;如何解决msvcp120.dll丢失的问题呢&#xff1f;本文将为大家介绍…...

SQL Server 2022 安装步骤——SQL Server设置身份验证教程

目录 前言: 安装详细步骤: 第一步: 第二步: 第三步: 第四步: SQL Server 连接的方式: Window验证: SQL Server验证: 两者之间区别: 总结: SQL Server身份验证登录配置教程:​ 第一步: 第二步: 第三步: 番外篇: 前言: 本文讲解&#xff0c;如何安装SQL Server安…...

Maven各方面配置好了却无法显示版本

今天配置了maven环境&#xff0c;各方面都配置好了命令行却一直没办法显示maven的版本&#xff0c;原因 竟是两个JDK导致maven无法选择&#xff0c;因为maven依赖于JDK&#xff0c;导致在选择JDK的时候差生了二义 性&#xff0c;在环境变量里面删除不常用的JDK&#xff0c;只…...

Jdk 1.8 for mac 详细安装教程(含版本切换)

Jdk 1.8 for mac 详细安装教程&#xff08;含版本切换&#xff09; 官网下载链接 https://www.oracle.com/cn/java/technologies/downloads/#java8-mac 一、选择我们需要安装的jdk版本&#xff0c;这里以jdk8为例&#xff0c;下载 macOS 版本&#xff0c;M芯片下载ARM64版本…...

02MyBatisPlus条件构造器,自定义SQL,Service接口

一、条件构造器 1.MyBatis支持各种复杂的where条件&#xff0c;满足开发的需求 Wrapper是条件构造器&#xff0c;构建复杂的where查询 AbstractWrapper有构造where条件的所有方法&#xff0c;QueryWrapper继承后并有自己的select指定查询字段。UpdateWrapper有指定更新的字段的…...

c语言练习11周(6~10)

输入任意字串&#xff0c;将串中除了首尾字符的其他字符升序排列显示&#xff0c;串中字符个数最多20个。 题干 输入任意字串&#xff0c;将串中除了首尾字符的其他字符升序排列显示&#xff0c;串中字符个数最多20个。输入样例gfedcba输出样例gbcdefa 选择排序 #include<s…...

钉钉API与集简云无代码开发连接:电商平台与营销系统的自动化集成

连接科技与能源&#xff1a;钉钉API与集简云的一次集成尝试 在数字化时代&#xff0c;许多公司面临着如何将传统的工作方式转变为更智能、高效的挑战。某能源科技有限公司也不例外&#xff0c;他们是一家专注于能源科技领域的公司&#xff0c;产品包括节能灯具、光伏逆变器、电…...

C++算法:包含三个字符串的最短字符串

涉及知识点 有序集合 字符串 题目 给你三个字符串 a &#xff0c;b 和 c &#xff0c; 你的任务是找到长度 最短 的字符串&#xff0c;且这三个字符串都是它的 子字符串 。 如果有多个这样的字符串&#xff0c;请你返回 字典序最小 的一个。 请你返回满足题目要求的字符串。…...

华为开源carbondata中的使用问题处理

carbondata中的使用问题处理 Q&#xff1a;什么是不良记录&#xff1f; A&#xff1a;由于数据类型不兼容而无法加载到CarbonData中的记录或为空或具有不兼容格式的记录被归类为不良记录。 Q&#xff1a;CarbonData中的不良记录存储在哪里&#xff1f; A&#xff1a;不良记录…...

如何在看板中体现优先级变化

在看板中有效体现优先级变化的关键措施包括&#xff1a;采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中&#xff0c;设置任务排序规则尤其重要&#xff0c;因为它让看板视觉上直观地体…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建

制造业采购供应链管理是企业运营的核心环节&#xff0c;供应链协同管理在供应链上下游企业之间建立紧密的合作关系&#xff0c;通过信息共享、资源整合、业务协同等方式&#xff0c;实现供应链的全面管理和优化&#xff0c;提高供应链的效率和透明度&#xff0c;降低供应链的成…...

Java - Mysql数据类型对应

Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)

宇树机器人多姿态起立控制强化学习框架论文解析 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架&#xff08;一&#xff09; 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...

多模态大语言模型arxiv论文略读(108)

CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题&#xff1a;CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者&#xff1a;Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...

技术栈RabbitMq的介绍和使用

目录 1. 什么是消息队列&#xff1f;2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...

基于Springboot+Vue的办公管理系统

角色&#xff1a; 管理员、员工 技术&#xff1a; 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能&#xff1a; 该办公管理系统是一个综合性的企业内部管理平台&#xff0c;旨在提升企业运营效率和员工管理水…...

uniapp 开发ios, xcode 提交app store connect 和 testflight内测

uniapp 中配置 配置manifest 文档&#xff1a;manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号&#xff1a;4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...

MinIO Docker 部署:仅开放一个端口

MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...