OpenCV进阶操作:光流估计
文章目录
- 前言
- 一、光流估计
- 1、光流估计是什么?
- 2、光流估计的前提?
- 1)亮度恒定
- 2)小运动
- 3)空间一致
- 3、OpenCV中的经典光流算法
- 1)Lucas-Kanade方法(稀疏光流)
- 2) Farneback方法(稠密光流)
- 3)DIS光流(快速稠密光流)
- 二、使用步骤
- 1、读取视频
- 2、特征检测
- 3、处理每一帧画面
- 4、运行结果
- 5、完整代码
- 总结
前言
光流(Optical Flow)是计算机视觉中用于描述图像序列中物体运动模式的核心技术。从视频稳定到自动驾驶,从动作识别到增强现实,光流估计在动态场景分析中扮演着关键角色。OpenCV提供了多种光流算法实现,本文将深入解析其原理与实践方法。
一、光流估计
1、光流估计是什么?
光流估计是空间运动物体在观测成像平面上的像素运动的“瞬时速度”,根据各个像素点的速度矢量特征,可以对图像进行动态分析,例如目标跟踪。
2、光流估计的前提?
1)亮度恒定
同一点随着时间的变化,其亮度不会发生改变。
2)小运动
随着时间的变化不会引起位置的剧烈变化,只有小运动情况下才能用前后帧之间单位位置变化引起的灰度变化去近似灰度对位置的偏导数。
3)空间一致
一个场景上邻近的点投影到图像上也是邻近点,且邻近点速度一致。因为光流法基本方程约束只有一个,而要求x,y方向的速度,有两个未知变量。所以需要连立n多个方程求解。
3、OpenCV中的经典光流算法
1)Lucas-Kanade方法(稀疏光流)
-
原理:对局部窗口内的像素应用最小二乘法求解
-
特点:仅跟踪关键特征点
-
计算效率高,适合实时应用
-
函数:cv2.calcOpticalFlowPyrLK()
2) Farneback方法(稠密光流)
-
原理:通过多项式展开近似邻域像素
-
特点:计算每个像素的运动向量
-
资源消耗较大,但信息更丰富
-
函数:cv2.calcOpticalFlowFarneback()
3)DIS光流(快速稠密光流)
-
原理:基于变分方法的快速实现
-
特点:速度与精度的平衡方案
-
函数:cv2.DISOpticalFlow_create()
二、使用步骤
1、读取视频
import numpy as np
import cv2
cap = cv2.VideoCapture('test.avi')
#随机生成颜色,用于绘制轨迹
color = np.random.randint(0,255,(100,3))
ret,old_frame = cap.read()
old_gray = cv2.cvtColor(old_frame,cv2.COLOR_BGR2GRAY)
2、特征检测
feature_params = dict(maxCorners=100,qualityLevel=0.3,minDistance=7)
p0 = cv2.goodFeaturesToTrack(old_gray, mask=None, **feature_params)
mask = np.zeros_like(old_frame)
lk_params = dict(winSize=(15,15),maxLevel=2)
3、处理每一帧画面
while True:ret,frame = cap.read()if not ret:breakframe_gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)p1,st,err = cv2.calcOpticalFlowPyrLK(old_gray,frame_gray,p0,None,**lk_params)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()a,b,c,d = int(a),int(b),int(c),int(d)mask = cv2.line(mask,(a,b),(c,d),color[i].tolist(),2)cv2.imshow('mask',mask)img = cv2.add(frame,mask)cv2.imshow('frame',img)k = cv2.waitKey(10)if k == 27:breakold_gray = frame_gray.copy()p0 = good_new.reshape(-1,1,2)cv2.destroyAllWindows()
cap.release()
4、运行结果
5、完整代码
import cv2
import numpy as np# 打开视频文件
cap = cv2.VideoCapture('test.avi')
color = np.random.randint(0,255,(100,3)) # 生成随机整数数组,值范围为0-255,格式为100*3,以此充当颜色用来绘制轨迹,此处的值为矩阵类型
ret,old_frame = cap.read() # 读取视频的di一帧画面,返回读取状态布尔值和每一帧的图像
old_gray = cv2.cvtColor(old_frame,cv2.COLOR_BGR2GRAY) # 将第一帧转换为灰度图# 定义特征点检测参数
feature_params = dict(maxCorners=100, # 最大角点数量,特征点qualityLevel = 0.3, # 角点质量的阚值minDistance = 7) # 两个特征点最小欧式距离,用于分散角点# 对第一帧画面进行特征检测
p0 = cv2.goodFeaturesToTrack(old_gray,mask=None,**feature_params) # **:关键字参数解包,用于将字典解包为关键字参数,# 创建一个与给定数组大小和数据类型都相同的全0的新的数组,将其当做掩膜
mask = np.zeros_like(old_frame)#定义Lucas-Kanade光流参数
lk_params = dict(winSize=(15,15), # 窗口大小为15*15maxLevel=2) # 金字塔层数为2# 主循环,处理视频的每一帧
while (True): # 定义一个死循环ret,frame = cap.read() # 上述已经读取了第一帧画面,再次读取会接着第二帧进行读取if not ret: # 检查是否成功读取到breakframe_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 转换为灰度图# calcOpticalFlowPyrLK在图像序列中跟踪特征点的运动,计算前一帧old_gray特征点p0在当前帧frame_gray中的新位置p1p1,st,err = cv2.calcOpticalFlowPyrLK(old_gray,frame_gray,p0,None,**lk_params)# p1 特征点新坐标# st 状态数组,表示每个特征点是否被成功跟踪,1表示成功,0表示失败# err 错误数组,包含每个特征点的跟踪误差,误差与匹配质量有关# 选择好的点(状态为1的点)good_new = p1[st == 1]good_old = p0[st == 1]# 绘制轨迹for i,(new,old) in enumerate(zip(good_new,good_old)): # 将新的特征点和旧的特征点进行打包,因为有很多特针点,所以使用enumerate将其转变成可迭代对象,返回索引和值a,b = new.ravel() # 获取新点的坐标(a,b), 或者使用[a,b]= new,ravel()将多维数组展平成一维数组,一维视图,返回一维数组c,d = old.ravel() # 获取旧点的坐标a,b,c,d = int(a),int(b),int(c),int(d) # 将数值转换为整数# 在掩模上给制线段,连接新点和旧点mask = cv2.line(mask,(a,b),(c,d),color[i].tolist(),2) # 绘制线,在mask图像上绘制从点(a,b)到(c,d)的线,颜色为上述定义的,每个特征点的颜色不同cv2.imshow( 'mask', mask)img = cv2.add(frame, mask) # 使用add叠加图像,将mask图像叠加到当前帧frame上cv2.imshow('frame', img) # 显示结果图像# 等待150ms,检测是否按下了Esc键(键码为27)k = cv2.waitKey(150) & 0xffif k == 27: # 按下ESC键,退出循环break# 更新旧灰度图和旧特征点old_gray = frame_gray.copy() # 每当绘制完当前帧与上一帧的图像后将当前帧的副本赋值给上一帧使其进入下一个循环# 将当前帧的特征点的新位置赋值给p0,重新整理特征点为适合下次计算的形状p0 = good_new.reshape(-1,1,2) # 将当前帧关键点的坐标形状更改为3维,-1表示自动判断维度大小,1,2表示一行两列# 释放资源
cv2.destroyAllWindows() # 关闭所有页面
cap.release() # 释放摄像头资源
总结
OpenCV的光流工具为运动分析提供了强大支持,
-
稀疏光流适合实时跟踪,稠密光流适合精细分析
-
参数调优需在精度与效率之间取得平衡
-
结合传统图像处理与深度学习可获得更鲁棒的结果
相关文章:
OpenCV进阶操作:光流估计
文章目录 前言一、光流估计1、光流估计是什么?2、光流估计的前提?1)亮度恒定2)小运动3)空间一致 3、OpenCV中的经典光流算法1)Lucas-Kanade方法(稀疏光流)2) Farneback方…...
2025年渗透测试面试题总结-渗透测试红队面试八(题目+回答)
网络安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 渗透测试红队面试八 二百一十一、常见中间件解析漏洞利用方式 二百一十二、MySQL用户密码存储与加密 …...
前端面试高频50个问题,解答
以下是前端面试中常见的50个高频问题及其简要解答: HTML HTML5 有哪些新特性? 语义化标签(如 <header>、<footer>)、多媒体支持(如 <audio>、<video>)、本地存储(如 l…...
Elasticsearch架构原理
1、Elasticsearch的节点类型 1.1 Master节点 在Elasticsearch启动时,会选举出来一个Master节点。当某个节点启动后,然后 使用Zen Discovery机制找到集群中的其他节点,并建立连接。 discovery.seed_hosts: ["192.168.21.130", &qu…...
前端面试宝典---webpack面试题
webpack 的 tree shaking 的原理 Webpack 的 Tree Shaking 过程主要包含以下步骤: 模块依赖分析:Webpack 首先构建一个完整的模块依赖图,确定每个模块之间的依赖关系。导出值分析:通过分析模块之间的 import 和 exportÿ…...
Vue 2 项目中配置 Tailwind CSS 和 Font Awesome 的最佳实践
Vue 2 项目中配置 Tailwind CSS 和 Font Awesome 的最佳实践 一、Tailwind CSS 配置 1. 安装依赖 npm install tailwindcssnpm:tailwindcss/postcss7-compat tailwindcss/postcss7-compat postcss^7 autoprefixer^92. 创建配置文件 npx tailwindcss init3. 创建样式文件 在…...
hiveserver2与beeline进行远程连接hive配置及遇到的问题
1、hiveserver2 参与用户模拟功能,因为开启后才能保证各用户之间的权限隔离。 1.1、配置 $HADOOP_HOME/etc/hadoop/core-site.xml <!--配置所有节点的root用户都可作为代理用户--> <property><name>hadoop.proxyuser.root.hosts</name>&…...
单词短语0512
当然可以,下面是“opportunity”在考研英语中的常用意思和高频短语,采用大字体展示,便于记忆: ✅ opportunity 的考研常用意思: 👉 机会,良机 表示有利的时机或条件,尤指成功的可能…...
c++刷题便捷函数(类似于stoi的小函数)
标题 stoi(字符串转整形)map和set都有count成员函数,返回值是该key的个数,可以用来查是否存在该元素。bool is_sorted(nums.begin(), nums.end() 检验是否有序INT_MAX,INT_MIN分别是整形最大和最小初始化二维矩阵 vector<vector\<int>> mart…...
想实现一个基于MCP的pptx生成系统架构图【初版实现】
技术栈:Python + MCP协议 + python-pptx + FastMCP 核心创新点:通过MCP协议实现PPTX元素的动态化生成与标准化模板管理 当前还是个半成品,后续持续更新。 主要先介绍一下思路。 一、MCP协议与系统设计原理 1.1 为什么选择MCP? 标准化工具调用:通过MCP将PPTX元素生成逻辑封…...
jwt学习
基于token的鉴权机制也是无状态的(类似于http协议),不需要保在服务端保留用户的认证或会话信息。 构成 jwt由三部分构成:头部、payload、签名,中间用.隔开 头部(header) 包含两部分信息:声明类型、声明加密的算法 例如:…...
pth的模型格式怎么变成SafeTensors了?
文章目录 背景传统模型格式的安全隐患效率与资源瓶颈跨框架兼容性限制Hugging Face 的解决方案:SafeTensors行业与社区的推动SafeTensors 的意义总结 背景 最近要找一些适合embedding的模型,在huggingface模型库上看到一些排名比较靠前的,准…...
如何判断IP是否被平台标记
一、基础检测:连通性与黑名单筛查 网络连通性测试 Ping与Traceroute:通过命令测试延迟和路由路径,若延迟>50ms或存在异常节点(如某跳延迟>200ms),可能影响可用性。示例命令: bash ping 8.…...
【c++】异常详解
目录 C语言处理错误的局限性异常的定义异常的具体使用细则异常的抛出与捕获在函数调用链中异常栈展开匹配原则异常的重新抛出异常规范throw(类型)noexcept 成熟的异常体系c自己的异常体系异常的优缺点优点缺点 异常安全 C语言处理错误的局限性 C语言处理错误常常会用到assert和…...
从模型加密到授权交付,CodeMeter赋能3D打印商业化全流程
引言 在数字化制造快速演进的当下,3D 打印(增材制造)作为具备高度灵活性与创新潜力的制造方式,正重塑备件供应链与产品生命周期管理。然而,随着应用场景不断扩展,企业面临的知识产权保护、数字资产商业化与…...
ESP32开发之freeRTOS的事件组
什么是事件组事件组的应用场景事件组的API函数事件组应用举例总结什么是事件组 概念:事件组就是一个整数,高8位给内核使用,其他位用来表示事件。在ESP32的IDF freeRTOS中,这个整数是32位的,低24位用来供事件组使用。 举一个生活中的例子: 你在等快递,有三个包裹来自不…...
K8S中构建双架构镜像-从零到成功
背景介绍 公司一个客户的项目使用的全信创的环境,服务器采用arm64的机器,而我们的应用全部是amd64的,于是需要对现在公司流水线进行arm64版本的同步镜像生成。本文介绍从最开始到最终生成双架构的全部过程,以及其中使用的相关配置…...
腾讯怎样基于DeepSeek搭建企业应用?怎样私有化部署满血版DS?直播:腾讯云X DeepSeek!
2025新春,DeepSeek横空出世,震撼全球! 通过算法优化,DeepSeek将训练与推理成本降低至国际同类模型的1/10,极大的降低了AI应用开发的门槛。 可以预见,2025年,是AI应用落地爆发之年! ✔…...
【论信息系统项目的质量管理】
论信息系统项目的质量管理 前言一、抓好质量管理规划工作,为质量管理和确认提供指南和方向。二、做好管理质量相关工作,促进质量过程改进。三、抓好控制质量,确保实现质量目标四、综合协调质量与成本、进度、范围的关系总结 前言 为解决日常出…...
SpringAI框架中的RAG模块详解及应用示例
SpringAI框架中的RAG模块详解及应用示例 RAG(Retrieval-Augmented Generation)可以通过检索知识库,克服大模型训练完成后参数冻结的局限性,携带知识让大模型根据知识进行回答。SpringAI框架提供了模块化的API来支持RAG࿰…...
图像增强技术
一、目的 通过本实验加深对数字图像增强操作的理解,熟悉MATLAB中的有关函数;了解直方图均衡化和卷积滤波的原理;熟悉低通和高通滤波模板的构造方法。 二、实验内容与设计思想 1、观察实验结果可看出, 原图像 I的对比度较低&…...
【Java学习笔记】多态参数
多态参数 应用:方法定义的形参类型为父类类型,实参允许为子类类型 // 父类 package polyparemeter;public class employee {private String name;private double salary;//构造器public employee(){}public employee(String name, double salary) {thi…...
计算机网络核心技术解析:从基础架构到应用实践
计算机网络作为现代信息社会的基石,承载着全球数据交换与资源共享的核心功能。本文将从网络基础架构、核心协议、分层模型到实际应用场景,全面解析计算机网络的核心技术,并结合行业最新趋势,为读者构建系统的知识体系。 一、计算机…...
LiveData:Android响应式编程的核心利器
LiveData是一种可观察的数据持有类,用于在Android应用中实现数据的响应式编程。它具有以下特点和作用: 特点 生命周期感知:LiveData能够感知与其关联的组件(如Activity、Fragment)的生命周期状态。只有当组件处于活跃状态(如Activity处于RESUMED状态)时,LiveData才会将…...
【LeeCode】1.两数之和
文章目录 1. 暴力求解2. 哈希表具体过程1. nums [2, 7, 11, 15],target 9:2. nums [11, 15, 2, 7], target 9 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数ÿ…...
继承关系下创建对象的具体流程
public class Person {int x initX(); // 显式初始化:调用方法 initX()public Person() {System.out.println("Parent 构造器执行, x " x);}int initX() {System.out.println("initX() 被调用了");return 100;} }public class Child extends…...
基于世界土壤数据库(HWSD)的中国土壤数据集(v1.1)(2009)
时间分辨率:年共享方式:开放获取数据大小:156.47 MB数据时间范围:2009元数据更新时间:2020-03-26 数据集摘要 数据来源于联合国粮农组织(FAO)和维也纳国际应用系统研究所(IIASA)所构建的世界土…...
mac M2能安装的虚拟机和linux系统系统
目前网上的资料大多错误,能支持M2的很少。 推荐安装的改造过的centos7也无法进行yum操作,建议安装centos8 VMware Fusion下载地址: https://pan.baidu.com/s/14v3Dy83nuLr2xOy_qf0Jvw 提取码: jri4 centos8下载地址: https://…...
212. 单词搜索 II【 力扣(LeetCode) 】
文章目录 零、原题链接一、题目描述二、测试用例三、解题思路四、参考代码 零、原题链接 212. 单词搜索 II 一、题目描述 给定一个 m x n 二维字符网格 board 和一个单词(字符串)列表 words, 返回所有二维网格上的单词 。 单词必须按照字母…...
【软考-高级】【信息系统项目管理师】论文写作注意事项及2014年至2024年历年论文题目汇总
论文写作注意事项 要求 字数要求:2500字以内(2024年超过2500字,在线答题系统无法输入)时长要求:2小时(大多数人不够用)内容要求: 必须响应子标题,如子标题要求写如何优…...
MySQL数据库表的约束
目录 1.null属性 2.默认值约束(default) 3.comment 4.zerofill 5.主键(primary key) 6.自增长(auto_increment) 7.唯一键(unique) 编辑 8.外键 约束是为了安全插入数据&a…...
硅基计划2.0 学习总结 壹 Java初阶
一、初见Java (1)Java简介 首先不得不承认Java是一门优秀的程序设计语言 其系列的计算机软件和跨平台体系包括国内的生态链完善是C/C语言难以弥补的 (2)Java SE 全称Java Standard Edition,是Java体系的基础 &am…...
逆向破解:x64dbg
文章目录 一、CPU窗口1、反汇编窗口2、寄存器窗口3、栈地址窗口4、十六进制数据窗口5、堆栈参数解析窗口 二、常用快捷键三、字符串检索功能四、调试功能1、上一步 一、CPU窗口 1、反汇编窗口 2、寄存器窗口 寄存器窗口用于显示和解释当前线程环境下CPU寄存器的各种状态值和内…...
从MCU到SoC的开发思维转变
目录 1、硬件设计 2、软件开发 3、调试与测试 4、电源管理 微控制器单元(MCU)和系统级芯片(SoC)是嵌入式开发中最常见的两种处理器类型。MCU以其简单、低功耗的特点,广泛应用于特定控制任务;而SoC凭借强…...
3DGS-to-PC:3DGS模型一键丝滑转 点云 or Mesh 【Ubuntu 20.04】【2025最新版!!】
一、引言 3D高斯泼溅(3DGS)是一种新兴的三维场景表示方法,可以生成高质量的场景重建结果。然而,要查看这些重建场景,需要特殊的高斯渲染器。大多数3D处理软件并不兼容3D高斯分布模型,但它们通常都兼容点云文件。 3DGS-to-PC项目提…...
互联网大厂Java求职面试:优惠券服务架构设计与AI增强实践-3
互联网大厂Java求职面试:优惠券服务架构设计与AI增强实践-3 场景背景 面试场景设定在一家大型互联网公司,面试官为拥有10年以上经验的技术总监,专注于高并发、高可用系统的架构设计。候选人郑薪苦是一名技术潜力十足的程序员,擅…...
ABP-Book Store Application中文讲解 - 前期准备 - Part 3:Acme.BookStore项目模块详解
ABP-Book Store Application中文讲解-汇总-CSDN博客 本文通过对Acme.BookStore项目各模块的详解,让大家知道每个project用来干什么的,他们之间的引用关系是什么,同时知道怎样添加新的功能模块。 Acme.Bookstore 是主要 ABP Studio 模块的主…...
智慧城市综合运营管理系统Axure原型
这款Axure原型的设计理念紧紧围绕城市管理者的需求展开。它旨在打破传统城市管理中信息孤岛的局面,通过统一标准接入各类业务系统,实现城市运营管理信息资源的全面整合与共享。以城市管理者为中心,为其提供一个直观、便捷、高效的协同服务平台…...
Java中进阶并发编程
第一章、并发编程的挑战 并发和并行:指多线程或多进程 线程的本质:操作系统能够进行运算调度的最小单位,是进程(Process)中的实际工作单元 进程的本质:操作系统进行资源分配和调度的基本单位,…...
cursor 出现问题 为客户解决问题
文档出自:https://www.kdocs.cn/l/cp5GpLHAWc0p...
【氮化镓】GaN在不同电子能量损失的SHI辐射下的损伤
该文的主要发现和结论如下: GaN的再结晶特性 :GaN在离子撞击区域具有较高的再结晶倾向,这导致其形成永久损伤的阈值较高。在所有研究的电子能量损失 regime 下,GaN都表现出这种倾向,但在电子能量损失增加时,其效率会降低,尤其是在材料发生解离并形成N₂气泡时。 能量损失…...
用drawdb.app可视化创建mysql关系表
平时自己建表,没有可视化图形参考 为了便于理解,用drwadb画mysql关系表 drawDB | Online database diagram editor and SQL generator...
模型上下文协议(MCP):AI的“万能插座”
~犬📰余~ “我欲贱而贵,愚而智,贫而富,可乎? 曰:其唯学乎” 一、MCP解决什么问题? \quad 在过去的几年中,AI大模型快速发展,从横空出世的GPT到“AI界拼多多”DeepSeek&am…...
初识 Pandas:Python 数据分析的利器
在数据分析、数据清洗和可视化等领域,Python 无疑是最受欢迎的语言之一,而在 Python 的数据处理生态中,Pandas 是最核心、最基础的库之一。如果你接触数据分析、机器学习、金融建模,或者只是想处理一些 Excel 表格,那么…...
Python教程(四)参数提取pymysql
Python(四) 本系列其他教程: Python教程(二):函数、异常、模块&包、文件读取、常用模块 Python教程(三):类&对象、闭包、装饰器、类型注解 Python教程(三):类&对象、闭包、装饰器、类型注解、…...
Halcon案例(一):C#联合Halcon识别路由器上的散热孔
本案例分3部分 识别效果,分别显示识别前后识别后;代码展示,分别是Halcon源码和Halcon转为C#的代码代码解释(解释在源码中) 原图如下: 处理后的图像: Halcon源码: *读取一张图像 read_image (Image, progres)*获取图像大小 get_image_size (Image, Width, Height)*关…...
SC5061串口设备联网服务器,4路RS-232,4路422/485串行接口
串口设备联网服务器,简称串口服务器。能够将RS-232/485/422串口设备联入TCP/IP网络,实现RS-232/485/422串口与TCP/IP网络接口的数据双向传输,使得串口设备能够具备联网功能,根据串口数量的不同,可以分为单串口、两串口…...
谈AI/OT 的融合
过去的十几年间,工业界讨论最多的话题之一就是IT/OT 融合,现在,我们不仅要实现IT/OT 的融合,更要面向AI/OT 的融合。看起来不太靠谱,却留给我们无限的想象空间。OT 领域的专家们不要再当“九斤老太”,指责这…...
RAGFlow 初步尝试 (01)
1. 起因, 目的: 简单尝试一下。 2. 先看效果 3. 过程: 目的: 研究 RAG 的实现过程。 实用目的: 对于一本电子书, pdf,我在读书的时候,可以问一写些问题。对一个 github 项目,可以迅速理解文件的关系。…...
Linux 服务器用 SSH 拉取多个 Git 工程
在一台 Linux 服务器上用 SSH 拉取两个 Git 工程,而这两个工程对应的是 不同的 Git 账号(SSH Key),做法: 使用 SSH Config 配置多个 Git 账号 场景假设: 工程 A 的仓库地址:gitgithub.com:com…...