关注

计算机视觉——Opencv(物体跟踪)

什么是物体跟踪?

物体跟踪(Object Tracking)是指在视频序列中,对预先选定的目标物体进行连续的位置定位,输出目标在每一帧中的坐标、尺寸信息。与目标检测不同:

  • 目标检测:逐帧独立识别画面中的所有目标,无前后帧关联;

  • 物体跟踪:仅初始化时选定目标,后续通过帧间关联算法持续追踪,速度更快、资源消耗更低。

简单来说:检测是 “找目标”,跟踪是 “跟目标”

OpenCV 内置跟踪器对比

OpenCV 3.x 及以上版本内置了多种经典跟踪器,适配不同场景,核心跟踪器特性如下:

跟踪器类型核心优势局限性适用场景
BOOSTING算法简单,兼容性强速度慢,遮挡后易丢失低分辨率、简单场景
MIL精度较高,抗轻微遮挡速度一般,无法处理快速运动静态目标、慢速运动目标
KCF速度极快,精度高无法处理完全遮挡、尺度变化实时性要求高的场景
CSRT精度极高,抗遮挡、抗尺度变化速度较慢高精度要求、复杂场景
MEDIANFLOW运动轨迹平滑遮挡后完全失效运动规律的目标
TLD抗长期遮挡速度慢,易误跟踪长期跟踪场景

本文选择 CSRT 跟踪器的原因:它在精度和鲁棒性上表现最优,能应对目标尺度变化、轻微遮挡,非常适合入门学习和实际简单场景使用,是物体跟踪入门的首选跟踪器。

ROI:物体跟踪的核心前提

ROI(Region of Interest)即感兴趣区域,是物体跟踪的 “起点”。我们需要手动框选视频帧中的目标区域,告诉跟踪器:你需要追踪的目标就是这个区域。跟踪器会基于 ROI 的特征,在后续帧中匹配并更新位置。

完整代码解析

导入库与初始化跟踪器

import cv2
# 创建一个CSRT跟踪器实例
tracker = cv2.TrackerCSRT_create()

cv2.TrackerCSRT_create():创建 CSRT 跟踪器对象,这是 OpenCV 提供的标准化 API,无需手动实现算法。

定义状态变量与打开摄像头

# 跟踪标志,默认为False
tracking = False
# 打开默认摄像头(通常编号为0)
cap = cv2.VideoCapture(0)
  • tracking:布尔型标志位,控制跟踪的开启与关闭,False表示未开始跟踪;

  • cv2.VideoCapture(0):打开摄像头设备。参数0代表默认摄像头,若有多个摄像头,可改为 1、2 切换;若要处理视频文件,可传入视频路径(如cv2.VideoCapture("test.mp4"))。

主循环:读取视频帧

while True:
    # 从摄像头读取一帧图像
    ret, frame = cap.read()
    # 如果没有正确读取到图像,则退出循环
    if not ret:
        break
  • hile True:无限循环,持续读取摄像头帧,实现实时视频流;

  • cap.read():读取一帧数据,返回两个值:

    • ret:布尔值,True表示读取帧成功,False表示读取失败(摄像头断开、视频结束);

    • frame:读取到的视频帧(三维数组,存储图像像素信息);

  • if not ret: break:异常处理,读取失败时退出循环,避免程序崩溃。

按键触发:框选目标并初始化跟踪

if cv2.waitKey(1) == ord('s'):
    tracking = True
    # 让用户在当前帧中选择一个矩形区域作为要跟踪的对象
    roi = cv2.selectROI('Tracking', frame, False)
    # 初始化跟踪器,传入当前帧和选定的ROI
    tracker.init(frame, roi)
  • cv2.waitKey(1):监听键盘按键,每 1 毫秒刷新一次;

  • ord('s'):获取按键 'S' 的 ASCII 码,按下 S 键时触发跟踪;

  • tracking = True:将跟踪标志置为真,启动跟踪;

  • cv2.selectROI():弹出窗口,允许用户用鼠标框选目标:

    • 第一个参数:窗口名称;

    • 第二个参数:要框选的帧;

    • 第三个参数:False表示不显示十字线,兼容所有 OpenCV 版本;

    • 返回值roi:框选区域的坐标(x, y, w, h)(x = 左上角横坐标,y = 左上角纵坐标,w = 宽度,h = 高度);

  • tracker.init(frame, roi)跟踪器初始化,告诉跟踪器 “要跟踪的目标是这个区域”。

实时更新跟踪结果

if tracking:
    success, box = tracker.update(frame)
    if success:
        x, y, w, h = [int(v) for v in box]
        cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
  • 仅当tracking=True时,执行跟踪更新;

  • tracker.update(frame):跟踪器根据当前帧,更新目标位置,返回两个值:

    • success:布尔值,True表示跟踪成功,False表示目标丢失;

    • box:跟踪到的目标坐标(x, y, w, h)

  • 坐标转换:box返回的是浮点数,需转为整数才能绘制矩形;

  • cv2.rectangle():在视频帧上绘制绿色矩形,标记跟踪目标(颜色:(0,255,0),线条宽度:2)。

显示画面与退出程序

cv2.imshow('Tracking', frame)
if cv2.waitKey(1) == 27:
    break

cv2.waitKey(1) == 27:监听 ESC 键(ASCII 码 27),按下后退出循环

资源释放

cap.release()
cv2.destroyAllWindows()

转载自CSDN-专业IT技术社区

原文链接:https://blog.csdn.net/2401_83998832/article/details/159174908

评论

赞0

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--