OpenCV_目标追踪

看到了大佬的微信公共号发布了一篇关于OpenCV目标追踪的文章,于是便决定自己来时操作下。大佬公共号是[皮皮科克]:

原文如下:OpenCV案例【31】目标追踪

一、目标追踪介绍

OpenCV 中的目标追踪,简单来说就是让计算机在视频的第一帧“认识”一个物体后,能在后续所有的画面中自动锁定并跟随它。这项技术广泛应用于视频监控、自动驾驶、人机交互和医疗影像分析等领域。

二、OpenCV 中的主要追踪算法

算法名称 核心特点 速度 适用场景
CSRT 精度高,对遮挡和形变鲁棒性好 中等 对准确性要求高的场景,如工业检测、目标部分遮挡
KCF 精度和速度平衡得很好 通用场景,实时性要求较高,目标运动相对平稳
MOSSE 速度极快,计算负载低,但精度一般,只支持灰度图 非常快 极速场景,如低功耗设备、简单背景下的快速追踪
MedianFlow 擅长预测和纠正错误,对目标报错(如方向反转)处理较好 目标运动平滑、可预测,且可能出现自我遮挡的情况
MIL 基于多示例学习,对部分遮挡有一定抵抗力 中等 存在中度遮挡,但对实时性要求不苛刻的环境
Boosting 基于AdaBoost算法,对光照变化有一定鲁棒性,但速度较慢,易漂移 光照条件不稳定,且不追求高速的场景

简单来说,追求最佳效果就选 CSRT,需要快速运行就选 KCF,追求极致速度则考虑 MOSSE

三、示例代码

3.1 单个算法测试:

import cv2

video_path = './video/slam_dunk.mp4'
cap = cv2.VideoCapture(video_path)
if not cap.isOpened():
    raise IOError("视频无法打开")

# 2.读取第一帧
ret, frame = cap.read()
if not ret:
    raise IOError("无法读取帧")

print("正在读取第一帧,请用鼠标框住要追踪的目标,然后按Enter键确认")

bbox = cv2.selectROI("Select Target",frame, fromCenter =  False, showCrosshair = False)
cv2.destroyWindow("Select Target")

if bbox == (0,0,0,0):
    print(f"未选择目标,退出")
    cap.release()
    exit(1)

print(f"目标已选定")

#3 。初始化CRST 追踪器

def create_tracker():
    # 可选:
    return cv2.TrackerCSRT_create()    # 最准、稍慢
    # return cv2.TrackerKCF_create()     # 快 + 准
    # return cv2.legacy.TrackerMOSSE_create()   # 极快
    # return cv2.legacy.TrackerMedianFlow_create()
    # return cv2.legacy.TrackerMIL_create()
    # return cv2.legacy.TrackerTLD_create()
    # return cv2.legacy.TrackerBoosting_create()

tracker = create_tracker()
tracker.init(frame, bbox)

#  # 创建多个追踪器同时对比
# trackers = {
#     "CSRT": cv2.TrackerCSRT_create(),
#     "KCF": cv2.TrackerKCF_create(),
#     "MOSSE": cv2.legacy.TrackerMOSSE_create()
# }
#
# for name in trackers:
#     trackers[name].init(frame, bbox)

#4.开始追踪
print("开始追踪,按q退出")
while True:
    ret, frame = cap.read()
    if not ret:
        print("播放完毕")
        break
    # for name, tracker in trackers.items():
    success, bbox = tracker.update(frame)
    if success:
        (x,y,w,h) = [int (v) for v in bbox]
        cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,0),2)
        cv2.putText(frame,"Tracking",(x,y-10),
                    cv2.FONT_HERSHEY_SIMPLEX,0.6,(0,255,0),2)
    else:
        cv2.putText(frame,"LOST",(20,40),
                    cv2.FONT_HERSHEY_SIMPLEX,1,(0,0,255),2)


    cv2.imshow("CSRT Video tracker...",frame)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()
print("追踪结束")

这是在代码中逐个测试目标追踪算法的代码。

CSRT算法测试效果如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

多个算法测试:

import cv2

video_path = './video/slam_dunk.mp4'
cap = cv2.VideoCapture(video_path)
if not cap.isOpened():
    raise IOError("视频无法打开")

# 2.读取第一帧
ret, frame = cap.read()
if not ret:
    raise IOError("无法读取帧")

print("正在读取第一帧,请用鼠标框住要追踪的目标,然后按Enter键确认")

bbox = cv2.selectROI("Select Target",frame, fromCenter =  False, showCrosshair = False)
cv2.destroyWindow("Select Target")

if bbox == (0,0,0,0):
    print(f"未选择目标,退出")
    cap.release()
    exit(1)

print(f"目标已选定")

#3 。初始化CRST 追踪器

# def create_tracker():
#     # 可选:
#     # return cv2.TrackerCSRT_create()    # 最准、稍慢
#     # return cv2.TrackerKCF_create()     # 快 + 准
#     # return cv2.legacy.TrackerMOSSE_create()   # 极快
#     return cv2.legacy.TrackerMedianFlow_create()
#     # return cv2.legacy.TrackerMIL_create()
#     # return cv2.legacy.TrackerTLD_create()
#     # return cv2.legacy.TrackerBoosting_create()
#
# tracker = create_tracker()
# tracker.init(frame, bbox)

 # 创建多个追踪器同时对比
trackers = {
    "CSRT": cv2.TrackerCSRT_create(),
    "KCF": cv2.TrackerKCF_create(),
    "MOSSE": cv2.legacy.TrackerMOSSE_create()
}

for name in trackers:
    trackers[name].init(frame, bbox)

#4.开始追踪
print("开始追踪,按q退出")
while True:
    ret, frame = cap.read()
    if not ret:
        print("播放完毕")
        break
    for name, tracker in trackers.items():
        success, bbox = tracker.update(frame)
        if success:
           (x,y,w,h) = [int (v) for v in bbox]
           cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,0),2)
           cv2.putText(frame,"Tracking",(x,y-10),
                    cv2.FONT_HERSHEY_SIMPLEX,0.6,(0,255,0),2)
    else:
        cv2.putText(frame,"LOST",(20,40),
                    cv2.FONT_HERSHEY_SIMPLEX,1,(0,0,255),2)


    cv2.imshow("CSRT Video tracker...",frame)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()
print("追踪结束")

代码运行效果:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
好了,OpenCV中目标检测就介绍到这里了。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐