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

OpenCV版本兼容问题致目标跟踪代码无法运行求助

OpenCV目标跟踪代码版本兼容问题修复与全跟踪器对比方案

问题概述

手上有一套基于旧版OpenCV编写的目标跟踪代码,运行时报错:AttributeError: module 'cv2' has no attribute 'TrackerCSRT_create',查阅官方文档和网络资料后仍未解决,需要适配新版OpenCV并获取所有可用目标跟踪技术进行对比测试。

错误原因

从OpenCV 4.x版本开始,大部分传统目标跟踪器被迁移至cv2.legacy模块下,旧版直接调用cv2.TrackerXX_create的方式不再生效,这是导致报错的核心原因。

修复与适配方案

  1. 调整跟踪器初始化路径:将原代码中cv2.TrackerXX_create的调用改为从cv2.legacy模块获取
  2. 兼容多版本(可选):添加版本判断逻辑,让代码同时支持OpenCV 3.x和4.x+环境
  3. 扩充跟踪器范围:加入OpenCV 4.x新增的跟踪器(如GOTURN、DaSiamRPN),覆盖所有官方支持的跟踪技术

适配后的全跟踪器对比代码

import cv2
import numpy as np
import matplotlib.pyplot as plt
import time
import pandas as pd

# 适配OpenCV多版本的跟踪器映射,包含所有官方支持的跟踪器
OPENCV_OBJECT_TRACKERS = {
    "csrt": cv2.legacy.TrackerCSRT_create if hasattr(cv2.legacy, 'TrackerCSRT_create') else cv2.TrackerCSRT_create,
    "kcf": cv2.legacy.TrackerKCF_create if hasattr(cv2.legacy, 'TrackerKCF_create') else cv2.TrackerKCF_create,
    "boosting": cv2.legacy.TrackerBoosting_create,
    "mil": cv2.legacy.TrackerMIL_create,
    "tld": cv2.legacy.TrackerTLD_create,
    "medianflow": cv2.legacy.TrackerMedianFlow_create,
    "mosse": cv2.legacy.TrackerMOSSE_create,
    # OpenCV 4.x新增跟踪器
    "goturn": cv2.TrackerGOTURN_create if hasattr(cv2, 'TrackerGOTURN_create') else None,
    "dasiamrpn": cv2.TrackerDaSiamRPN_create if hasattr(cv2, 'TrackerDaSiamRPN_create') else None
}

# 过滤当前环境不支持的跟踪器
available_trackers = {k:v for k,v in OPENCV_OBJECT_TRACKERS.items() if v is not None}
print("可用跟踪器列表:", list(available_trackers.keys()))

# 选择单个跟踪器测试(可替换为循环实现批量测试)
tracker_name = "mil"
tracker = available_trackers[tracker_name]()
print("当前使用跟踪器:", tracker_name)

gt = pd.read_csv("gt_new.txt")
video_path = "MOT17-13-SDP.mp4"
cap = cv2.VideoCapture(video_path)

# 通用参数初始化
initBB = None
fps = 25
frame_number = []
f = 0
success_track_count = 0
track_list = []
start_time = time.time() 

while True:
    time.sleep(0.01)
    ret, frame = cap.read()
    
    if ret:
        frame = cv2.resize(frame, dsize=(960, 540))
        (H, W) = frame.shape[:2]
        
        # 绘制真实标注框(GT)
        car_gt = gt[gt.frame_no == f]
        if len(car_gt) != 0:
            x, y, w, h = car_gt.x.values[0], car_gt.y.values[0], car_gt.w.values[0], car_gt.h.values[0]
            center_x, center_y = car_gt.center_x.values[0], car_gt.center_y.values[0]
            
            cv2.rectangle(frame, (x, y), (x+w, y+h), (0,255,0), 2)
            cv2.circle(frame, (center_x, center_y), 2, (0,0,255), -1)
            
        # 跟踪逻辑执行
        if initBB is not None:
            success, box = tracker.update(frame)
            
            if f <= np.max(gt.frame_no):
                x, y, w, h = [int(i) for i in box]
                cv2.rectangle(frame, (x, y), (x+w, y+h), (0,0,255), 2)
                success_track_count += 1
                track_center_x = int(x + w/2)
                track_center_y = int(y + h/2)
                track_list.append([f, track_center_x, track_center_y])
            
            # 显示跟踪状态信息
            info = [("跟踪器", tracker_name), ("跟踪成功", "是" if success else "否")]
            for i, (label, value) in enumerate(info):
                text = f"{label}: {value}"
                cv2.putText(frame, text, (10, H - (i*20) - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0,0,255), 2)
        
        # 显示当前帧号
        cv2.putText(frame, f"帧号: {f}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,255), 2)
        cv2.imshow("跟踪画面", frame)    
        
        # 按键控制
        key = cv2.waitKey(1) & 0xFF
        if key == ord("t"):
            initBB = cv2.selectROI("跟踪画面", frame, fromCenter=False)
            tracker.init(frame, initBB)
        elif key == ord("q"):
            break
        
        frame_number.append(f)
        f += 1 
    else:
        break

cap.release()
cv2.destroyAllWindows()            

# 计算跟踪耗时
stop_time = time.time()
total_time = stop_time - start_time          

# 跟踪结果评估
track_df = pd.DataFrame(track_list, columns=["frame_no", "center_x", "center_y"])

if len(track_df) != 0:
    print("跟踪方法: ", tracker)
    print("总耗时: ", total_time)
    print("GT总帧数: ", len(gt))
    print("跟踪成功帧数: ", success_track_count)
    
    # 计算GT与跟踪结果的欧氏误差
    track_frames = track_df.frame_no
    gt_center_x = gt.center_x[track_frames].values
    gt_center_y = gt.center_y[track_frames].values
    
    track_center_x = track_df.center_x.values
    track_center_y = track_df.center_y.values
    
    error_per_frame = np.sqrt((gt_center_x - track_center_x)**2 + (gt_center_y - track_center_y)**2 )
    plt.plot(error_per_frame)
    plt.xlabel("帧号")
    plt.ylabel("GT与跟踪结果的欧氏距离")
    plt.title(f"{tracker_name}跟踪误差曲线")
    plt.show()
    
    total_error = np.sum(error_per_frame)
    print("总误差: ", total_error)

批量对比测试实现

若要批量测试所有可用跟踪器,可将单个跟踪器选择逻辑替换为循环遍历:

for tracker_name in available_trackers.keys():
    print(f"\n===== 测试跟踪器: {tracker_name} =====")
    tracker = available_trackers[tracker_name]()
    
    # 重置跟踪相关变量
    initBB = None
    success_track_count = 0
    track_list = []
    start_time = time.time()
    f = 0
    
    # 后续执行原代码中的视频读取、跟踪、评估逻辑(需将循环内的帧计数等变量重置)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 21:24:56