You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在OpenCV中实现多目标自动检测追踪,替代手动选择bbox

问题

我正在用OpenCV开发一个算法,用来追踪视频特定区域内的多个移动目标。现在的算法需要在第一帧手动选择bbox(边界框)才能开始追踪,我想改成自动检测所有目标,但不知道具体怎么实现。

当前手动选择bbox的代码片段:

# Select the bounding box in the first frame
bbox = cv2.selectROI(frame, False)
ret = tracker.init(frame, bbox)

完整原始代码:

tracker = cv2.TrackerKCF_create()

# import the necessary packages
# noinspection PyUnresolvedReferences
from imutils.video import VideoStream
import argparse
# noinspection PyUnresolvedReferences
import imutils
import time
import cv2

print("GeeksForGeeks")
print("Your OpenCV version is: " + cv2.__version__)

tracker_types = ['BOOSTING', 'MIL','KCF', 'TLD', 'MEDIANFLOW', 'MOSSE', 'CSRT']
tracker_type = tracker_types[5]

if tracker_type == 'BOOSTING':
    tracker = cv2.legacy.TrackerBoosting_create()
if tracker_type == 'MIL':
    tracker = cv2.TrackerMIL_create()
if tracker_type == 'KCF':
    tracker = cv2.TrackerKCF_create()
if tracker_type == 'TLD':
    tracker = cv2.legacy.TrackerTLD_create()
if tracker_type == 'MEDIANFLOW':
    tracker = cv2.legacy.TrackerMedianFlow_create()
#if tracker_type == 'GOTURN':
   # tracker = cv2.TrackerGOTURN_create()
if tracker_type == 'MOSSE':
    tracker = cv2.legacy.TrackerMOSSE_create()
if tracker_type == "CSRT":
   tracker = cv2.TrackerCSRT_create()


# Get the video file and read it
vid_capture = cv2.VideoCapture('/Users/leonienelz/Downloads/capture_output60_countr02_1676545157.mp4')
ret, frame = vid_capture.read()


frame_height, frame_width = frame.shape[:2]
# Resize the video for a more convinient view
frame = cv2.resize(frame, [frame_width // 2, frame_height // 2])
# Initialize video writer to save the results
output = cv2.VideoWriter(f'{tracker_type}.avi',
                         cv2.VideoWriter_fourcc(*'XVID'), 60.0,
                         (frame_width // 2, frame_height // 2), True)
if not ret:
    print('cannot read the video')
# Select the bounding box in the first frame
bbox = cv2.selectROI(frame, False)
ret = tracker.init(frame, bbox)
# Start tracking
while True:
    ret, frame = vid_capture.read()
    frame = cv2.resize(frame, [frame_width // 2, frame_height // 2])
    if not ret:
        print('something went wrong')
        break
    timer = cv2.getTickCount()
    ret, bbox = tracker.update(frame)
    fps = cv2.getTickFrequency() / (cv2.getTickCount() - timer)
    if ret:
        p1 = (int(bbox[0]), int(bbox[1]))
        p2 = (int(bbox[0] + bbox[2]), int(bbox[1] + bbox[3]))
        cv2.rectangle(frame, p1, p2, (255, 0, 0), 2, 1)
    else:
        cv2.putText(frame, "Tracking failure detected", (100, 80),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 0, 255), 2)
    cv2.putText(frame, tracker_type + " Tracker", (100, 20),
                cv2.FONT_HERSHEY_SIMPLEX, 0.75, (50, 170, 50), 2)
    cv2.putText(frame, "FPS : " + str(int(fps)), (100, 50),
                cv2.FONT_HERSHEY_SIMPLEX, 0.75, (50, 170, 50), 2)
    cv2.imshow("Tracking", frame)
    output.write(frame)
    k = cv2.waitKey(1) & 0xff
    if k == 27: break

vid_capture.release()
output.release()
#cv2.destroyAllWindows()

解决方案

核心思路

要实现自动检测+多目标追踪,分两步走:

  1. 目标自动检测:在第一帧用目标检测模型识别所有需要追踪的目标边界框
  2. 多目标追踪管理:为每个检测到的目标初始化独立追踪器,后续帧统一更新所有追踪器的位置

下面以HOG+SVM行人检测(适合行人追踪场景)和OpenCV多追踪器为例,修改代码实现需求:

修改后的完整代码

# 导入必要包
from imutils.video import VideoStream
import argparse
import imutils
import time
import cv2

print("GeeksForGeeks")
print("Your OpenCV version is: " + cv2.__version__)

tracker_types = ['BOOSTING', 'MIL','KCF', 'TLD', 'MEDIANFLOW', 'MOSSE', 'CSRT']
tracker_type = tracker_types[5]  # 选用MOSSE,速度快适合多目标场景

# 初始化多追踪器,用于管理多个目标的追踪器
multi_tracker = cv2.legacy.MultiTracker_create()

# 初始化HOG行人检测器(如果追踪其他目标,替换为对应检测器即可)
hog = cv2.HOGDescriptor()
hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())

# 读取视频文件
vid_capture = cv2.VideoCapture('/Users/leonienelz/Downloads/capture_output60_countr02_1676545157.mp4')
ret, frame = vid_capture.read()

frame_height, frame_width = frame.shape[:2]
# 调整视频尺寸方便查看
frame = cv2.resize(frame, [frame_width // 2, frame_height // 2])
# 初始化视频写入器保存结果
output = cv2.VideoWriter(f'{tracker_type}_multi.avi',
                         cv2.VideoWriter_fourcc(*'XVID'), 60.0,
                         (frame_width // 2, frame_height // 2), True)
if not ret:
    print('无法读取视频')

# ---------------------------
# 替换手动选框:自动检测目标
# ---------------------------
# HOG检测行人,参数可根据场景调整
rects, weights = hog.detectMultiScale(frame, winStride=(4, 4), padding=(8, 8), scale=1.05)
# 非极大值抑制,去除重叠框避免重复追踪
rects = imutils.non_max_suppression(rects, probs=None, overlapThresh=0.65)

# 为每个检测到的目标初始化追踪器并添加到多追踪器
for (x, y, w, h) in rects:
    # 根据选择的追踪器类型创建实例
    if tracker_type == 'BOOSTING':
        tracker = cv2.legacy.TrackerBoosting_create()
    elif tracker_type == 'MIL':
        tracker = cv2.TrackerMIL_create()
    elif tracker_type == 'KCF':
        tracker = cv2.TrackerKCF_create()
    elif tracker_type == 'TLD':
        tracker = cv2.legacy.TrackerTLD_create()
    elif tracker_type == 'MEDIANFLOW':
        tracker = cv2.legacy.TrackerMedianFlow_create()
    elif tracker_type == 'MOSSE':
        tracker = cv2.legacy.TrackerMOSSE_create()
    elif tracker_type == "CSRT":
        tracker = cv2.TrackerCSRT_create()
    # 将追踪器和对应目标框添加到多追踪器
    multi_tracker.add(tracker, frame, (x, y, w, h))

# 开始追踪循环
while True:
    ret, frame = vid_capture.read()
    frame = cv2.resize(frame, [frame_width // 2, frame_height // 2])
    if not ret:
        print('视频读取异常')
        break
    timer = cv2.getTickCount()
    # 更新所有追踪器的位置
    ret, bboxes = multi_tracker.update(frame)
    fps = cv2.getTickFrequency() / (cv2.getTickCount() - timer)
    
    # 绘制所有追踪框
    if ret:
        for i, bbox in enumerate(bboxes):
            p1 = (int(bbox[0]), int(bbox[1]))
            p2 = (int(bbox[0] + bbox[2]), int(bbox[1] + bbox[3]))
            # 用不同颜色区分不同目标
            color = (0, 255*(i%3), 255*(i%2))
            cv2.rectangle(frame, p1, p2, color, 2, 1)
    else:
        cv2.putText(frame, "部分目标追踪失败", (100, 80),
                    cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 0, 255), 2)
    
    # 添加文字信息
    cv2.putText(frame, tracker_type + " 多目标追踪器", (100, 20),
                cv2.FONT_HERSHEY_SIMPLEX, 0.75, (50, 170, 50), 2)
    cv2.putText(frame, "FPS : " + str(int(fps)), (100, 50),
                cv2.FONT_HERSHEY_SIMPLEX, 0.75, (50, 170, 50), 2)
    cv2.imshow("多目标追踪", frame)
    output.write(frame)
    # 按ESC退出
    k = cv2.waitKey(1) & 0xff
    if k == 27: break

# 释放资源
vid_capture.release()
output.release()
cv2.destroyAllWindows()

关键修改说明

  1. 自动检测替换手动选框:用HOG+SVM实现行人自动检测,若需追踪其他目标,可替换为Haar级联分类器(如车辆检测)或YOLO系列模型(通用目标检测)
  2. 多追踪器管理:使用cv2.legacy.MultiTracker_create()替代单个追踪器,支持同时追踪多个目标
  3. 目标去重:用imutils.non_max_suppression去除重叠检测框,避免重复追踪同一目标
  4. 多目标可视化:为每个目标分配不同颜色的追踪框,方便区分

扩展优化建议

  • 特定区域过滤:在检测后,可添加逻辑只保留位于指定区域内的目标框,实现"特定区域内追踪"的需求
  • 高精度检测:如果需要更高精度,可使用YOLOv8的ONNX模型,OpenCV支持直接加载ONNX模型进行推理
  • 失效重检测:添加追踪失效判断,当某个目标追踪失败时,重新运行检测找回目标

内容的提问来源于stack exchange,提问作者phytonnewbie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 15:35:27