单目标追踪程序:完成单目标追踪算法,在图像的追踪效果检测非常好

上周帮同实验室的哥们调他的毕设单目标追踪代码,本来以为就是套个现成的库就行,结果俩人蹲在机房啃了半宿才搞明白为啥他的视频里橘猫跑着跑着就跟丢了——说白了就是他一开始选的追踪器太拉胯。

其实单目标追踪说穿了特别接地气,就是给视频里的一个目标先框好,然后让程序跟着这个目标在后续帧里自动找它的位置,不管它怎么晃、躲点小障碍物,只要不是彻底藏没影了,都能尽量跟上。OpenCV里自带了好几种现成的追踪器,比如KCF、CSRT、MOSSE这些,各有各的优缺点:KCF快但抗遮挡差,CSRT慢一丢丢但稳得一批,我们最后用的就是CSRT,毕竟追猫这种爱钻缝的主儿,稳比快重要。

直接上我改完的代码,亲测追猫追仓鼠都好使:

import cv2
import numpy as np

tracker = cv2.TrackerCSRT_create()

# 读取视频文件,填0的话直接调用电脑摄像头
video_path = "your_video_path.mp4"
cap = cv2.VideoCapture(video_path)

# 读取第一帧,手动选要追踪的目标
ret, frame = cap.read()
if not ret:
    print("打不开视频啊老哥,检查下路径对不对")
    exit()

# 鼠标拖框选目标,选完按回车/空格确认就行,别框太宽带太多背景
bbox = cv2.selectROI("选要追踪的目标", frame, False)
# 把选好的框喂给追踪器初始化
tracker.init(frame, bbox)

# 循环处理每一帧
while True:
    ret, frame = cap.read()
    if not ret:
        break
    
    # 更新追踪位置,ok是是否成功追到,new_bbox是新的框坐标
    ok, new_bbox = tracker.update(frame)
    if ok:
        # 把框画到画面上,OpenCV的格式是(x,y,w,h),转成矩形直接画
        x, y, w, h = map(int, new_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.5, (0, 255, 0), 2)
    else:
        # 跟丢了弹个红提示,这时候可以手动重框或者加自动重检测逻辑
        cv2.putText(frame, "Lost Target!", (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
    
    # 显示结果,按q退出,30ms的延迟刚好对应正常视频帧率
    cv2.imshow("Single Target Tracking", frame)
    if cv2.waitKey(30) & 0xFF == ord('q'):
        break

# 记得释放资源,不然会占着视频文件/摄像头
cap.release()
cv2.destroyAllWindows()

咱一步步唠唠这段代码,没那么多学术套话:

首先导入库就不多说了,cv2是核心,numpy其实这里不用也行,但习惯带上防报错。初始化追踪器的时候选CSRT,就是刚才说的稳的那个,我们当时追那只钻沙发的橘猫,换了CSRT之后就没丢过,之前用KCF刚看到猫躲垃圾桶后面直接就跟丢了。

然后读取视频的部分,要是想直接用摄像头拍着玩,把video_path改成0就行,我试过用摄像头追自己的手,晃来晃去都能跟上。selectROI这个函数绝了,不用自己手动写坐标,直接拖鼠标拉框就行,选完按回车就确认,当时我们框的就是那橘猫的脑袋,别框太宽啊,框太宽把背景带进去,追踪器容易被别的东西干扰。

单目标追踪程序:完成单目标追踪算法,在图像的追踪效果检测非常好

循环读帧的时候,每帧都调用tracker.update(),它会返回两个值:一个是有没有成功追踪到,另一个是新的框坐标。成功的话就画个绿框,还加个小字标注“Tracking”,要是跟丢了就弹个红的“Lost Target!”提示你。最后按q就能退出,记得释放资源,不然会占着摄像头或者视频文件。

当时我俩踩的坑可不少:一开始哥们把视频路径写错了,直接报了个空指针,我俩愣了十分钟才反应过来;还有他一开始用的是cv2.waitKey(1),结果帧跑得飞快,根本看不清追踪效果,改成30之后就和正常视频速度差不多了。

我们最后用这段代码跑了宿舍楼道拍的橘猫视频,那猫从楼梯上跑下来,还躲在垃圾桶后面藏了两秒,CSRT追踪器居然稳稳地跟着,直到猫跑出镜头才跟丢,效果比他一开始的版本好太多了。

要是想搞更进阶的,比如不用手动框选目标,先拿YOLOv8检测一下第一帧的目标,把检测到的框传给追踪器就行,不过单目标的话手动框其实更省心,不用搞那么复杂的检测逻辑。

反正这个代码真的足够应付大多数日常的单目标追踪场景了,不管是追猫追狗追仓鼠,还是追实验室里乱跑的器材,都好使,亲测有效!

Logo

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

更多推荐