OpenCV实现多目标追踪(1)
本文利用OpenCV已有的七种目标追踪算法,通过对传入视频中感兴趣的目标对象进行框选,实现实时追踪框选对象。
步骤:
- 首先需要配置相应参数并创建MultiTracker对象,其次,读取并处理视频的每一帧,接着,框选ROI区域,然后,给MultiTracker对象添加实际的追踪算法,最后,对每一帧进行进行目标追踪。
1.配置参数
ap = argparse.ArgumentParser()
ap.add_argument("-v", "--video", type=str,
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稍精确,但速度不佳
"kcf": cv2.legacy.TrackerKCF_create,#有遮挡的情况下表现不佳
"boosting": cv2.legacy.TrackerBoosting_create,#速度较慢,并且表现不好
"mil": cv2.legacy.TrackerMIL_create,#失败率比较高
"tld": cv2.legacy.TrackerTLD_create,#在多帧遮挡下效果最好。但是TLD的误报非常多
"medianflow": cv2.legacy.TrackerMedianFlow_create,#当运动是可预测的并且没有遮挡时,效果非常好,但是对于快速跳动或快速移动的物体,模型会失效。
"mosse": cv2.legacy.TrackerMOSSE_create#速度真心快,但是不如CSRT和KCF的准确率那么高
}
# 实例化OpenCV's multi-object tracker
trackers = cv2.legacy.MultiTracker_create()#创建MultiTracker对象
vs = cv2.VideoCapture(args["video"])
3.处理视频的每一帧
# 视频流
while True:
# 取当前帧
frame = vs.read()
# (true, data)
frame = frame[1]
# 到头了就结束
if frame is None:
break
# resize每一帧
(h, w) = frame.shape[:2]
width=600
r = width / float(w)
dim = (width, int(h * r))
frame = cv2.resize(frame, dim, interpolation=cv2.INTER_AREA)
# 追踪结果
(success, boxes) = trackers.update(frame)#更新目标追踪器,返回两个参数,一个是是否追踪成功,另一个是追踪到的ROI框
4.框选ROI并追踪
# 绘制区域
for box in boxes:
(x, y, w, h) = [int(v) for v in box]#box是一个浮点型的ndarray,绘图时需要转成int型
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
# 显示
cv2.imshow("Frame", frame)
key = cv2.waitKey(100) & 0xFF
if key == ord("s"):
# 选择一个区域,按s
box = cv2.selectROI("Frame", frame, fromCenter=False,
showCrosshair=True)#"Frame":窗口名;frame:图像名;showCrosshair:是否在矩形框里画十字线,默认为True;fromCenter:是否在矩形框里画十字线,默认为False。
# 创建一个新的追踪器
tracker = OPENCV_OBJECT_TRACKERS["csrt"]()#创建一个实际的目标追踪器
trackers.add(tracker, frame, box)#将选择好的目标添加到追踪器上
# 退出
elif key == 27:
break
vs.release()
cv2.destroyAllWindows()