多目标 - 实时追踪
单目标追踪:
多目标追踪:
BUG1:
module 'cv2' has no attribute 'legacy'
- 原因:
opencv_python
和opencv_contrib-python
的版本不一致问题- 解决:安装与
opencv_python
相同版本的opencv_contrib-python
。参考文献
BUG2:
module 'cv2' has no attribute 'TrackerCSRT_create'
- 原因:新版本的
opencv_contrib-python
中,一些函数被取消。- 解决:通过
cv2.legacy
来调用这些函数。如:将cv2.TrackerBoosting_create
改为cv2.legacy.TrackerBoosting_create
。参考文献
机器学习进阶-目标跟踪-KCF目标跟踪方法
计算机视觉项目-实时目标追踪
OpenCV学习笔记15-目标跟踪算法介绍及实战
定义不同的目标追踪算法(不含深度学习):
7+1种目标追踪算法 | 函数 | 说明 |
---|---|---|
BOOSTING Tracker | cv2.legacy.TrackerBoosting_create | 算法原理类似于Harr cascdes(AdaBoost),是一种很老的算法。速度慢并且不准。(最低支持OpenCV 3.0.0) |
MIL Tracker | cv2.legacy.TrackerMIL_create | 比BOOSTING更精确,但是失败率比较高。(最低支持OpenCV 3.0.0) |
KCF Tracker | cv2.legacy.TrackerKCF_create | 速度比BOOSTING和MIL更快,与BOOSTING和MIL一样不能很好的处理遮挡问题。 |
CSRT Tracker | cv2.legacy.TrackerCSRT_create | 比KCF更准一些,但是速度比KCF慢。(最低支持OpenCV 3.4.2) |
TLD Tracker | cv2.legacy.TrackerTLD_create | 在多帧遮挡下效果最好。但是TLD的误报非常多。(最低支持OpenCV 3.0.0) |
MedianFlow | cv2.legacy.TrackerMedianFlow_create | 出色的跟踪故障报告。当运动是可预测的并且没有遮挡时,效果非常好,但是对于快速跳动或快速移动的物体,模型会失效。(最低支持OpenCV 3.0.0) |
MOSSE Tracker | cv2.legacy.TrackerMOSSE_create | 速度真心快,但是不如CSRT和KCF的准确率那么高,如果追求速度选它准没错。(最低支持OpenCV 3.4.1) |
GOTURN Tracker | 这是OpenCV中唯一一深度学习为基础的目标检测器。它需要额外的模型才能运行。(最低支持OpenCV 3.2.0) |
trackers = cv2.legacy.MultiTracker_create() # 使用多目标追踪器
tracker = cv2.legacy.TrackerCSRT_create() # 使用csrt追踪算法
函数说明:success, boxes = trackers.update(frame)
输入参数: frame: 传入的图像
输出参数: success: 是否追踪成功boxes: 追踪到的目标框
(x, y, w, h) = [int(ii) for ii in boxes] # 获取目标位置
cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2) # 矩形框标出动态目标
cv2.imshow('frame', frame) # 实时显示追求目标
函数说明:[min_x, min_y, w, h] = cv2.selectROI(windowName, img, showCrosshair, fromCenter)
输入参数:windowName: 选择的区域被显示在的窗口的名字img: 要在什么图片上选择ROIshowCrosshair: 是否在矩形框里画十字线,默认为True。fromCenter: 是否是从矩形框的中心开始画,默认为False。
输出参数:min_x 为矩形框中最小的x值,左上角min_y 为矩形框中最小的y值,左上角w 为这个矩形框的宽h 为这个矩形框的高
# 备注:选好区域后,按空格或者Enter完成选择;换区域的时候直接通过鼠标重新选择即可
import cv2
image = cv2.imread('blank_write.jpg')
im = cv2.selectROI(windowName='img', img=image, showCrosshair=False, fromCenter=False)
print(im)
cv2.waitKey(1)
import cv2
image=cv2.imread('blank_write.jpg')
im = cv2.selectROI(windowName='img', img=image, showCrosshair=True, fromCenter=False)
print(im)
img_roi = image[int(im[1]):int(im[1]+im[3]), int(im[0]):int(im[0]+im[2])]
cv2.imshow("imageHSV",img_roi)
cv2.waitKey(0)
import cv2# 设置参数
video_load_path = r'C:\Users\my\Videos\football.mp4' # 视频存放地址
video_save_path = r'C:\Users\my\Videos\football2.mov' # 视频存放地址if __name__ == '__main__':cap = cv2.VideoCapture(video_load_path) # 读取视频流ret, frame = cap.read() # 读取帧图像frame_width = int(cap.get(3)) # 获取图像宽,并转换为整数 frame_height = int(cap.get(4)) # 获取图像高,并转换为整数 # 创建保存视频的对象(设置编码格式,帧率,图像的宽高等)out = cv2.VideoWriter(video_save_path, cv2.VideoWriter_fourcc('D', 'I', 'V', 'X'), 10, (frame_width, frame_height))bbox = cv2.selectROI('frame', frame, fromCenter=False, showCrosshair=True) # 人工标注感兴趣目标tracker = cv2.legacy.TrackerCSRT_create() # 使用csrt算法tracker.init(frame, bbox) # 初始化trackerwhile True:_, frame = cap.read() # 读取帧图像if frame is None: # 如果读到的帧数不为空,则继续读取;如果为空,则退出。breakbool_para, box = tracker.update(frame) # 由于物体运动,需要动态的根据物体运动更新矩形框if bool_para: # 若读取成功,我们就定位画框,并跟随(x, y, w, h) = [int(ii) for ii in box]cv2.rectangle(frame, pt1=(int(x),int(y)), pt2=(int(x)+int(w), int(y)+int(h)), color=(0, 255, 0), thickness=2)cv2.imshow('frame', frame) # 实时显示追求目标out.write(frame) # 将每一帧图像写入到输出文件中# 使用 waitKey 可以控制视频的播放速度。数值越小,播放速度越快。if cv2.waitKey(1) == ord(' '): # ord(' '): 按空格结束breakcap.release() # 释放摄像头out.release() # 释放摄像头cv2.destroyAllWindows() # 摧毁所有图窗
import argparse
import cv2# (1)参数设置(视频存放地址 + 指定追踪器类型)
ap = argparse.ArgumentParser()
ap.add_argument('-v', '--video', type=str, default='01.mp4', help='path to input video file')
ap.add_argument('-t', '--tracker', type=str, default='kcf', help='Opencv object tracker type')
args = vars(ap.parse_args())# (2)构造Opencv的追踪算法列表
OPENCV_OBJECT_TRACKERS = {"csrt": cv2.legacy.TrackerCSRT_create,"kcf": cv2.legacy.TrackerKCF_create,"boosting": cv2.legacy.TrackerBoosting_create,"mil": cv2.legacy.TrackerMIL_create,"tld": cv2.legacy.TrackerTLD_create,"medianflow": cv2.legacy.TrackerMedianFlow_create,"mosse": cv2.legacy.TrackerMOSSE_create
}# (3)实例化多目标追踪器
trackers = cv2.legacy.MultiTracker_create()# (4)读取视频
vs = cv2.VideoCapture(args['video'])while True:# (5)读取帧图像frame = vs.read() # frame=[bool, data]frame = frame[1] # 获取帧图像# 若视频播放结束,则跳出if frame is None:break# (6)使用cv2.resize对图像进行长宽的放缩操作h, w = frame.shape[:2] # 获取帧图像的高宽width = 300 # 视频缩放到指定大小r = width / float(w) # 缩放比例dim = (width, int(r * h)) # 缩放后的尺寸frame = cv2.resize(frame, dim, cv2.INTER_AREA)# (7)由于物体运动,需要根据物体的动态运动更新矩形框(success, boxes) = trackers.update(frame)# (8)循环多组矩形框,进行画图操作for box in boxes:(x, y, w, h) = [int(v) for v in box] # 获取动态目标的位置cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2) # 矩形框标出动态目标# (9)显示图像cv2.imshow('Frame', frame)# (10)英文输入下:先按s暂停视频,然后手动选择一个区域,最后按空格键开始播放(可多次重复操作,添加多个追踪目标)key = cv2.waitKey(100) & 0xffif key == ord('s'):box = cv2.selectROI('Frame', frame, fromCenter=False, showCrosshair=True)tracker = OPENCV_OBJECT_TRACKERS[args['tracker']]() # 创建追踪器trackers.add(tracker, frame, box) # 添加追踪器elif key == 27:breakvs.release()
cv2.destroyAllWindows()