首页 > 编程语言 >opencv-python目标跟踪

opencv-python目标跟踪

时间:2023-08-14 23:12:32浏览次数:48  
标签:old python frame cv2 目标 opencv 算法 跟踪

目标追踪(object tracking)是指先给定视频的第一帧中的目标以及它的位置,之后不断的追踪目标,预测目标的轨迹。

1 目标跟踪的困难点

  • 形态变化 :姿态变化是目标跟踪中常见的干扰问题。运动目标发生姿态变化时,会导致它的特征以及外观模型发生改变,容易导致跟踪失败。比如体育比赛中的运动员、马路上的行人。
  • 尺度变化 :尺度的自适应也是目标跟踪中的关键问题。当目标尺度缩小时,由于跟踪框不能自适应跟踪,会将很多背景信息包含在内,导致目标模型的更新错误;当目标尺度增大时,由于跟踪框不能将目标完全包括在内,跟踪框内目标信息不全,也会导致目标模型的更新错误。因此, 实现尺度自适应跟踪是十分必要的。
  • 遮挡与消失 :目标在运动过程中可能出现被遮挡或者短暂的消失情况。当这种情况发生时,跟踪框容易将遮挡物以及背景信息包含在跟踪框内,会导致后续帧中的跟踪目标漂移到遮挡物上面。若目标被完全遮挡时,由于找不到目标的对应模型,会导致跟踪失败。
  • 图像模糊 :光照强度变化, 目标快速运动,低分辨率等情况会导致图像模型,尤其是在运动目标与背景相似的情况下更为明显。因此,选择有效的特征对目标和背景进行区分非常必要。

2 目标跟踪方法

按照时间顺序,目标跟踪的方法经历了从经典算法到基于核相关滤波算法,再到基于深度学习的跟踪算法的过程。

1)经典算法

经典跟踪算法主要有:光流法(利用视频序列在相邻帧之间的像素关系,寻找像素的位移变化来判断目标的运动状态)、Meanshfit(基于概率密度分布的跟踪方法,适用于目标的色彩模型和背景差异比较大的情形)、粒子滤波(基于粒子分布统计的方法,不对目标的特征建模,而是对目标的运动模型进行了建模,常用于估计目标在下一帧的位置)

早期的目标跟踪算法主要是根据目标建模或者对目标特征进行跟踪。

基于目标模型建模的方法是通过对目标外观模型进行建模,然后在之后的帧中找到目标。例如,区域匹配、特征点跟踪、基于主动轮廓的跟踪算法、光流法等。最常用的是特征匹配法,首先提取目标特征,然后在后续的帧中找到最相似的特征进行目标定位,常用的特征有:SIFT特征、SURF特征、Harris角点等。

经典算法的缺点比较明显:没有将背景信息考虑在内,导致在目标遮挡,光照变化以及运动模糊等干扰下容易出现跟踪失败;以及跟踪算法执行速度慢。

2)基于核相关滤波的跟踪算法

后来,人们将通信领域的相关滤波(衡量两个信号的相似程度)引入到了目标跟踪中。一些基于相关滤波的跟踪算法(比如MOSSE、KCF、BACF、SAMF等)也随之产生,速度可以达到数百帧每秒,可以广泛地应用于实时跟踪系统中。

3)基于深度学习的跟踪算法

随着深度学习方法的广泛应用,人们开始考虑将其应用到目标跟踪中。人们开始使用深度特征并取得了很好的效果,然后开始考虑用深度学习建立全新的跟踪框架,进行目标跟踪。

基于深度学习的目标跟踪大致可分为两类,一类是采用卷积神经网络提取目标特征,然后与其他跟踪方式进行融合来实现目标跟踪。另一类是训练出端到端的神经网络模型,目标跟踪的所有步骤均由神经网络来实现。

3 opencv 目标跟踪算法

1 )光流估计

光流:光的流动,比如人眼感受到的夜空中划过的流行。在计算机视觉中,定义图像中对象的移动,这个移动可以是相机移动或者物体移动引起的。具体是指视频图像的一帧中的代表同一对象(物体)像素点移动到下一帧的移动量,使用二维向量表示。

根据是否选取图像稀疏点进行光流估计,可以将光流估计分为稀疏光流和稠密光流。

opencv中提供了光流估计的接口,包括稀疏光流估计算法cv2.calcOpticalFlowPyrLK(), 和稠密光流估计算法cv2.calcOpticalFlowFarneback()。其中稀疏光流估计算法为Lucas-Kanade算法,该算法比较经典也比较容易理解。

为了将光流估计进行建模,Lucas-Kanade做了三个重要假设:

1 亮度恒定:同一点随着时间的变化,其亮度不会发生改变。

2 小运动:随着时间的变化不会引起位置的剧烈变化,只有小运动情况下才能用前后帧之间单位位置变化引起的灰度变化去近似灰度对位置的偏导数。

3 空间一致:一个场景上邻近的点投影到图像上也是邻近点,且邻近点速度一致。因为光流法基本方程约束只有一个,而要求x,y方向的速度,有两个未知量,所以需要联立n多个方程求解。

 opencv中提供的稀疏光流估计算法 cv2.calcOpticalFlowPyrLK()

参数说明:

prevImage:前一帧图像

nextImage:当前帧图像

prevPts:待跟踪的特征点向量(特征点可以用特征检测方法计算:Harris角点检测,SIFT关键点检测,shi-Tomasi角点检测等)

winSize:搜索窗口的大小

maxLevel:最大的金字塔层数

返回:

nextPts:输出跟踪特征点向量

status:特征点是否找到,找到的状态为1,未找到为0

光流估计法的重点是找到待跟踪的特征向量,以下用shi-Tomasi角点检测来找第一帧的特征点向量,示例视频为vtest.avi。

import cv2
import numpy as np

#读取视频
cap = cv2.VideoCapture('vtest.avi')

#读取第一帧图片,提取其特征点向量
ret,old_frame = cap.read()
old_gray = cv2.cvtColor(old_frame,cv2.COLOR_BGR2GRAY)

#角点(特征点)检测 (shi-Tomasi角点检测)
old_pts = cv2.goodFeaturesToTrack(old_gray,maxCorners=100,qualityLevel=0.3,minDistance=10)
# print(old_pts)

#创建一个mask
mask = np.zeros_like(old_frame)
#随机颜色
color = np.random.randint(0,255,size=(100,3))
print(color[1].tolist())

while True:
    ret,frame = cap.read()
    if frame is None:
        break
        
    gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)

    #光流估计
    next_pts,status,err = cv2.calcOpticalFlowPyrLK(old_gray,gray,old_pts,None,winSize = (15,15),maxLevel=4)
#     print(len(next_pts))

    #哪些特征点找到了,哪些特征点没有找到
    good_new = next_pts[status == 1]
    good_old = old_pts[status == 1]
    print(good_new)
    
    #绘制特征点的轨迹
    for i,(new,old) in enumerate(zip(good_new,good_old)):
        x1,y1 = new
        x0,y0 = old
        mask = cv2.line(mask,(x1,y1),(x0,y0),color[i].tolist(),2)
        frame = cv2.circle(frame,(x1,y1),5,color[i].tolist(),-1)
    
    img = cv2.add(mask,frame)  #把轨迹和当前帧图片融合
    
    cv2.imshow('mask',mask)
    cv2.imshow('video',img)
    key =cv2.waitKey(100)
    if key == ord('q'):
        break
        
    #更新
    old_gray = gray.copy()
    old_pts = good_new.reshape(-1,1,2)   #要把 good_new 的维度变回old_pts一样
    
cap.release()
cv2.destroyAllWindows()

 可以看出,这种算法的缺陷主要有两个:一是跟踪的目标被遮挡后,跟踪会丢失;二是如果不是第一帧出现的人物,不会被标记跟踪。

当然,除了使用shi-Tomasi角点检测来找到待跟踪的特征向量,还可以用SIFT特征、SURF特征等,但是要注意这些算法返回的不一定是需要的特征向量,而是keypoint对象。

使用SIFT关键点检测来找到待跟踪的特征向量如下:

import cv2
import numpy as np

#读取视频
cap = cv2.VideoCapture('cars.mp4')

#读取第一帧图片,提取其特征点向量
ret,old_frame = cap.read()
old_gray = cv2.cvtColor(old_frame,cv2.COLOR_BGR2GRAY)

#创建sift对象  (SIFT关键点检测)
sift = cv2.xfeatures2d.SIFT_create(nfeatures=100)  #只需要100个关键点,不指定nfeatures的话关键点太多
#进行检测
kpoint = sift.detect(old_gray)
old_pts = cv2.KeyPoint_convert(kpoint)  #把关键点转换为坐标
old_pts = old_pts.reshape(-1,1,2)  #维度变换

#创建一个mask
mask = np.zeros_like(old_frame)
#随机颜色
color = np.random.randint(0,255,size=(100,3))
print(color[1].tolist())

while True:
    ret,frame = cap.read()
    if frame is None:
        break
        
    gray = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)

    #光流估计
    next_pts,status,err = cv2.calcOpticalFlowPyrLK(old_gray,gray,old_pts,None,winSize = (15,15),maxLevel=4)
#     print(len(next_pts))

    #哪些特征点找到了,哪些特征点没有找到
    good_new = next_pts[status == 1]
    good_old = old_pts[status == 1]
#     print(good_new)
    
    #绘制特征点的轨迹
    for i,(new,old) in enumerate(zip(good_new,good_old)):
        x1,y1 = new
        x0,y0 = old
        mask = cv2.line(mask,(x1,y1),(x0,y0),color[i].tolist(),2)
        frame = cv2.circle(frame,(x1,y1),5,color[i].tolist(),-1)
    
    img = cv2.add(mask,frame)  
    
    cv2.imshow('mask',mask)
    cv2.imshow('video',img)
    key =cv2.waitKey(100)
    if key == ord('q'):
        break
        
    #更新
    old_gray = gray.copy()
    old_pts = good_new.reshape(-1,1,2)  #要把 good_new 的维度变回old_pts一样
    
cap.release()
cv2.destroyAllWindows()

 

 2)opencv的常用目标追踪算法

opencv上面有8种不同的目标追踪算法:

BOOSTING Tracker:和Harr cascades(AdaBoost)背后所用的机器学习算法相同,比较老的算法,追踪速度慢,表现不好。

MIL Tracker:比上一个追踪更精确,但是失败率高。

KCF Tracker:比上面两个都快,但是在有遮挡的时候表现不佳。

CSRT Tracker:比KCF更精确,但是速度慢一些。

MedianFlow Tracker:出色的跟踪故障报告。运动是可预测且没有遮挡的时候,表现很好。但是对于快速跳动或快速移动的物体,模型会失效。

TLD Tracker:在多帧遮挡下效果最好,但是TLD误报非常多。

MOSSE Tracker:速度非常快,但是不如CSRT和KCF那么精确,准确率稍低。

GOTURN Tracker:opencv中唯一一个以深度学习为基础的目标检测器,需要额外的模型才能运行。

opencv目标跟踪算法使用步骤:

  1. 创建MultiTracker对象。
  2. 读取视频或摄像头数据。
  3. 框选ROI区域。
  4. 给MultiTracker对象添加实际的追踪算法。
  5. 对每一帧进行目标追踪。

前面7种目标追踪算法实例如下:

import cv2
import numpy as np

#定义opencv中的七种目标追踪算法
OPENCV_OBJECT_TRACKERS = {
    'boosting':cv2.TrackerBoosting_create,
    'csrt':cv2.TrackerCSRT_create,
    'kcf':cv2.TrackerKCF_create,
    'mil':cv2.TrackerMIL_create,
    'tld':cv2.TrackerTLD_create,
    'medianflow':cv2.TrackerMedianFlow_create,
    'mosse':cv2.TrackerMedianFlow_create
}

trackers = cv2.MultiTracker_create()  #创建MultiTracker对象

cap = cv2.VideoCapture('D:/videos/los_angeles.mp4')

while True:
    ret,frame = cap.read()
    
    if frame is None:
        break
    #绘制追踪到的矩形区域(要在imshow之前)
    success,boxes = trackers.update(frame)
    
    for box in boxes:  #显示追踪框
        (x,y,w,h) = [int(v) for v in box] #box是浮点型,画图需要整型
        cv2.rectangle(frame,(x,y),(x+w,y+h),[0,0,255],2)
    
    cv2.imshow('viedo',frame)
    
    key = cv2.waitKey(100)
    
    if key == ord('s'):  #按s选择需要追踪的目标
        roi = cv2.selectROI('viedo',frame,showCrosshair = False)
        #创建一个实际的目标追踪器
        tracker = OPENCV_OBJECT_TRACKERS['tld']()
        trackers.add(tracker,frame,roi)
        
    if key == 27:
        break

cap.release()
cv2.destroyAllWindows()

  

 

按s键选择待追踪目标,然后按任意键进行目标追踪,可以尝试上面的7种目标跟踪算法,根据具体情况选择合适的算法。

 

标签:old,python,frame,cv2,目标,opencv,算法,跟踪
From: https://www.cnblogs.com/libai123456/p/17630025.html

相关文章

  • java opencv创建 空图片
    javaopencv创建空图片  packageml;importorg.opencv.core.Core;importorg.opencv.core.CvType;importorg.opencv.core.Mat;importorg.opencv.core.Scalar;importorg.opencv.highgui.HighGui;publicclassTest2{publicstaticvoidmain(String[......
  • VS Code调试Python相关的问题
    VSCode启动Debug模式调试带参数的python文件:https://blog.csdn.net/weixin_39329055/article/details/119530587单步调试进入外部文件:launch.json中写入以下:{//使用IntelliSense了解相关属性。//悬停以查看现有属性的描述。//欲了解更多信息,请访问:......
  • linux安装python
    转载请注明出处:1.查看当前系统上已安装的Python版本:在终端中运行以下命令:python--version或者使用以下命令查看全部已安装的Python版本:ls/usr/bin/python* 2.下载并安装python包访问Python官方网站https://www.python.org/downloads/source/,找到并......
  • 如何使用Python调用常用的Linux命令
    本文将介绍如何使用Python调用Linux命令,包括常用命令的使用方法和示例代码。1.使用subprocess模块调用Linux命令Python内置了一个名为subprocess的模块,可以用于在Python程序中执行外部命令。subprocess模块提供了许多函数和方法,可以方便地启动新进程、连接到它们的输入/输出/错误......
  • 如何将Python代码转换为Goland
    本文将介绍如何将Python代码转换为Goland,包括转换工具、转换步骤和注意事项。1.转换工具目前市面上有很多Python到Go的转换工具,例如:Transcrypt:一个命令行工具,可以将Python代码转换为Go代码。PyGo:一个Python库,可以在Python代码中嵌入Go代码,从而实现Python到Go的转换。GoPy:一个Pytho......
  • 免费敏捷工具做敏捷缺陷跟踪管理-leangoo
    ​缺陷管理通常关注如下几个方面:1.缺陷的处理速度2.缺陷处理的状态3.缺陷的分布4.缺陷产生的原因使用Leangoo敏捷看板我们可以对缺陷进行可视化的管理,方便我们对缺陷的处理进展、负责人、当前状态、分布情况等各个方面一目了然。我们可以通过Leangoo领歌敏捷工具来管理......
  • 关于Python的学习记录(二十二_读写 CSV 文件)
    CSV文件介绍CSV(CommaSeparatedValues)全称逗号分隔值文件是一种简单、通用的文件格式,被广泛的应用于应用程序(数据库、电子表格等)数据的导入和导出以及异构系统之间的数据交换。因为CSV是纯文本文件,不管是什么操作系统和编程语言都是可以处理纯文本的,而且很多编程语言中都提供了......
  • Python分享之requests(1)
    1、模块说明requests是使用Apache2licensed许可证的HTTP库。用python编写。比urllib2模块更简洁。Request支持HTTP连接保持和连接池,支持使用cookie保持会话,支持文件上传,支持自动响应内容的编码,支持国际化的URL和POST数据自动编码。在python内置模块的基础上进行了高度的封装,从而......
  • Python 对象拷贝的详细教程
    在本篇文章中,会先介绍Python中对象的基础概念,之后会提到对象的深浅拷贝以及区别。在阅读后,应该掌握如下的内容:理解变量、引用和对象的关系理解Python对象中identity,type和value的概念什么是mutable和immutable对象?以及它们和hashable的关系深浅拷贝的过程以及区别1.......
  • Python 优雅的使用 paramiko 进行交互式输入输出
    目的:需要ssh链接到Linux主机,执行telnet命令,抓回显匹配制定内容。ssh.exec_command(cmd,bufsize,timeout)#exec_command参数使用只需要执行一次的命令,因为执行完该命令以后,shell会自动回到ssh初始连接的shell状态下ssh.invoke_shell()#在SSHserver端创建一个交互式的shell,且......