OpenCv高阶(十一)——物体跟踪

news2025/4/25 23:32:30

文章目录

  • 前言
  • 一、OpenCV 中的物体跟踪算法
    • 1、均值漂移(Mean Shift):
    • 2、CamShift:
    • 3、KCF(Kernelized Correlation Filters):
    • 4、MIL(Multiple Instance Learning):
  • 二、物体跟踪方法
    • 1、基于特征的跟踪方法
      • (1)光流法:
      • (2)特征点跟踪法:
    • 2、基于模型的跟踪方法
    • 3、基于外观模型的跟踪方法
    • 4、基于深度学习的跟踪方法
    • 5、基于检测的跟踪方法
    • 物体跟踪的一般步骤
  • 三、常见的物体跟踪器介绍
  • 四、调用摄像头物体跟踪
    • 1、分步讲解
      • (1)导库并创建
      • (2)读取摄像头对象或者读取视频
      • (3)循环读取视频的每一帧
      • (4)当按下键盘中的S键时,开始追踪
        • cv2.selectROI() 函数
        • tracker.init(frame, roi)
      • (5)当Tracking为True时条件满足,更新位置,绘制被追踪物体的外接矩形
      • (6)这里表示摄像头显示每一毫秒读取一帧画面,当按下ESC键时跳出循环,停止读取,并释放摄像头资源,摧毁窗口,减少内存的占用。
    • 完整代码
  • 五、应用
    • 视频监控领域
    • 智能交通领域
    • 体育领域
    • 虚拟现实和增强现实领域
    • 医学领域


前言

物体跟踪是在视频序列或图像流中持续监测和定位特定物体的过程。通过分析相邻帧之间物体的特征和位置变化,实现对物体运动的跟踪。

一、OpenCV 中的物体跟踪算法

1、均值漂移(Mean Shift):

基于概率分布的跟踪算法。它通过计算目标区域的颜色直方图,在后续帧中搜索与该直方图最匹配的区域,从而实现目标跟踪。该算法计算速度快,但对目标的尺度变化和旋转不鲁棒。

2、CamShift:

是均值漂移算法的扩展。它不仅能跟踪目标的位置,还能根据目标的大小和形状自适应地调整搜索窗口的大小和方向,对目标的尺度变化有一定的适应性。

3、KCF(Kernelized Correlation Filters):

基于相关滤波的跟踪算法。它利用核函数将目标特征映射到高维空间,通过学习目标的外观模型,在后续帧中快速定位目标。KCF 算法具有较高的跟踪精度和速度,对光照变化和部分遮挡有较好的鲁棒性。

4、MIL(Multiple Instance Learning):

采用多示例学习的方法来训练目标模型。它将目标区域划分为多个子区域,通过学习这些子区域的特征来跟踪目标。MIL 算法对遮挡和背景干扰具有较好的鲁棒性,但计算复杂度较高,跟踪速度相对较慢。

二、物体跟踪方法

1、基于特征的跟踪方法

(1)光流法:

光流是指图像中物体表面上的点在图像平面上的运动速度。通过计算相邻帧之间像素点的光流场,可以得到物体的运动信息,进而实现物体跟踪。该方法对物体的运动较为敏感,但对光照变化和噪声的鲁棒性相对较差。

(2)特征点跟踪法:

首先在图像中提取一些具有独特性和稳定性的特征点,如 SIFT、SURF、ORB 等特征点。然后在后续帧中通过匹配这些特征点来跟踪物体的运动。这种方法对物体的旋转、尺度变化和光照变化有一定的适应性,但当特征点被遮挡或丢失时,可能会影响跟踪效果。

2、基于模型的跟踪方法

模板匹配法:在第一帧中手动或自动选择一个目标模板,然后在后续帧中通过搜索与模板最相似的区域来定位目标。常用的相似性度量方法有归一化互相关(NCC)等。该方法简单直观,但对目标的尺度变化、旋转和光照变化的适应性较差,且计算量较大。

3、基于外观模型的跟踪方法

通过学习目标物体的外观模型来进行跟踪。例如,使用主成分分析(PCA)等方法对目标的图像特征进行降维,建立目标的外观模型。在跟踪过程中,根据当前帧的图像特征与外观模型的匹配程度来确定目标的位置。这种方法对目标的外观变化有一定的适应性,但需要大量的训练数据来建立准确的外观模型。

4、基于深度学习的跟踪方法

孪生网络:孪生网络是一种基于深度学习的物体跟踪方法,它通过孪生结构的神经网络学习目标与搜索区域之间的相似性度量。在训练过程中,孪生网络通过大量的图像对来学习如何区分目标物体和背景,从而能够在新的视频序列中快速准确地定位目标。孪生网络具有较高的跟踪精度和速度,对各种复杂场景和目标变化具有较好的鲁棒性。

5、基于检测的跟踪方法

利用深度学习目标检测算法,如 Faster R-CNN、YOLO 等,在每一帧中对目标进行检测,然后通过数据关联算法将不同帧中的检测结果进行关联,实现物体跟踪。这种方法能够利用深度学习强大的特征提取能力,对目标的检测和跟踪效果较好,但计算量较大,实时性相对较差。

物体跟踪的一般步骤

目标初始化:在第一帧图像中指定要跟踪的目标物体,可以通过手动选择目标区域或使用目标检测算法来确定目标的初始位置和大小。
特征提取:根据选择的跟踪算法,提取目标物体的特征,如颜色、纹理、形状等。这些特征将用于在后续帧中识别和定位目标。
跟踪过程:在后续的视频帧中,根据上一帧的跟踪结果,利用选定的跟踪算法在当前帧中搜索目标物体的新位置。算法会根据目标的特征和运动模型,预测目标可能出现的位置,并在该区域内进行匹配和定位。
结果更新:将当前帧中目标的位置和状态信息更新到跟踪器中,以便为下一帧的跟踪提供初始条件。同时,根据需要可以对目标的特征模型进行在线学习和更新,以适应目标外观的变化。

三、常见的物体跟踪器介绍

1、BOOSTING 跟踪器
原理:基于 AdaBoost 算法,通过迭代训练多个弱分类器并组合成强分类器。在跟踪过程中,不断利用样本更新分类器,以区分目标和背景。
特点:
精度较低,在目标外观变化、光照变化或存在遮挡时,容易丢失目标。
计算速度较慢,实时性较差。
对目标外观变化的适应性较弱。
适用场景:适用于目标外观相对稳定、光照变化小且对精度要求不高的简单场景。

import cv2

boosting_tracker = cv2.legacy.TrackerBoosting_create()

2、MIL(Multiple Instance Learning)跟踪器
原理:采用多示例学习方法,将目标区域划分为多个子区域(示例),通过学习这些子区域的特征来训练目标模型。在跟踪时,根据模型匹配目标位置。
特点:
对部分遮挡有一定的鲁棒性,能够在目标被部分遮挡时继续跟踪。
跟踪精度一般,当目标快速运动或外观变化剧烈时,跟踪效果不佳。
计算复杂度较高,速度较慢。
适用场景:适用于目标可能会被部分遮挡,但运动速度相对较慢、外观变化不太剧烈的场景。

import cv2

mil_tracker = cv2.legacy.TrackerMIL_create()

3、 KCF(Kernelized Correlation Filters)跟踪器
原理:基于相关滤波的方法,通过核函数将目标特征映射到高维空间,学习目标的外观模型,在后续帧中利用相关滤波快速定位目标。
特点:
跟踪速度快,具有较好的实时性。
对目标的尺度变化和部分遮挡有一定的适应性。
精度相对较高,但在目标外观发生较大变化时,跟踪效果会受到影响。

适用场景:适用于对实时性要求较高,目标外观变化不大、运动速度适中的场景。

import cv2

kcf_tracker = cv2.TrackerKCF_create()

4、CSRT(Discriminative Correlation Filter with Channel and Spatial Reliability)跟踪器
原理:同样基于相关滤波,通过引入通道和空间可靠性信息,提高目标跟踪的精度和鲁棒性。
特点:
跟踪精度高,在目标外观变化、尺度变化和遮挡等情况下,都能保持较好的跟踪效果。
计算速度相对较慢,实时性不如 KCF 跟踪器。
适用场景:适用于对跟踪精度要求较高,目标外观和尺度可能会发生变化,且存在一定遮挡的复杂场景。

import cv2

csrt_tracker = cv2.legacy.TrackerCSRT_create()

5、MEDIANFLOW 跟踪器
原理:基于光流法,通过计算目标区域内像素点的光流,预测目标在后续帧中的位置。使用中值流的方法来提高跟踪的稳定性。
特点:
跟踪速度快,能够实时处理视频流。
对目标的运动速度和方向变化较为敏感,在目标运动平稳时,跟踪效果较好。
对遮挡和外观变化的鲁棒性较差,容易丢失目标。
适用场景:适用于目标运动平稳、无明显遮挡和外观变化的场景,如监控视频中的静态场景跟踪。

import cv2

medianflow_tracker = cv2.legacy.TrackerMedianFlow_create()

6、TLD(Tracking - Learning - Detection)跟踪器
原理:结合了跟踪(Tracking)、学习(Learning)和检测(Detection)三个模块。跟踪模块负责在当前帧中预测目标的位置;学习模块不断更新目标的外观模型;检测模块用于在整个图像中搜索目标,以应对目标丢失或遮挡的情况。
特点:
对目标的长期跟踪效果较好,能够在目标长时间消失后重新检测到目标。
容易产生漂移问题,即跟踪结果逐渐偏离真实目标。
计算量较大,实时性较差。
适用场景:适用于需要对目标进行长时间跟踪,且目标可能会暂时消失或被遮挡的场景。

import cv2

tld_tracker = cv2.legacy.TrackerTLD_create()

四、调用摄像头物体跟踪

1、分步讲解

(1)导库并创建

import cv2

tracker=cv2.TrackerCSRT_create()	#创建CRST跟踪器
tracking=False	#tracking 一般用来表示是否处于跟踪状态。False 意味着当前并未开始跟踪目标。

(2)读取摄像头对象或者读取视频

cap=cv2.VideoCapture(0)	

写零表示调用电脑自身的摄像头,里面还可以传视频文件(传入参数为视频的保存路径)

(3)循环读取视频的每一帧

while True:
    ret,frame=cap.read()	
    #使用read读取,视频或摄像头中的每一帧,ret表示视频是否读取成功,frame是指每一帧图像画面。

    if not ret:		#表示视频读取失败,则跳出循环
        break

(4)当按下键盘中的S键时,开始追踪

if cv2.waitKey(1)==ord('s'):
        tracking=True

        roi=cv2.selectROI('Tracking',frame,showCrosshair=False)

        tracker.init(frame,roi)

cv2.selectROI() 函数

其作用是让用户手动选取视频帧里的一个感兴趣区域(Region of Interest,简称 ROI)。
1、 ‘Tracking’:这是弹出的选择窗口的标题,当运行代码时,会出现一个名为 Tracking 的窗口,用户可以在这个窗口里进行 ROI 的选择操作。
2、frame:这是当前要处理的视频帧,也就是用户选择 ROI 所基于的图像。
3、showCrosshair=False:这个参数控制在选择 ROI 时是否显示十字线。设置为 False 表示不显示十字线;若设置为 True,在选择 ROI 的过程中会显示十字线,方便用户更精准地定位 ROI 的中心位置。
4、cv2.selectROI() 函数在用户完成 ROI 选择后,会返回一个包含 ROI 位置和大小信息的元组 (x, y, w, h),其中:
x 和 y 是 ROI 左上角的坐标。
w 和 h 分别是 ROI 的宽度和高度。

tracker.init(frame, roi)

调用了跟踪器对象 tracker 的 init() 方法,其作用是使用用户选择的 ROI 来初始化跟踪器。
1、frame:这是当前的视频帧,也就是用户选择 ROI 所在的那一帧图像。跟踪器会以这一帧为基准,对后续视频帧里的目标进行跟踪。
2、roi:这是前面通过 cv2.selectROI() 函数得到的 ROI 信息,跟踪器会根据这个 ROI 来确定要跟踪的目标。

(5)当Tracking为True时条件满足,更新位置,绘制被追踪物体的外接矩形

if tracking:
        success,box=tracker.update(frame)

        if success:
            x,y,w,h=[int(v) for v in box]

            cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,0),2)
    cv2.imshow('Tracking',frame)
    

success, box = tracker.update(frame)
调用了跟踪器对象 tracker 的 update() 方法,用于在当前视频帧 frame 中更新目标的位置。

返回值:
1、success:一个布尔值,用于表示目标跟踪是否成功。如果成功跟踪到目标,success 为 True;否则为 False。
2、 box:一个包含目标位置和大小信息的元组,通常格式为 (x, y, w, h),其中 x 和 y 是目标矩形框左上角的坐标,w 和 h 分别是矩形框的宽度和高度。

(6)这里表示摄像头显示每一毫秒读取一帧画面,当按下ESC键时跳出循环,停止读取,并释放摄像头资源,摧毁窗口,减少内存的占用。

if cv2.waitKey(1)==27:
        break
cap.release()
cv2.destroyAllWindows()

完整代码

import cv2

tracker=cv2.TrackerCSRT_create()
tracking=False

cap=cv2.VideoCapture(0)		#写零表示调用电脑自身的摄像头,里面还可以传视频文件(传入参数为视频的保存路径)
while True:
    ret,frame=cap.read()

    if not ret:
        break

    if cv2.waitKey(1)==ord('s'):
        tracking=True

        roi=cv2.selectROI('Tracking',frame,showCrosshair=False)

        tracker.init(frame,roi)

    if tracking:
        success,box=tracker.update(frame)

        if success:
            x,y,w,h=[int(v) for v in box]

            cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,0),2)
    cv2.imshow('Tracking',frame)
    if cv2.waitKey(1)==27:
        break
cap.release()
cv2.destroyAllWindows()

五、应用

物体跟踪在多个领域都有广泛的应用

视频监控领域

行为分析:通过对监控视频中人物或物体的跟踪,分析其行为模式,如是否有异常徘徊、奔跑等行为,可用于公共场所的安全监控,及时发现潜在的安全威胁。
事件检测:检测特定事件的发生,如检测商场中的顾客摔倒、打架等行为,以便及时采取相应措施。

智能交通领域

车辆跟踪与流量监测:在交通路口或高速公路上,对车辆进行跟踪,获取车辆的行驶速度、轨迹等信息,从而实现交通流量的统计和分析,为交通管理部门提供决策依据,优化交通信号灯时长和道路规划。
辅助自动驾驶:在自动驾驶车辆中,物体跟踪技术可以实时跟踪周围的车辆、行人、交通标志等物体,为车辆的决策和控制提供重要信息,帮助车辆避免碰撞、规划行驶路径等。

体育领域

运动员表现分析:在体育比赛中,通过跟踪运动员的运动轨迹和动作,可以对运动员的表现进行分析,帮助教练和运动员了解技术动作的优缺点,制定训练计划,提高运动成绩。
比赛转播:在体育赛事转播中,物体跟踪技术可以实时跟踪运动员和球的位置,为观众提供更丰富的比赛信息,如球员的跑动距离、速度、传球路线等,增强比赛的观赏性和专业性。

虚拟现实和增强现实领域

交互体验:在虚拟现实和增强现实应用中,通过跟踪用户的头部、手部等身体部位的运动,实现与虚拟环境的自然交互。例如,用户可以通过头部转动来观察虚拟场景,通过手部动作来操作虚拟物体。
场景重建:物体跟踪技术可以帮助重建真实场景的三维模型,将虚拟元素与真实场景更好地融合,提高增强现实应用的沉浸感。

医学领域

手术导航:在手术过程中,通过跟踪手术器械和患者体内的器官、组织等,为医生提供实时的位置信息,辅助医生进行精确的手术操作,提高手术的安全性和准确性。
康复治疗:在康复治疗中,跟踪患者的肢体运动,评估康复训练的效果,为康复治疗方案的调整提供依据。

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

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

相关文章

2194出差-节点开销Bellman-ford/图论

题目网址: 蓝桥账户中心 我先用Floyd跑了一遍,不出所料TLE了 n,mmap(int,input().split())clist(map(int,input().split()))INFfloat(inf) ma[[INF]*n for i in range(n)]for i in range(m):u,v,wmap(int,input().split())ma[u-1][v-1]wma[v-1][u-1]w#“…

Docker安装beef-xss

新版的kali系统中安装了beef-xss会因为环境问题而无法启动,可以使用Docker来安装beef-xss,节省很多时间。 安装步骤 1.启动kali虚拟机,打开终端,切换到root用户,然后执行下面的命令下载beef的docker镜像 wget https:…

时间序列-数据窗口进行多步预测

在时间序列预测领域,多步预测旨在基于历史数据预测未来多个时间点的值,而创建数据窗口是实现这一目标的常用且高效的技术手段。数据窗口技术的核心是通过滑动窗口机制构建训练数据集,其核心逻辑可概括为:利用历史时间步的序列模式…

(三)mac中Grafana监控Linux上的Redis(Redis_exporter安装使用)

框架:GrafanaPrometheusRedis_exporter Grafana安装-CSDN博客 普罗米修斯Prometheus监控安装(mac)-CSDN博客 1.Redis_exporter安装 直接下载 wget https://github.com/oliver006/redis_exporter/releases/download/v1.0.3/redis_expor…

Linux Sed 深度解析:从日志清洗到 K8s 等12个高频场景

看图猜诗,你有任何想法都可以在评论区留言哦~ 摘要:Sed(Stream Editor)作为 Linux 三剑客之一,凭借其流式处理与正则表达式能力,成为运维场景中文本批处理的核心工具。本文聚焦生产环境高频需求&#xff…

基于java的网络编程入门

1. 什么是IP地址 由此可见,32位最大为255.255.255.255 打开cmd查询自己电脑的ip地址:ipconfig 测试网络是否通畅:ping 目标ip地址 2. IP地址的组成 注意:127.0.0.1是回送地址,指本地机,一般用来测试使用 …

Git简介与入门

Git的发明 Git由著名的Linux创始人linus于2005年发明(所以git的界面、使用方式与Linux挺像的,即命令行方式) 经过发展,现在广泛应用于代码管理与团队协作。 Git特性 Git是分布式版本控制系统 分布式 每个开发者拥有完整仓库&…

Linux 网络基础三 (数据链路层协议:以太网协议、ARP 协议)

一、以太网 两个不同局域网的主机传递数据并不是直接传递的,而是通过路由器 “一跳一跳” 的传递过去。 跨网络传输的本质:由无数个局域网(子网)转发的结果。 所以,要理解数据跨网络转发原理就要先理解一个局域网中数…

16.QT-Qt窗口-菜单栏|创建菜单栏|添加菜单|创建菜单项|添加分割线|添加快捷键|子菜单|图标|内存泄漏(C++)

Qt窗⼝是通过QMainWindow类来实现的。 QMainWindow是⼀个为⽤⼾提供主窗⼝程序的类,继承⾃QWidget类,并且提供了⼀个预定义的布局。QMainWindow包含⼀个菜单栏(menu bar)、多个⼯具栏(tool bars)、多个浮动窗⼝(铆接部…

[特殊字符] 分布式定时任务调度实战:XXL-JOB工作原理与路由策略详解

在微服务架构中,定时任务往往面临多实例重复执行、任务冲突等挑战。为了解决这一问题,企业级调度框架 XXL-JOB 提供了强大的任务统一调度与执行机制,特别适合在分布式系统中使用。 本文将从 XXL-JOB 的核心架构入手,详细讲解其调…

java面试题及答案2020,java最新面试题(四十四)

java面试题及答案2020 二面-2020/3/18 1、自我介绍项目比赛 2、java集合框架全部介绍。。从list set queue到map 3、hashmap底层扩容线程安全问题 4、如果-一个对象要作为hashmap的key需要做什么 5、Threadlocal类以及 内存泄漏 6、线程同步方式,具体每一个怎么做的 7、jvm类加…

oracle 锁的添加方式和死锁的解决

DML锁添加方式 DML 锁可由一个用户进程以显式的方式加锁,也可通过某些 SQL 语句隐含方式实现。 DML 锁有三种加锁方式:共享锁方式、独占锁方式、共享更新。 共享锁,独占锁用于 TM 锁,共享锁用于 TX 锁。 1)共享方式的表级锁 共享方…

基于Hadoop的音乐推荐系统(源码+lw+部署文档+讲解),源码可白嫖!

摘要 本毕业生数据分析与可视化系统采用B/S架构,数据库是MySQL,网站的搭建与开发采用了先进的Java语言、爬虫技术进行编写,使用了Spring Boot框架。该系统从两个对象:由管理员和用户来对系统进行设计构建。主要功能包括&#xff…

Java查询数据库表信息导出Word

参考: POI生成Word多级标题格式_poi设置word标题-CSDN博客 1.概述 使用jdbc查询数据库把表信息导出为word文档, 导出为word时需要下载word模板文件。 已实现数据库: KingbaseES, 实现代码: 点击跳转 2.效果图 2.1.生成word内容 所有数据库合并 数据库不合并 2.2.生成文件…

RK3588平台用v4l工具调试USB摄像头实践(亮度,饱和度,对比度,色相等)

目录 前言:v4l-utils简介 一:查找当前的摄像头设备 二:查看当前摄像头支持的v4l2-ctl调试参数 三根据提示设置对应参数,在提示范围内设置 四:常用调试命令 五:应用内执行命令方法 前言:v4l-utils简介 v4l-utils工具是由Linu…

在Linux中,使用read函数去读取写入文件空洞部分时,读取出来的内容是什么?为什么这样操作,以及应用场景?

使用 read 函数读取文件空洞(hole)部分时,读取到的内容会被系统填充为 \0(即零字节)。文件空洞是稀疏文件中未实际分配磁盘空间的区域,但逻辑上表现为连续的零字节。 1.在指定空洞部分后,写入数…

Qt6笔记-对Qt6中对CMakeLists.txt的解析

首先,新建Qt Console Application项目。 下面对CMakeLists.txt进行次理解。新建好后,Qt Creator会生成CMakeLists.txt,具体内容如下: cmake_minimum_required(VERSION 3.16)project(EasyCppMain LANGUAGES CXX)set(CMAKE_AUTOUIC…

CIFAR10图像分类学习笔记(三)---数据加载load_cifar10

新创建一个load_cifar10源文件 需要导入的包 import glob from torchvision import transforms from torch.utils.data import DataLoader ,Dataset import os #读取工具 from PIL import Image import numpy as np 01同样定义10个类别的标签名数组 label_name ["airpl…

计算机视觉cv入门之答题卡自动批阅

前边我们已经讲解了使用cv2进行图像预处理与边缘检测等方面的知识,这里我们以答题卡自动批阅这一案例来实操一下。 大致思路 答题卡自动批阅的大致流程可以分为这五步:图像预处理-寻找考试信息区域与涂卡区域-考生信息区域OCR识别-涂卡区域填涂答案判断…

Java学习手册:JSON 数据格式基础知识

1. JSON 简介 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于阅读和编写,也易于机器解析和生成。它最初来源于 JavaScript,但如今已被许多语言所采用,包括 Java、Python、C 等。JSON 以…