尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

BoxMOT 原生 BoTSORT:C++17 追踪器核心的构建、Replay 管线与双布局推理实战

BoxMOT 原生 BoTSORT:C++17 追踪器核心的构建、Replay 管线与双布局推理实战 BoxMOT 原生 BoTSORTC17 追踪器核心的构建、Replay 管线与双布局推理实战【免费下载链接】boxmotBoxMOT: Pluggable Python and C SOTA multi-object tracking modules with support for axis-aligned and oriented bounding boxes项目地址: https://gitcode.com/GitHub_Trending/bo/boxmotBoTSORT 是 BoxMOT 仓库中同时具备 Python 与原生 C 两套实现的代表性多目标追踪器。本指南以 boxmot/native/cpp/trackers/botsort/README.md 为骨架完整讲解原生 C17 BoTSORT 的构建方式、在缓存回放replay与在线推理live两条路径中的角色、ReID 与 AABB/OBB 双布局支持并结合仓库源码入口、C ABI、数据 I/O、追踪循环、相机运动补偿与单元测试帮助读者既能在命令行/ Python API 层面落地使用也能理解其底层调用链与工程约束。原生 C 追踪器族botsort、bytetrack、occluboost、ocsort、sfsort的整体布局、构建入口与后端选择方式见 boxmot/native/cpp/README.md公开集成与嵌入指南见 docs/native/index.md。一、原生 BoTSORT 在 BoxMOT 中的角色README 明确指出boxmot/native/cpp/trackers/botsort/目录提供的是C17 实现服务于两个场景独立 replay 可执行程序botsort_replay供缓存式 benchmark 工作流使用共享库live library供在线track --tracker-backend cpp使用。从 CMakeLists.txt 可以确认该目录既定义了可复用的 tracker 核心目标也产出了botsort_replay可执行文件与botsort_capi共享库其 OpenCV 组件依赖为calib3d core dnn imgcodecs imgproc video。共享追踪基座boxmot/trackers/base/C 侧为boxmot/native/cpp/trackers/base/承担了 replay 主循环、检测序列加载、MOT 结果行输出等与具体算法无关的通用逻辑而 BoTSORT 特有的关联/状态机逻辑集中在 src/tracker.cpp。缓存回放cached replay三步流水线README 将原生 runner 定位为缓存回放阶段的核心整体流程为Python 侧生成检测与 embedding写入runs/dets_n_embs/...botsort_replay消费缓存检测并写出 MOT 结果文件Python 侧对生成的结果运行仓库内置 MOT 指标。对应的 Python 侧入口是 boxmot/native/trackers/botsort.py 中的process_sequence_cpp它负责解析检测/embedding 缓存位置、将追踪器配置序列化为--track-*-thresh、--cmc-method等命令行参数再通过run_replay_process启动botsort_replay子进程。值得注意的是process_sequence_cpp目前仅支持tracker_namebotsort参见其if str(tracker_name).lower() ! botsort: raise ValueError(...)的保护逻辑。在线推理live路径在线模式下Python 侧通过 ctypes 加载tracker_capi共享库。_BotSortLiveLibrary封装了boxmot_botsort_create/destroy/reset/update以及一组 ReID 耗时查询函数boxmot_botsort_last_reid_time_ms及 preprocess/process/postprocess 三段细分耗时并通过NativeBotSortTracker继承NativeTrackerMixin以统一的update(dets, img, embs)接口接入追踪框架。从_BotSortCConfig的字段可以看到 live 路径支持的完整配置集合与 C 侧 types.hpp 的botsort::Config一一对应。二、构建与环境要求README 给出的构建命令如下cmake -S boxmot/native/cpp/trackers/botsort -B build/native/botsort -DCMAKE_BUILD_TYPERelease cmake --build build/native/botsort --config Release --target botsort_replay如果 CMake 无法自动定位 OpenCV 或 Eigen3可在 configure 阶段显式传入cmake -S boxmot/native/cpp/trackers/botsort -B build/native/botsort \ -DCMAKE_BUILD_TYPERelease \ -DOpenCV_DIR/path/to/opencv/lib/cmake/opencv4 \ -DEigen3_DIR/path/to/eigen/share/eigen3/cmake最低依赖版本README docs/native/index.md 交叉确认依赖最低版本说明C17 编译器GCC 9 / Clang 10 / MSVC 2019docs 中的放宽区间为 GCC ≥ 7 / Clang ≥ 5 / MSVC ≥ 19.14CMake3.16与cmake_minimum_required(VERSION 3.16)一致OpenCV4.x组件calib3d core dnn imgcodecs imgproc videoEigen33.3仅头文件追踪器内部大量使用Eigen::Vector4d、Eigen::MatrixXd等Ubuntu/Debian 一键安装系统依赖sudo apt install -y build-essential cmake libopencv-dev libeigen3-dev。两种使用入口的构建差异在源码/可编辑安装中boxmot build可预构建全部 live 共享库boxmot build全部、boxmot build --tracker bytetrack --tracker ocsort子集、boxmot build --force强制重建botsort_replay等缓存回放可执行文件不会被boxmot build预构建而是在首次eval/tune时按需构建参见 docs/native/index.mdPython 包装层botsort.py 中的ensure_botsort_cpp_executable/ensure_botsort_cpp_library使用线程锁保护按需构建过程保证多线程场景下只触发一次编译。三、从 BoxMOT CLI 使用原生 BoTSORT在源码安装下通过--tracker-backend cpp即可将追踪器实现切换为原生 C 后端。对botsort而言track使用 live 共享库eval/tune使用缓存回放# 在线追踪live boxmot track --detector yolov8n --tracker botsort --tracker-backend cpp --source video.mp4 # 缓存回放评估 boxmot eval --experiment mot17-ablation-yolox-lmbn --tracker botsort --tracker-backend cpp # 兼容别名--tracking-backend cpp 仍可被缓存回放类命令接受 boxmot eval --experiment mot17-ablation-yolox-lmbn --tracker botsort --tracking-backend cpp从 boxmot/native/cpp/README.md 可知两个后端参数的语义区分--tracker-backend决定追踪器实现用 Python 还是 C--tracking-backend则是兼容别名指代缓存回放的进程/线程执行策略。Python 侧直接调用时等价写法为model.track(..., tracker_backendcpp)、model.val(..., tracker_backendcpp)与model.tune(..., tracker_backendcpp)。当前后端能力矩阵TrackerLivetrackCached replay备注botsort是是AABB/OBB使用原生 C ReIDbytetrack是是AABB/OBB无 ReIDoccluboost是是AABB/OBBReID 用于 embedding、recovery 与 second passocsort是是AABB/OBB原生后端当前使用asso_funciousfsort是是AABB/OBB无 ReID注意原生 live 追踪器目前不支持per_classTrue需要按类别隔离追踪状态时应使用 Python 后端docs/native/index.md。四、ReID 支持与原生 ONNX 推理README 对原生 BoTSORT 的 ReID 能力有明确描述可归纳为四条live 原生追踪当追踪器配置了.onnx的 ReID 模型如models/lmbn_n_duke.onnx时可在内部运行 ONNX ReID 推理replay 回退当 embedding 缓存不可用且提供了.onnxReID 模型路径时原生回放可回退到 ONNX ReID 推理预处理契约一致AABB crops 与矫正后的 OBB crops 共享 Python 侧预处理契约批量支持动态 batch 与固定 batch 的 ONNX 输入均受支持已存在的 embedding 缓存仍会优先复用。从实现看C 侧通过boxmot::trackers::base::OnnxReIdModelreid_onnx.hpp 中using OnnxReIdModel boxmot::trackers::base::OnnxReIdModel;完成裁剪、resize、归一化与模型推理GetReIdFeaturesTimed额外返回 preprocess/process/postprocess 三段耗时供 C ABI 的boxmot_botsort_last_reid_*_time_ms系列查询。OBB 检测会被矫正为摆正的轴对齐裁剪warped to straightened axis-aligned cropsAABB 则直接 clamp 后裁剪两者都复用 base 的GetReIdFeaturesForDetections。在追踪主循环tracker.cpp 的Update中只有当with_reid开启、模型存在且检测缺少 embedding时才会触发一次批量 ReID 推理推理结果逐行写回Detection::embeddingPython 包装层在update()前会对 embedding 做有限性校验非有限值直接抛ValueError参见测试test_native_botsort_rejects_nonfinite_embeddings确保无效特征不会流入原生赋值阶段。.pt 权重的自动导出当传入的 ReID 权重是.pt文件时Python 包装层会自动导出兼容的 ONNX 产物并缓存在原生 ONNX 缓存路径后续原生运行直接复用该导出botsort.py 的_ensure_native_reid_model_path/_export_reid_to_onnx。一个特殊边界是在 macOS 的 CI runner 上当仅有.pt权重且无缓存的 ONNX 时为避免导出崩溃原生 ReID 会被显式关闭with_reidFalse并记录 warning对应测试test_native_botsort_ci_macos_disables_pt_reid_without_cached_onnx。嵌入缓存布局缓存采用 producer-first 布局Python/PyTorch 与 C/ONNX Runtime 生成的 embedding 落在不同 bucketembs/ python|cpp/ model-format-runtime[-wHASH]/ preprocess-cropvN/ sequence.npypython/cpp标识实际产生 embedding 的代码路径而非追踪器算法wHASH对解析后的模型产物做指纹cropvN对 ReID 预处理前的 crop 几何做版本化。测试test_cached_embedding_path_uses_versioned_preprocess_directory给出的实际示例路径为runs/dets_n_embs/mot17-mini/yolox_x/embs/cpp/lmbn_n_duke-pt-ort/resize-cropv2/MOT17-02-FRCNN.npy当 embedding 缓存完整时replay 命令的--reid-model会被置空测试test_process_sequence_cpp_uses_complete_explicit_embedding_cache断言了这一行为避免不必要的模型加载。可用的运行时环境变量docs/native/index.mdBOXMOT_REID_BACKEND—auto默认、ort/onnxruntime、opencv/dnnauto优先使用 ONNX Runtime否则回退 OpenCV DNNBOXMOT_REID_DEVICE—autoC 运行时默认、cpu、cuda、coreml加速器不可用时回退 CPU。五、AABB 与 OBB 双布局检测契约与 Kalman 状态变换README 归纳的检测/布局支持如下Live 原生追踪接受 6 列的 AABB 检测x1 y1 x2 y2 conf cls与 7 列的 OBB 检测cx cy w h angle conf cls缓存回放接受 7 列的 AABB 缓存与 8 列的 OBB 缓存多出的列应为帧索引列OBB 输出原生 OBB 回放按 MMOT 风格角点输出写入结果供下游 OBB 评估流程消费。在 C 数据契约层面types.hpp 的botsort::Detection同时携带Eigen::Vector4d xyxy与Eigen::Matrixdouble,5,1 xywha通过is_obb标志区分TrackOutput亦同构。追踪器内部在首次收到检测时锁定布局模式is_obb_mode_之后禁止在同一实例上混用 AABB 与 OBB否则抛出std::runtime_error(Native BoTSORT cannot switch between AABB and OBB detections after initialization.)Python 包装层在_coerce_detections_for_mode中做了同样的布局锁定测试test_native_botsort_tracker_rejects_mode_switch_after_initialization与test_native_botsort_empty_obb_frame_latches_layout_before_first_detection验证了空帧也能提前锁定 OBB 布局。IoU 计算针对两种布局分别实现AABB 用经典矩形交并比OBB 使用 OpenCV 的cv::rotatedRectangleIntersectioncv::contourAreatracker.cpp 的AabbIoU/ObbIoU。Kalman 状态维度自适应BotSortTracker的 Kalman 滤波器按布局自适应AABB 使用 4 维测量KalmanFilterXYWH(4)OBB 使用 5 维测量KalmanFilterXYWH(5)在首次锁定布局时创建kalman_filter_ KalmanFilterXYWH(det_is_obb ? 5 : 4);。配套的botsort_obb_cmc_probeEXCLUDE_FROM_ALL仅测试构建用于 Python 单测验证原生 OBB 相机运动状态变换与transform_obb_kalman_state的一致性AABB 场景下原生均值/协方差与 Python 的transform_aabb_kalman_state以rtolatol1e-10严格对齐test_native_botsort_aabb_cmc_state_matches_python_jacobianOBB 场景下similarity 变换为解析路径容差2e-2/1e-2以内即可affine 变换因不同 OpenCV 构建的minAreaRectfloat32 重拟合协方差交叉项允许约1e-2偏差test_native_botsort_obb_cmc_state_matches_python_jacobian。六、replay 可执行文件的参数契约botsort_replay的命令行接口由 src/main.cpp 定义通过boxmot::trackers::base::ParseKeyValueArgs解析--key value风格参数。必选参数Usage: botsort_replay --mot-root path --det-emb-root path --detector-name name --reid-name name --sequence name --output path [options]可选参数及其 C 侧默认值与 types.hpp 的Config一致参数默认值语义--track-high-thresh0.6高置信度阈值第一轮关联的检测来源--track-low-thresh0.1低置信度阈值第二轮关联second match的检测来源--new-track-thresh0.7新轨迹激活阈值只有 ≥ 该值的未匹配高置信检测才允许开新轨迹--track-buffer30轨迹丢失缓冲帧数与frame_rate/30共同决定max_time_lost_--match-thresh0.8第一轮线性分配的最大允许距离--proximity-thresh0.5距离门控阈值IoU 距离大于该值相似度低于该值时禁用外观融合--appearance-thresh0.25外观距离门控embedding 距离大于该值时该成本项被置 1--second-match-thresh0.5低置信度第二轮关联的最大允许距离--unconfirmed-match-thresh0.7未确认轨迹与剩余高置信检测关联的阈值--unconfirmed-emb-scale2.0未确认轨迹 embedding 距离的放大除数--cmc-methodecc相机运动补偿方法ecc/sof/none--frame-rate30序列帧率用于计算max_time_lost_--fuse-first-associatefalse是否在第一轮关联中对 IoU 成本做置信度融合--with-reidtrue是否启用 ReID 外观关联--reid-model空.onnxReID 模型路径为空则依赖 embedding 缓存--reid-preprocessresizeReID 预处理模式回放默认resizeC 配置默认resize_pad--conf-threshold0.0检测置信度过滤下限--target-fps0目标帧率抽帧0 表示不抽帧Python 侧process_sequence_cpp会把这些参数与解析后的追踪器配置对齐后逐一拼接botsort.py 的build_replay_command调用单元测试test_process_sequence_cpp_builds_native_command对--reid-name、--reid-preprocess、--track-high-thresh、--cmc-method、--second-match-thresh、--unconfirmed-match-thresh、--unconfirmed-emb-scale、--reid-model等参数值做了精确断言。输出与错误处理执行成功时进程在 stdout 输出一行 JSON 摘要{sequence:..., num_frames:..., track_time_ms:..., kept_frame_ids:[...]}Python 侧parse_summary解析后返回(seq_name, kept_ids, timing)追踪结果由WriteMotLinedata_io.cpp按 MOT 行格式写入--output指定文件当检测行数与 embedding 行数不一致时程序以非零退出码终止并输出错误测试test_native_botsort_rejects_empty_embedding_cache_without_runtime_reid断言 stderr 含 Detection and embedding row counts do not match当--target-fps抽帧时embedding 缓存按帧索引对齐保留测试test_native_botsort_target_fps_keeps_embedding_rows_aligned验证了 30fps 抽到 15fps 后输出帧号恰为[1,3,5]。七、C ABI 与在自有 C 程序中嵌入每个原生追踪器都暴露扁平 C ABIc_api.hpp导出符号以boxmot_botsort_为前缀create传BoxMOTBotSortConfig、destroy、reset、update、last_reid_time_ms/last_reid_preprocess_time_ms/last_reid_process_time_ms/last_reid_postprocess_time_ms、last_error。该头文件即契约可供 C、Rust、Go、Swift、JNI、.NET 等语言通过 FFI 调用产物为tracker_capi.{so,dylib,dll}。update的输入输出均为扁平数组dets 指针 行列数、embs 指针 行列数、图像 raw buffer、输出轨迹缓冲区并附带线程局部错误字符串thread_local std::string g_last_error。若要在自有 C 程序中链接核心目标README 指向的做法与 docs/native/index.md 中的示例一致——对 BoTSORT 而言即为botsort_core目标与botsort::BotSortTracker类add_subdirectory(${BOXMOT_ROOT}/boxmot/native/cpp/trackers/botsort ${CMAKE_BINARY_DIR}/boxmot_botsort) add_executable(my_app main.cpp) target_link_libraries(my_app PRIVATE botsort_core)随后在代码中包含追踪器头并逐帧喂入检测#include botsort/tracker.hpp #include botsort/types.hpp botsort::Config config; botsort::BotSortTracker tracker(config); std::vectorbotsort::Detection detections; // 填充 detection.xyxy或 xywha is_obb、detection.conf、detection.cls、detection.det_ind。 // 可选detection.embedding 直接提供外观特征。 std::vectorbotsort::TrackOutput tracks tracker.Update(detections, frame);BoTSORT 的 ReID 由公共静态目标boxmot_tracker_base中的boxmot::trackers::base::OnnxReIdModel提供链接botsort_core时会传递引入。两种启用外观特征的方式在Detection::embedding字段上直接填充自有模型输出的特征设置cfg.reid_model_path指向 ONNX 模型由内置OnnxReIdModel自动计算 embedding。cfg.with_reid false可完全关闭外观关联。ReID 后端/设备同样受BOXMOT_REID_BACKEND与BOXMOT_REID_DEVICE环境变量控制。注意不要把 AABB 与 OBB 混在同一实例——切换布局前需重建追踪器或调用Reset()。八、追踪主循环源码级解析BotSortTracker::Updatetracker.cpp完整复刻了经典 BoTSORT 的多级关联流水线是本文档所述双阈值 相机补偿 外观融合能力的实现核心布局锁定与帧计数首帧检测锁定 AABB/OBB 模式并创建对应维度的 Kalman 滤波器随后递增frame_count_、清零 ReID 计时按需 ReID检测缺 embedding 时批量推理并写回双阈值分流conf track_high_thresh进入第一轮高置信检测池track_low_thresh conf track_high_thresh进入第二轮低置信检测池状态分离SeparateTracks将轨迹分为unconfirmed与已激活active两组预测与相机运动补偿对active lost池逐一Predict随后cmc_-Apply(image, detections)得到 2×3 仿射变换track-ApplyAffine(linear, translation)将变换施加到轨迹未确认轨迹同样补偿第一轮关联高置信计算 IoU 距离矩阵fuse_first_associate开启时以置信度加权FuseScore启用 ReID 时计算EmbeddingDistancesmooth feature 与当前特征点积并与 IoU 距离取 min超出appearance_thresh/proximity_thresh门控的成本项置 1LinearAssignment(dist_first, match_thresh)求匹配已跟踪轨迹Update、丢失轨迹ReActivate第二轮关联低置信仅对剩余kTracked轨迹与低置信检测做 IoU 线性分配阈值second_match_thresh未匹配者MarkLost未确认轨迹与剩余高置信检测关联阈值unconfirmed_match_threshembedding 距离除以unconfirmed_emb_scale未匹配且conf new_track_thresh的检测Activate成为新轨迹过期回收与去重UpdateTrackStates移除超过max_time_lost_由frame_rate/30 * track_buffer计算的丢失轨迹RemoveDuplicateTracks对活跃与丢失轨迹按 IoU 0.15 且存活时长比较去重输出仅输出已激活is_activated的活跃轨迹逐条构造TrackOutput。PrepareOutput中可以看到 BoTSORT 特有的活跃/丢失/移除三池管理JointTracks按 id 合并去重、SubTracks按 id 差集、RemoveDuplicateTracks共同维护轨迹生命周期。相机运动补偿CMC实现CMC 由CameraMotionCompensator工厂创建CreateCameraMotionCompensatorcmc.cpp支持三种取值ecccv::findTransformECC配准MOTION_TRANSLATION最多 100 次迭代计算掩码排除目标区域相关系数 0.5 或仿射非法时回退单位矩阵sofgoodFeaturesToTrack提取关键点 cv::calcOpticalFlowPyrLK光流跟踪 cv::estimateAffinePartial2DRANSAC估计相似变换要求内点数 ≥ 8 且内点率 ≥ 0.2none/ 空串返回nullptr跳过补偿。两张方法共用Preprocess灰度化 0.15 缩放与GenerateMask中心 96% 区域 抠除检测框逻辑GenerateMask对 OBB 检测使用cv::fillConvexPoly抠除旋转矩形区域。仿射有效性通过IsValidAffine有限值 行列式区间与IsValidSofAffine内点约束双重校验Python 测试test_native_botsort_cmc_rejects_nonfinite_affine_elements验证了 NaN 平移、无穷线性项、奇异变换均被拒绝。RestoreAffineScale将低分辨率估计的仿射还原到原始图像尺度保证轨迹状态变换与 Python 侧transform_obb_kalman_state/transform_aabb_kalman_state的数值一致性。九、验证与回归保障原生 BoTSORT 的 Python 单测集中在 tests/unit/native/trackers/test_native_botsort.py覆盖了本文档涉及的几乎全部契约Replay 命令构建test_process_sequence_cpp_builds_native_command、test_process_sequence_cpp_passes_onnx_reid_model_path、test_process_sequence_cpp_auto_exports_pt_reid_model缓存与 ReID 回退test_process_sequence_cpp_uses_complete_explicit_embedding_cache、test_process_sequence_cpp_keeps_original_reid_cache_key_when_native_model_resolves_to_onnx追踪器语义test_native_botsort_rejects_nonfinite_embeddings、test_native_botsort_tracker_accepts_obb_rows_and_preserves_empty_mode、test_native_botsort_sof_accepts_bgra_live_imagesSOF CMC 下 BGRA 输入C/Python 数值对齐AABB/OBB Kalman 状态与 CMC Jacobian 对齐测试、botsort_obb_cmc_probe二进制端到端 replaytest_native_botsort_target_fps_keeps_embedding_rows_aligned、test_native_botsort_rejects_empty_embedding_cache_without_runtime_reid。这些测试同时扮演了实现事实的权威来源例如空帧布局锁定、AABB/OBB 禁止混用、embedding 非有限值拒绝、抽帧对齐、缓存完整时跳过 ReID 加载等行为均可在测试中找到对应的断言依据。十、常见问题与限制botsort_replay只接受 AABB 缓存 7 列、OBB 缓存 8 列列数与 README 描述一致Python 侧生成缓存时需保证dets与embs行对齐否则 replay 以非零码失败AABB/OBB 不可混用同一原生实例初始化后切换布局会抛错如需切换请重建追踪器或调用Reset()ReID 依赖 ONNXlive/replay 的原生 ReID 推理均要求.onnx模型.pt权重由 Python 包装层自动导出并缓存 ONNXmacOS CI 无缓存 ONNX 时会显式关闭 ReIDper_classTrue暂不支持原生 live 后端需要按类别独立追踪时请使用 Python 后端--tracking-backend cpp只是兼容别名新代码应使用--tracker-backend cpp表达原生追踪器实现这一语义无法自动定位 OpenCV/Eigen3 时显式传-DOpenCV_DIR与-DEigen3_DIROpenCV 组件依赖为calib3d core dnn imgcodecs imgproc videoCMakeLists.txt。综上原生 BoTSORT 在 BoxMOT 中承担缓存回放评估与在线原生推理双角色完整支持 AABB/OBB 双布局、原生 ONNX ReID、ECC/SOF 相机运动补偿与可复用的 C ABI。开发者既可以通过--tracker-backend cpp一行切换后端也可以链接botsort_core目标将 BoTSORT 直接嵌入自有 C 管线。【免费下载链接】boxmotBoxMOT: Pluggable Python and C SOTA multi-object tracking modules with support for axis-aligned and oriented bounding boxes项目地址: https://gitcode.com/GitHub_Trending/bo/boxmot创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表