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

OpenCV实现目标追踪

目录

准备工作

语言:

软件包:

效果演示

代码解读

(1)导入OpenCV库

(2)使用 cv2.VideoCapture 打开指定路径的视频文件

(3)使用 vid.read() 读取视频的第一帧,ret 表示是否成功读取,fr 包含实际的视频帧

(4)弹出一个窗口,然后我们通过拖动鼠标选择需要跟踪的区域(ROI)。选择的ROI作为一个元组(initial_box)返回,表示对象跟踪的初始边界框

(5)创建一个KCF(Kernelized Correlation Filters)跟踪器,并使用初始边界框在第一帧上初始化

(6)获取视频的原始帧率,然后计算等待时间,确保每秒有 original_fps 帧

(7)开始一个循环,读取视频的每一帧,如果没有更多的帧可读,退出循环

(8)使用跟踪器更新并跟踪对象。如果跟踪成功,获取边界框的坐标,然后在当前帧上绘制一个矩形

(9)在窗口中显示带有跟踪结果的当前帧,然后等待 wait_time 毫秒。

(10)按下 'q' 键,退出循环,退出程序

(11)循环结束后,释放视频捕获对象和关闭所有OpenCV窗口

总体代码

总结


        最近有一直在玩无人机,但是局限于财力买的是很入门的款式,然后我也关注过更高级的无人机,例如大疆的mini4pro,他们有一个功能是选取视频中的框然后就可以实时的跟踪锁定这一个物体,例如跟车或者跟随人物等更加的有利于航拍。

        那么我虽然开发不了一个能集成到无人机飞控系统中的这样的软件,我就在思考能不能做一个小程序可以实时框选目标然后跟踪它。


准备工作

语言:

        在使用的语言之中我采用了Python来进行实现,因为Python的软件包是实在是很多,例如我们这次的程序就需要用到这个东西。

软件包:

        这次的程序和我之前的OpenCV程序比起来要简单很多,只使用了CV2也就是OpenCV这么一个软件包。


效果演示


代码解读

(1)导入OpenCV库

import cv2

(2)使用 cv2.VideoCapture 打开指定路径的视频文件

# 打开视频文件
vid = cv2.VideoCapture("D:\\Dji\\00002\\DJI_0029.MP4")

(3)使用 vid.read() 读取视频的第一帧,ret 表示是否成功读取,fr 包含实际的视频帧

# 读取第一帧
ret, fr = vid.read()

(4)弹出一个窗口,然后我们通过拖动鼠标选择需要跟踪的区域(ROI)。选择的ROI作为一个元组(initial_box)返回,表示对象跟踪的初始边界框

# 选择初始边界框
initial_box = cv2.selectROI("Select ROI", fr, fromCenter=False, showCrosshair=True)

(5)创建一个KCF(Kernelized Correlation Filters)跟踪器,并使用初始边界框在第一帧上初始化

# 初始化跟踪器
tracker = cv2.TrackerKCF_create()
tracker.init(fr, initial_box)

(6)获取视频的原始帧率,然后计算等待时间,确保每秒有 original_fps

# 获取视频的原始帧率
original_fps = vid.get(cv2.CAP_PROP_FPS)
wait_time = int(1000 / original_fps) if original_fps > 0 else 1  # 计算等待时间,确保每秒有 original_fps 帧

(7)开始一个循环,读取视频的每一帧,如果没有更多的帧可读,退出循环

while True:# 读取视频帧ret, fr = vid.read()if not ret:break

(8)使用跟踪器更新并跟踪对象。如果跟踪成功,获取边界框的坐标,然后在当前帧上绘制一个矩形

    # 进行跟踪(success, box) = tracker.update(fr)if success:(x, y, w, h) = [int(v) for v in box]cv2.rectangle(fr, (x, y), (x + w, y + h), (255, 255, 0), 1)

(9)在窗口中显示带有跟踪结果的当前帧,然后等待 wait_time 毫秒。

        为什么这里要等待,因为如果不等待的话视频的播放速度就是根据你的电脑的性能,一般都会导致视频加速。

    # 显示跟踪结果cv2.imshow("Output Frame", fr)key = cv2.waitKey(wait_time) & 0xFF

(10)按下 'q' 键,退出循环,退出程序

    # 按下 'q' 键退出循环if key == ord('q'):break

(11)循环结束后,释放视频捕获对象和关闭所有OpenCV窗口

# 释放资源
vid.release()
cv2.destroyAllWindows()

总体代码

import cv2# 打开视频文件
vid = cv2.VideoCapture("D:\\Dji\\00002\\DJI_0029.MP4")# 读取第一帧
ret, fr = vid.read()# 选择初始边界框
initial_box = cv2.selectROI("Select ROI", fr, fromCenter=False, showCrosshair=True)# 初始化跟踪器
tracker = cv2.TrackerKCF_create()
tracker.init(fr, initial_box)# 获取视频的原始帧率
original_fps = vid.get(cv2.CAP_PROP_FPS)
wait_time = int(1000 / original_fps) if original_fps > 0 else 1  # 计算等待时间,确保每秒有 original_fps 帧while True:# 读取视频帧ret, fr = vid.read()if not ret:break# 进行跟踪(success, box) = tracker.update(fr)if success:(x, y, w, h) = [int(v) for v in box]cv2.rectangle(fr, (x, y), (x + w, y + h), (255, 255, 0), 1)# 显示跟踪结果cv2.imshow("Output Frame", fr)key = cv2.waitKey(wait_time) & 0xFF# 按下 'q' 键退出循环if key == ord('q'):break# 释放资源
vid.release()
cv2.destroyAllWindows()

总结

ヾ( ̄▽ ̄)Bye~Bye~

相关文章:

OpenCV实现目标追踪

目录 准备工作 语言: 软件包: 效果演示 代码解读 (1)导入OpenCV库 (2)使用 cv2.VideoCapture 打开指定路径的视频文件 (3)使用 vid.read() 读取视频的第一帧,ret…...

【剑指offer--C/C++】JZ6 从尾到头打印链表

一、题目 二、本人思路及代码 直接在链表里进行翻转不太方便操作,但是数组就可以通过下标进行操作,于是, 思路1、 先遍历链表,以此存到vector中,然后再从后往前遍历这vector,存入到一个新的vector,就完成…...

算法-买卖股票的最佳时机

1、题目来源 121. 买卖股票的最佳时机 - 力扣(LeetCode) 2、题目描述 给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖…...

【大数据】Flink SQL 语法篇(十):EXPLAIN、USE、LOAD、SET、SQL Hints

《Flink SQL 语法篇》系列,共包含以下 10 篇文章: Flink SQL 语法篇(一):CREATEFlink SQL 语法篇(二):WITH、SELECT & WHERE、SELECT DISTINCTFlink SQL 语法篇(三&…...

Java中List接口常见的实现类

目录 ArrayList实现类 数据存储 构造器 成员方法:CRUD Vector实现类 数据存储 构造器方法 成员方法 LinkedList实现类 数据存储 构造器方法 成员方法CRUD List总结 ArrayList:数组实现,随机访问速度快,增删慢&#x…...

SPI通信

SPI通信: 四根通信线:SCK,MOSI,MISO,SS(从机选择线) 同步时钟,全双工 支持总线挂载多个设备,一主多从 SPI相对IIC传输更快,最简单,最快速 SPI没有接收和应答机制,发送就发…...

【动态规划】【数论】【区间合并】3041. 修改数组后最大化数组中的连续元素数目

作者推荐 视频算法专题 本文涉及知识点 动态规划汇总 数论 区间合并 LeetCode3041. 修改数组后最大化数组中的连续元素数目 给你一个下标从 0 开始只包含 正 整数的数组 nums 。 一开始,你可以将数组中 任意数量 元素增加 至多 1 。 修改后,你可以从…...

字节后端实习 一面凉经

心脏和字节永远都在跳动 深圳还有没有大厂招后端日常实习生啊,求捞~(boss小公司也不理我) 很纠结要不要干脆直接面暑期实习,又怕因为没有后端实习经历,面不到大厂实习。死锁了...

倒计时37天

复习1001. 马走日问题: 1.P1002 [NOIP2002 普及组] 过河卒 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) //日常碎碎念:谁懂啊,dev突然不能用了,也不知道是哪里出了问题下了五六次都不能用,,,找远程安…...

【计算机考研】考408,还是不考408性价比高?

首先综合考虑,如果其他科目并不是很优秀,需要我们花一定的时间去复习,408的性价比就不高,各个科目的时间互相挤压,如果备考时间不充裕,考虑其他专业课也未尝不可。 复习408本来就是费力不讨好的事情 不同…...

测试入门篇

测试: 这里写目录标题 测试:基础概念:BUG:创建一个合理的bug:bug 的级别:跟开发争执如何解决: 测试用例:编写测试用例的万能公式:案例: 登录功能的测试:设计测试用例的方法: 进阶篇(主要介绍测试方法):自动化测试:自动化测试的分类:selenium( web 自动化测试工具 )环境部署:什么…...

b站小土堆pytorch学习记录—— P25-P26 网络模型的使用和修改、保存和读取

文章目录 一、修改1.方法2.代码 二、保存和读取1.方法2.代码(1)保存(2)加载 3.陷阱 一、修改 1.方法 add_module(name: str, module: Module) -> None name 是要添加的子模块的名称。 module 是要添加的子模块。 调用 add_m…...

[数据结构]OJ用队列实现栈

225. 用队列实现栈 - 力扣(LeetCode) 官方题解:https://leetcode.cn/problems/implement-stack-using-queues/solutions/432204/yong-dui-lie-shi-xian-zhan-by-leetcode-solution/ 首先我们要知道 栈是一种后进先出的数据结构&#xff0c…...

「优选算法刷题」:最长回文子串

一、题目 给你一个字符串 s,找到 s 中最长的回文子串。 如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。 示例 1: 输入:s "babad" 输出:"bab" 解释:"aba"…...

Java项目:41 springboot大学生入学审核系统的设计与实现010

作者主页:舒克日记 简介:Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 本大学生入学审核系统管理员和学生。 管理员功能有个人中心,学生管理,学籍信息管理,入学办理管理等。 学生功能有…...

【数据结构与算法】常见排序算法(Sorting Algorithm)

文章目录 相关概念1. 冒泡排序(Bubble Sort)2. 直接插入排序(Insertion Sort)3. 希尔排序(Shell Sort)4. 直接选择排序(Selection Sort)5. 堆排序(Heap Sort)…...

Unity3D学习之XLua实践——背包系统

文章目录 1 前言2 新建工程导入必要资源2.1 AB包设置2.2 C# 脚本2.3 VSCode 的环境搭建 3 面板拼凑3.1 主面板拼凑3.2 背包面板拼凑3.3 格子复合组件拼凑3.4 常用类别名准备3.5 数据准备3.5.1 图集准备3.5.2 json3.5.3 打AB包 4 Lua读取json表及准备玩家数据5 主面板逻辑6 背包…...

前端技术研究越深入,越觉得技术不是决定录用唯一条件。

一、拒绝抬杠 我说技能不是唯一条件,不是说技能不重要,招聘前端条件是1X,其中1是技能,X是其他条件。 如果X条件很优秀,1这个条件可以降格为0.8、0.5,甚至更低。 有人就抬杠,那为啥不招聘清洁工来干前端&…...

vue组件的重新渲染的问题

目录 1.方式1 2.方式2 1.方式1 修改组件上的key属性 Vue是通过diffing算法比较虚拟DOM和真实DOM,来判断新旧 DOM 的变化。key是虚拟DOM对象的标识,在更新显示时key表示着DOM的唯一性。 DOM是否变化的核心是通过判断新旧DOM的key值是否变化&#xff0c…...

opengl 学习(二)-----你好,三角形

你好&#xff0c;三角形 分类demo效果解析 分类 opengl c demo #include "glad/glad.h" #include "glfw3.h" #include <iostream> #include <cmath> #include <vector>using namespace std;/** * 在学习此节之前&#xff0c;建议将这…...

Java 语言特性(面试系列2)

一、SQL 基础 1. 复杂查询 &#xff08;1&#xff09;连接查询&#xff08;JOIN&#xff09; 内连接&#xff08;INNER JOIN&#xff09;&#xff1a;返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径

目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会&#xff0c;其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具&#xff0c;对过去十年 WWDC 主题演讲内容进行了系统化分析&#xff0c;形成了这份…...

day52 ResNet18 CBAM

在深度学习的旅程中&#xff0c;我们不断探索如何提升模型的性能。今天&#xff0c;我将分享我在 ResNet18 模型中插入 CBAM&#xff08;Convolutional Block Attention Module&#xff09;模块&#xff0c;并采用分阶段微调策略的实践过程。通过这个过程&#xff0c;我不仅提升…...

FastAPI 教程:从入门到实践

FastAPI 是一个现代、快速&#xff08;高性能&#xff09;的 Web 框架&#xff0c;用于构建 API&#xff0c;支持 Python 3.6。它基于标准 Python 类型提示&#xff0c;易于学习且功能强大。以下是一个完整的 FastAPI 入门教程&#xff0c;涵盖从环境搭建到创建并运行一个简单的…...

高频面试之3Zookeeper

高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个&#xff1f;3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制&#xff08;过半机制&#xff0…...

《通信之道——从微积分到 5G》读书总结

第1章 绪 论 1.1 这是一本什么样的书 通信技术&#xff0c;说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号&#xff08;调制&#xff09; 把信息从信号中抽取出来&am…...

C# 类和继承(抽象类)

抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

三体问题详解

从物理学角度&#xff0c;三体问题之所以不稳定&#xff0c;是因为三个天体在万有引力作用下相互作用&#xff0c;形成一个非线性耦合系统。我们可以从牛顿经典力学出发&#xff0c;列出具体的运动方程&#xff0c;并说明为何这个系统本质上是混沌的&#xff0c;无法得到一般解…...