From f2374fc5caf9755ab6f5a2c8c252bc4ec30c3863 Mon Sep 17 00:00:00 2001 From: Nuzhny007 Date: Tue, 4 Nov 2025 22:25:26 +0300 Subject: [PATCH 1/8] Build with MSVC --- botsort/CMakeLists.txt | 32 +++- botsort/include/DataType.h | 4 +- botsort/include/ReID.h | 24 +-- .../TensorRT_InferenceEngine.h | 11 +- botsort/include/profiler.h | 6 + botsort/src/KalmanFilter.cpp | 2 +- botsort/src/KalmanFilterAccBased.cpp | 2 +- botsort/src/ReID.cpp | 156 +++++++++++++----- .../TensorRT_InferenceEngine.cpp | 11 +- examples/CMakeLists.txt | 5 + examples/botsort_tracking_example.cpp | 2 +- 11 files changed, 177 insertions(+), 78 deletions(-) diff --git a/botsort/CMakeLists.txt b/botsort/CMakeLists.txt index f64966a..3b51b59 100644 --- a/botsort/CMakeLists.txt +++ b/botsort/CMakeLists.txt @@ -17,7 +17,19 @@ endif() file(GLOB_RECURSE SOURCES "${PROJECT_SOURCE_DIR}/src/*.cpp") # Create library -add_library(${PROJECT_NAME} SHARED ${SOURCES}) +if(MSVC) + add_library(${PROJECT_NAME} STATIC ${SOURCES}) +else() + add_library(${PROJECT_NAME} SHARED ${SOURCES}) +endif() + +if(MSVC) + target_link_options(${PROJECT_NAME} PRIVATE "/NODEFAULTLIB:LIBCMT") + #target_link_options(${PROJECT_NAME} PRIVATE "/NODEFAULTLIB:LIBCMTD") + #target_link_options(${PROJECT_NAME} PRIVATE "/NODEFAULTLIB:MSVCRTD") + target_link_libraries(${PROJECT_NAME} ws2_32) +endif() + # Set include directories target_include_directories(${PROJECT_NAME} PUBLIC @@ -49,10 +61,24 @@ else() message(STATUS "CUDA version ${CUDA_VERSION_STRING} found") target_include_directories(${PROJECT_NAME} PUBLIC ${CUDA_INCLUDE_DIRS}) + find_library(TRT_NVINFER NAMES nvinfer PATHS ${TENSORRT_DIR} PATH_SUFFIXES lib lib64) + find_library(TRT_NVONNXPARSER NAMES nvonnxparser PATHS ${TENSORRT_DIR} PATH_SUFFIXES lib lib64) + find_path(TRT_INCLUDE_DIR NAMES NvInfer.h PATHS ${TENSORRT_DIR} PATH_SUFFIXES include) + + if (NOT TRT_NVINFER OR NOT TRT_NVONNXPARSER OR NOT TRT_INCLUDE_DIR) + message(FATAL_ERROR "Not all TensorRT was found. Check TENSORRT_DIR.") + else() + message("TRT_INCLUDE_DIR: ${TRT_INCLUDE_DIR}, TRT_NVINFER: ${TRT_NVINFER}, TRT_NVONNXPARSER: ${TRT_NVONNXPARSER}") + endif() + + target_include_directories(${PROJECT_NAME} PRIVATE ${TRT_INCLUDE_DIR}) + target_link_libraries(${PROJECT_NAME} ${TRT_NVINFER}) + target_link_libraries(${PROJECT_NAME} ${TRT_NVONNXPARSER}) + target_sources(${PROJECT_NAME} PRIVATE ${PROJECT_SOURCE_DIR}/src/TRT_InferenceEngine/TensorRT_InferenceEngine.cpp ${PROJECT_SOURCE_DIR}/src/ReID.cpp) - target_link_libraries(${PROJECT_NAME} ${CUDA_LIBRARIES} nvonnxparser nvinfer) + target_link_libraries(${PROJECT_NAME} ${CUDA_LIBRARIES}) endif() if(CMAKE_BUILD_TYPE MATCHES Debug) @@ -64,4 +90,4 @@ if(CMAKE_BUILD_TYPE MATCHES Debug) else() add_definitions(-DPROFILE=1) add_compile_options(-O3) -endif() \ No newline at end of file +endif() diff --git a/botsort/include/DataType.h b/botsort/include/DataType.h index 18ec1ae..b638229 100644 --- a/botsort/include/DataType.h +++ b/botsort/include/DataType.h @@ -1,8 +1,8 @@ #pragma once #include -#include -#include +#include +#include #include #include #include diff --git a/botsort/include/ReID.h b/botsort/include/ReID.h index 9543e32..5f242fa 100644 --- a/botsort/include/ReID.h +++ b/botsort/include/ReID.h @@ -4,32 +4,20 @@ #include "DataType.h" #include "ReIDParams.h" -#include "TRT_InferenceEngine/TensorRT_InferenceEngine.h" class ReIDModel { public: ReIDModel(const ReIDParams ¶ms, const std::string &onnx_model_path); - ~ReIDModel() = default; + ~ReIDModel(); - void pre_process(cv::Mat &image); FeatureVector extract_features(cv::Mat &image); - const std::string &get_distance_metric() const - { - return _distance_metric; - } + const std::string &get_distance_metric() const noexcept; -private: - void _load_params_from_config(const ReIDParams ¶ms); + class InferenceImpl; - -private: - inference_backend::TRTOptimizerParams _model_optimization_params; - std::unique_ptr - _trt_inference_engine; - u_int8_t _trt_logging_level; - cv::Size _input_size; - - std::string _onnx_model_path, _distance_metric; +private: + + InferenceImpl *_inference_impl = nullptr; }; \ No newline at end of file diff --git a/botsort/include/TRT_InferenceEngine/TensorRT_InferenceEngine.h b/botsort/include/TRT_InferenceEngine/TensorRT_InferenceEngine.h index f253a2f..781304c 100644 --- a/botsort/include/TRT_InferenceEngine/TensorRT_InferenceEngine.h +++ b/botsort/include/TRT_InferenceEngine/TensorRT_InferenceEngine.h @@ -1,7 +1,7 @@ #pragma once -#include -#include +#include +#include #include #include #include @@ -10,7 +10,10 @@ #include #include + +#ifndef _MSC_VER #include +#endif #include #include @@ -116,7 +119,7 @@ class TensorRTInferenceEngine public: TensorRTInferenceEngine(TRTOptimizerParams &optimization_params, - u_int8_t logging_level); + int8_t logging_level); ~TensorRTInferenceEngine(); bool load_model(const std::string &onnx_model_path); @@ -133,7 +136,7 @@ class TensorRTInferenceEngine // Non-const methods void _set_optimization_params(const TRTOptimizerParams ¶ms); - void _init_TRT_logger(u_int8_t logging_level); + void _init_TRT_logger(int8_t logging_level); void _build_engine(const std::string &onnx_model_path); bool _deserialize_engine(const std::string &engine_path); diff --git a/botsort/include/profiler.h b/botsort/include/profiler.h index bcb8a31..bb497dd 100644 --- a/botsort/include/profiler.h +++ b/botsort/include/profiler.h @@ -9,7 +9,13 @@ #if PROFILE #define PROFILE_SCOPE(name) Profiler timer##__LINE__(name) + +#ifdef _MSC_VER +#define PROFILE_FUNCTION() PROFILE_SCOPE(__FUNCSIG__) +#else #define PROFILE_FUNCTION() PROFILE_SCOPE(__PRETTY_FUNCTION__) +#endif + #else #define PROFILE_SCOPE(name) #define PROFILE_FUNCTION() diff --git a/botsort/src/KalmanFilter.cpp b/botsort/src/KalmanFilter.cpp index 013e269..ff75069 100644 --- a/botsort/src/KalmanFilter.cpp +++ b/botsort/src/KalmanFilter.cpp @@ -1,6 +1,6 @@ #include "KalmanFilter.h" -#include +#include namespace bot_kalman { diff --git a/botsort/src/KalmanFilterAccBased.cpp b/botsort/src/KalmanFilterAccBased.cpp index fc2df24..f1dc5a8 100644 --- a/botsort/src/KalmanFilterAccBased.cpp +++ b/botsort/src/KalmanFilterAccBased.cpp @@ -1,6 +1,6 @@ #include "KalmanFilterAccBased.h" -#include +#include namespace acc_kalman { diff --git a/botsort/src/ReID.cpp b/botsort/src/ReID.cpp index 6b81919..f1915ae 100644 --- a/botsort/src/ReID.cpp +++ b/botsort/src/ReID.cpp @@ -1,19 +1,113 @@ #include "ReID.h" #include "INIReader.h" +#include "TRT_InferenceEngine/TensorRT_InferenceEngine.h" +/// +class ReIDModel::InferenceImpl +{ +public: + InferenceImpl() = default; + virtual ~InferenceImpl() = default; + + virtual bool Init(const ReIDParams ¶ms, const std::string &onnx_model_path) = 0; + + virtual const std::string &get_distance_metric() const noexcept = 0; + virtual FeatureVector extract_features(cv::Mat &image_patch) = 0; +}; + +/// +class ReIDInferenceImpl final : public ReIDModel::InferenceImpl +{ +public: + bool Init(const ReIDParams& params, const std::string& onnx_model_path) override + { + _onnx_model_path = onnx_model_path; + + _load_params_from_config(params); + + _trt_inference_engine = + std::make_unique( + _model_optimization_params, _trt_logging_level); + + auto res = _trt_inference_engine->load_model(onnx_model_path); + return res; + } + + FeatureVector extract_features(cv::Mat &image_patch) override + { + pre_process(image_patch); + std::vector> output = + _trt_inference_engine->forward(image_patch); + + // TODO: Clean this up + FeatureVector feature_vector = FeatureVector::Zero(1, FEATURE_DIM); + for (int i = 0; i < FEATURE_DIM; i++) + { + feature_vector(0, i) = output[0][i]; + } + return feature_vector; + } + + const std::string &get_distance_metric() const noexcept override + { + return _distance_metric; + } + +private: + inference_backend::TRTOptimizerParams _model_optimization_params; + std::unique_ptr _trt_inference_engine; + + int8_t _trt_logging_level; + cv::Size _input_size; + + std::string _onnx_model_path; + std::string _distance_metric; + + + void _load_params_from_config(const ReIDParams ¶ms) + { + _distance_metric = params.distance_metric; + _trt_logging_level = params.trt_logging_level; + _model_optimization_params.batch_size = + static_cast(params.batch_size); + _model_optimization_params.fp16 = params.enable_fp16; + _model_optimization_params.tf32 = params.enable_tf32; + _model_optimization_params.input_layer_name = params.input_layer_name; + + std::cout << "Trying to get input dims" << std::endl; + const auto &input_dims = params.input_layer_dimensions; + _input_size = cv::Size(input_dims[3], input_dims[2]); + + std::cout << "Read input dims" << std::endl; + std::cout << "Input dims: " << input_dims[0] << " " << input_dims[1] + << " " << input_dims[2] << " " << input_dims[3] << std::endl; + + _model_optimization_params.input_dims = nvinfer1::Dims4{ + input_dims[0], input_dims[1], input_dims[2], input_dims[3]}; + _model_optimization_params.swapRB = params.swap_rb; + + _model_optimization_params.output_layer_names = + params.output_layer_names; + } + + void pre_process(cv::Mat &image) + { + cv::resize(image, image, _input_size); + if (_model_optimization_params.swapRB) + cv::cvtColor(image, image, cv::COLOR_BGR2RGB); + } +}; + +/// ReIDModel::ReIDModel(const ReIDParams ¶ms, const std::string &onnx_model_path) { std::cout << "Initializing ReID model" << std::endl; - _load_params_from_config(params); - _onnx_model_path = onnx_model_path; - _trt_inference_engine = - std::make_unique( - _model_optimization_params, _trt_logging_level); + _inference_impl = new ReIDInferenceImpl(); - bool net_initialized = _trt_inference_engine->load_model(_onnx_model_path); + bool net_initialized = _inference_impl->Init(params, onnx_model_path); if (!net_initialized) { std::cout << "Failed to initialize ReID model" << std::endl; @@ -21,49 +115,21 @@ ReIDModel::ReIDModel(const ReIDParams ¶ms, } } - -FeatureVector ReIDModel::extract_features(cv::Mat &image_patch) +/// +ReIDModel::~ReIDModel() { - pre_process(image_patch); - std::vector> output = - _trt_inference_engine->forward(image_patch); - - // TODO: Clean this up - FeatureVector feature_vector = FeatureVector::Zero(1, FEATURE_DIM); - for (int i = 0; i < FEATURE_DIM; i++) - feature_vector(0, i) = output[0][i]; - - return feature_vector; + if (_inference_impl) + delete _inference_impl; } - -void ReIDModel::pre_process(cv::Mat &image) +/// +FeatureVector ReIDModel::extract_features(cv::Mat &image_patch) { - cv::resize(image, image, _input_size); - if (_model_optimization_params.swapRB) - cv::cvtColor(image, image, cv::COLOR_BGR2RGB); + return _inference_impl->extract_features(image_patch); } -void ReIDModel::_load_params_from_config(const ReIDParams ¶ms) +/// +const std::string& ReIDModel::get_distance_metric() const noexcept { - _distance_metric = params.distance_metric; - _trt_logging_level = params.trt_logging_level; - _model_optimization_params.batch_size = static_cast(params.batch_size); - _model_optimization_params.fp16 = params.enable_fp16; - _model_optimization_params.tf32 = params.enable_tf32; - _model_optimization_params.input_layer_name = params.input_layer_name; - - std::cout << "Trying to get input dims" << std::endl; - const auto &input_dims = params.input_layer_dimensions; - _input_size = cv::Size(input_dims[3], input_dims[2]); - - std::cout << "Read input dims" << std::endl; - std::cout << "Input dims: " << input_dims[0] << " " << input_dims[1] << " " - << input_dims[2] << " " << input_dims[3] << std::endl; - - _model_optimization_params.input_dims = nvinfer1::Dims4{ - input_dims[0], input_dims[1], input_dims[2], input_dims[3]}; - _model_optimization_params.swapRB = params.swap_rb; - - _model_optimization_params.output_layer_names = params.output_layer_names; -} \ No newline at end of file + return _inference_impl->get_distance_metric(); +} diff --git a/botsort/src/TRT_InferenceEngine/TensorRT_InferenceEngine.cpp b/botsort/src/TRT_InferenceEngine/TensorRT_InferenceEngine.cpp index fb8ba9a..da39ed3 100644 --- a/botsort/src/TRT_InferenceEngine/TensorRT_InferenceEngine.cpp +++ b/botsort/src/TRT_InferenceEngine/TensorRT_InferenceEngine.cpp @@ -2,6 +2,11 @@ #include +#ifdef _MSC_VER +#include +#endif + + namespace { std::string get_devicename_from_deviceid(int device_id) @@ -20,7 +25,7 @@ std::string get_devicename_from_deviceid(int device_id) }// namespace inference_backend::TensorRTInferenceEngine::TensorRTInferenceEngine( - TRTOptimizerParams &optimization_params, u_int8_t logging_level) + TRTOptimizerParams &optimization_params, int8_t logging_level) { _set_optimization_params(optimization_params); _init_TRT_logger(logging_level); @@ -44,7 +49,7 @@ void inference_backend::TensorRTInferenceEngine::_set_optimization_params( void inference_backend::TensorRTInferenceEngine::_init_TRT_logger( - u_int8_t logging_level) + int8_t logging_level) { _logger = std::make_unique( static_cast(logging_level)); @@ -257,7 +262,7 @@ void inference_backend::TensorRTInferenceEngine::_allocate_buffers() #endif { _output_dims.emplace_back(dims); - _output_idx.emplace_back(i); + _output_idx.emplace_back(static_cast(i)); ++output_idx; #if NVINFER_MAJOR == 8 && NVINFER_MINOR <= 5 diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 504f1c0..fde5f22 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -16,6 +16,11 @@ endif() # Define the executable add_executable(${PROJECT_NAME} botsort_tracking_example.cpp) +if(MSVC) + target_link_options(${PROJECT_NAME} PRIVATE "/NODEFAULTLIB:LIBCMT") +endif() + + # Find and link OpenCV find_package(OpenCV REQUIRED) target_include_directories(${PROJECT_NAME} PUBLIC ${OpenCV_INCLUDE_DIRS}) diff --git a/examples/botsort_tracking_example.cpp b/examples/botsort_tracking_example.cpp index f3a6743..e5a3bd0 100644 --- a/examples/botsort_tracking_example.cpp +++ b/examples/botsort_tracking_example.cpp @@ -326,7 +326,7 @@ int main(int argc, char **argv) // Read filenames in labels dir for (const auto &entry: std::filesystem::directory_iterator(source)) { - image_filepaths.push_back(entry.path()); + image_filepaths.push_back(entry.path().string()); } std::sort(image_filepaths.begin(), image_filepaths.end()); } From d7e6a3f948e3c981d53cabf393779060aa3ac0b8 Mon Sep 17 00:00:00 2001 From: Nuzhny007 Date: Wed, 5 Nov 2025 00:44:19 +0300 Subject: [PATCH 2/8] Remove boost from dependences --- botsort/CMakeLists.txt | 5 ---- .../TensorRT_InferenceEngine.h | 3 -- .../TensorRT_InferenceEngine.cpp | 29 +++++++++---------- 3 files changed, 13 insertions(+), 24 deletions(-) diff --git a/botsort/CMakeLists.txt b/botsort/CMakeLists.txt index 3b51b59..619fb5a 100644 --- a/botsort/CMakeLists.txt +++ b/botsort/CMakeLists.txt @@ -47,11 +47,6 @@ find_package(Eigen3 REQUIRED) target_include_directories(${PROJECT_NAME} PUBLIC ${EIGEN3_INCLUDE_DIR}) target_link_libraries(${PROJECT_NAME} Eigen3::Eigen) -# Find and link Boost -find_package(Boost REQUIRED COMPONENTS filesystem) -target_include_directories(${PROJECT_NAME} PUBLIC ${Boost_INCLUDE_DIRS}) -target_link_libraries(${PROJECT_NAME} ${Boost_LIBRARIES}) - # Find and link CUDA find_package(CUDA QUIET) diff --git a/botsort/include/TRT_InferenceEngine/TensorRT_InferenceEngine.h b/botsort/include/TRT_InferenceEngine/TensorRT_InferenceEngine.h index 781304c..e9d7230 100644 --- a/botsort/include/TRT_InferenceEngine/TensorRT_InferenceEngine.h +++ b/botsort/include/TRT_InferenceEngine/TensorRT_InferenceEngine.h @@ -15,7 +15,6 @@ #include #endif -#include #include #include "TRT_Logger.h" @@ -129,11 +128,9 @@ class TensorRTInferenceEngine private: // Const methods std::string get_engine_path(const std::string &onnx_model_path) const; - bool file_exists(const std::string &name) const; size_t get_size_by_dims(const nvinfer1::Dims &dims, int element_size = 1) const; - // Non-const methods void _set_optimization_params(const TRTOptimizerParams ¶ms); void _init_TRT_logger(int8_t logging_level); diff --git a/botsort/src/TRT_InferenceEngine/TensorRT_InferenceEngine.cpp b/botsort/src/TRT_InferenceEngine/TensorRT_InferenceEngine.cpp index da39ed3..7b669e2 100644 --- a/botsort/src/TRT_InferenceEngine/TensorRT_InferenceEngine.cpp +++ b/botsort/src/TRT_InferenceEngine/TensorRT_InferenceEngine.cpp @@ -1,5 +1,7 @@ #include "TRT_InferenceEngine/TensorRT_InferenceEngine.h" +#include + #include #ifdef _MSC_VER @@ -65,7 +67,7 @@ bool inference_backend::TensorRTInferenceEngine::load_model( .c_str()); // Check if ONNX model exists - if (!file_exists(onnx_model_path)) + if (!std::filesystem::exists(onnx_model_path)) { _logger->log(nvinfer1::ILogger::Severity::kERROR, std::string("ONNX model not found at path: ") @@ -91,7 +93,7 @@ bool inference_backend::TensorRTInferenceEngine::load_model( // Check if engine exists, if not build it std::string engine_path = get_engine_path(onnx_model_path); - if (!file_exists(engine_path)) + if (!std::filesystem::exists(engine_path)) { _logger->log(nvinfer1::ILogger::Severity::kINFO, std::string("Engine not found at path: ") @@ -128,7 +130,7 @@ bool inference_backend::TensorRTInferenceEngine::load_model( } _logger->log(nvinfer1::ILogger::Severity::kERROR, - std::string("Failed to load engine").c_str()); + (std::string("Failed to load engine: ") + engine_path).c_str()); return false; } @@ -138,14 +140,17 @@ std::string inference_backend::TensorRTInferenceEngine::get_engine_path( { // Parent director + model name std::string engine_path = - boost::filesystem::path(onnx_model_path).parent_path().string() + - "/" + boost::filesystem::path(onnx_model_path).stem().string(); + (std::filesystem::path(onnx_model_path).parent_path() / + std::filesystem::path(onnx_model_path).stem()).string(); // Hostname char hostname[1024]; gethostname(hostname, sizeof(hostname)); +#if 0 std::string suffix(hostname); - +#else + std::string suffix("localhost"); +#endif suffix.append("_GPU_" + get_devicename_from_deviceid(_optimization_params.gpu_id)); @@ -174,14 +179,6 @@ std::string inference_backend::TensorRTInferenceEngine::get_engine_path( return engine_path; } - -bool inference_backend::TensorRTInferenceEngine::file_exists( - const std::string &name) const -{ - return boost::filesystem::exists(name); -} - - size_t inference_backend::TensorRTInferenceEngine::get_size_by_dims( const nvinfer1::Dims &dims, int element_size) const { @@ -302,7 +299,7 @@ bool inference_backend::TensorRTInferenceEngine::_deserialize_engine( if (!engine_file) { _logger->log(nvinfer1::ILogger::Severity::kERROR, - std::string("Failed to open engine file").c_str()); + (std::string("Failed to open engine file: ") + engine_path).c_str()); return false; } @@ -431,7 +428,7 @@ void inference_backend::TensorRTInferenceEngine::_build_engine( if (!engine_file) { _logger->log(nvinfer1::ILogger::Severity::kERROR, - std::string("Failed to open engine file").c_str()); + (std::string("Failed to open engine file: ") + engine_path).c_str()); return; } From fe843d1953c693cc3583d0218ef7bc3819d1fba7 Mon Sep 17 00:00:00 2001 From: Nuzhny007 Date: Wed, 5 Nov 2025 18:39:55 +0300 Subject: [PATCH 3/8] Apply C++ style lapjv --- botsort/include/lapjv.h | 81 +------ botsort/src/lapjv.cpp | 516 +++++++++++++++++++--------------------- botsort/src/utils.cpp | 31 +-- 3 files changed, 255 insertions(+), 373 deletions(-) diff --git a/botsort/include/lapjv.h b/botsort/include/lapjv.h index 52bd6af..2c12580 100644 --- a/botsort/include/lapjv.h +++ b/botsort/include/lapjv.h @@ -1,79 +1,8 @@ -// Directly taken from: https://github.com/ifzhang/ByteTrack/blob/main/deploy/ncnn/cpp/include/lapjv.h +#pragma once -#ifndef LAPJV_H -#define LAPJV_H +#include +#include -#define LARGE 1000000 +typedef float lapjv_t; -#if !defined TRUE -#define TRUE 1 -#endif -#if !defined FALSE -#define FALSE 0 -#endif - -#define NEW(x, t, n) \ - if ((x = (t *) malloc(sizeof(t) * (n))) == 0) { return -1; } -#define FREE(x) \ - if (x != 0) \ - { \ - free(x); \ - x = 0; \ - } -#define SWAP_INDICES(a, b) \ - { \ - int_t _temp_index = a; \ - a = b; \ - b = _temp_index; \ - } - -#if 0 -#include -#define ASSERT(cond) assert(cond) -#define PRINTF(fmt, ...) printf(fmt, ##__VA_ARGS__) -#define PRINT_COST_ARRAY(a, n) \ - while (1) \ - { \ - printf(#a " = ["); \ - if ((n) > 0) \ - { \ - printf("%f", (a)[0]); \ - for (uint_t j = 1; j < n; j++) { printf(", %f", (a)[j]); } \ - } \ - printf("]\n"); \ - break; \ - } -#define PRINT_INDEX_ARRAY(a, n) \ - while (1) \ - { \ - printf(#a " = ["); \ - if ((n) > 0) \ - { \ - printf("%d", (a)[0]); \ - for (uint_t j = 1; j < n; j++) { printf(", %d", (a)[j]); } \ - } \ - printf("]\n"); \ - break; \ - } -#else -#define ASSERT(cond) -#define PRINTF(fmt, ...) -#define PRINT_COST_ARRAY(a, n) -#define PRINT_INDEX_ARRAY(a, n) -#endif - - -typedef signed int int_t; -typedef unsigned int uint_t; -typedef double cost_t; -typedef char boolean; -typedef enum fp_t -{ - FP_1 = 1, - FP_2 = 2, - FP_DYNAMIC = 3 -} fp_t; - -extern int_t lapjv_internal(const uint_t n, cost_t *cost[], int_t *x, int_t *y); - -#endif// LAPJV_H \ No newline at end of file +int lapjv_internal(const size_t n, const std::vector>& cost, std::vector& x, std::vector& y); diff --git a/botsort/src/lapjv.cpp b/botsort/src/lapjv.cpp index 9e2168f..f1e8f57 100644 --- a/botsort/src/lapjv.cpp +++ b/botsort/src/lapjv.cpp @@ -1,347 +1,315 @@ -// Directly taken from: https://github.com/ifzhang/ByteTrack/blob/main/deploy/ncnn/cpp/src/lapjv.cpp - #include "lapjv.h" -#include - -#include -#include +#include +#include +#include +#include +#include -/** Column-reduction and reduction transfer for a dense cost matrix. - */ -int_t _ccrrt_dense(const uint_t n, cost_t *cost[], int_t *free_rows, int_t *x, - int_t *y, cost_t *v) +namespace { - int_t n_free_rows; - boolean *unique; + constexpr size_t LARGE = std::numeric_limits::max(); - for (uint_t i = 0; i < n; i++) - { - x[i] = -1; - v[i] = LARGE; - y[i] = 0; - } - for (uint_t i = 0; i < n; i++) + enum class fp_t { + FP_1 = 1, + FP_2 = 2, + FP_DYNAMIC = 3, + }; + + /** Column-reduction and reduction transfer for a dense cost matrix. + */ + int _ccrrt_dense(const size_t n, const std::vector>& cost, + std::vector& free_rows, std::vector& x, std::vector& y, std::vector& v) { - for (uint_t j = 0; j < n; j++) + for (size_t i = 0; i < n; i++) { - const cost_t c = cost[i][j]; - if (c < v[j]) + for (size_t j = 0; j < n; j++) { - v[j] = c; - y[j] = i; + const lapjv_t c = cost[i][j]; + if (c < v[j]) { + v[j] = c; + y[j] = i; + } } - PRINTF("i=%d, j=%d, c[i,j]=%f, v[j]=%f y[j]=%d\n", i, j, c, v[j], - y[j]); } - } - PRINT_COST_ARRAY(v, n); - PRINT_INDEX_ARRAY(y, n); - NEW(unique, boolean, n); - memset(unique, TRUE, n); - { - int_t j = n; - do { - j--; - const int_t i = y[j]; - if (x[i] < 0) { x[i] = j; } - else - { - unique[i] = FALSE; - y[j] = -1; - } - } while (j > 0); - } - n_free_rows = 0; - for (uint_t i = 0; i < n; i++) - { - if (x[i] < 0) { free_rows[n_free_rows++] = i; } - else if (unique[i]) + + std::vector unique(n, true); { - const int_t j = x[i]; - cost_t min = LARGE; - for (uint_t j2 = 0; j2 < n; j2++) - { - if (j2 == (uint_t) j) { continue; } - const cost_t c = cost[i][j2] - v[j2]; - if (c < min) { min = c; } + int j = n; + do { + j--; + const int i = y[j]; + if (x[i] < 0) { + x[i] = j; + } + else { + unique[i] = false; + y[j] = -1; + } + } while (j > 0); + } + int n_free_rows = 0; + for (size_t i = 0; i < n; i++) + { + if (x[i] < 0) { + free_rows[n_free_rows++] = i; + } + else if (unique[i]) { + const int j = x[i]; + lapjv_t min = LARGE; + for (size_t j2 = 0; j2 < n; j2++) + { + if (j2 == (size_t)j) + continue; + + const lapjv_t c = cost[i][j2] - v[j2]; + if (c < min) + min = c; + } + v[j] -= min; } - PRINTF("v[%d] = %f - %f\n", j, v[j], min); - v[j] -= min; } + return n_free_rows; } - FREE(unique); - return n_free_rows; -} -/** Augmenting row reduction for a dense cost matrix. - */ -int_t _carr_dense(const uint_t n, cost_t *cost[], const uint_t n_free_rows, - int_t *free_rows, int_t *x, int_t *y, cost_t *v) -{ - uint_t current = 0; - int_t new_free_rows = 0; - uint_t rr_cnt = 0; - PRINT_INDEX_ARRAY(x, n); - PRINT_INDEX_ARRAY(y, n); - PRINT_COST_ARRAY(v, n); - PRINT_INDEX_ARRAY(free_rows, n_free_rows); - while (current < n_free_rows) + /** Augmenting row reduction for a dense cost matrix. + */ + int _carr_dense( + const size_t n, const std::vector>& cost, + const size_t n_free_rows, + std::vector& free_rows, std::vector& x, std::vector& y, std::vector& v) { - int_t i0; - int_t j1, j2; - cost_t v1, v2, v1_new; - boolean v1_lowers; - - rr_cnt++; - PRINTF("current = %d rr_cnt = %d\n", current, rr_cnt); - const int_t free_i = free_rows[current++]; - j1 = 0; - v1 = cost[free_i][0] - v[0]; - j2 = -1; - v2 = LARGE; - for (uint_t j = 1; j < n; j++) + size_t current = 0; + int new_free_rows = 0; + size_t rr_cnt = 0; + while (current < n_free_rows) { - PRINTF("%d = %f %d = %f\n", j1, v1, j2, v2); - const cost_t c = cost[free_i][j] - v[j]; - if (c < v2) - { - if (c >= v1) + rr_cnt++; + const int free_i = free_rows[current++]; + int j1 = 0; + lapjv_t v1 = cost[free_i][0] - v[0]; + int j2 = -1; + lapjv_t v2 = LARGE; + for (size_t j = 1; j < n; j++) { + const lapjv_t c = cost[free_i][j] - v[j]; + if (c < v2) { - v2 = c; - j2 = j; - } - else - { - v2 = v1; - v1 = c; - j2 = j1; - j1 = j; + if (c >= v1) { + v2 = c; + j2 = j; + } + else { + v2 = v1; + v1 = c; + j2 = j1; + j1 = j; + } } } - } - i0 = y[j1]; - v1_new = v[j1] - (v2 - v1); - v1_lowers = v1_new < v[j1]; - PRINTF("%d %d 1=%d,%f 2=%d,%f v1'=%f(%d,%g) \n", free_i, i0, j1, v1, j2, - v2, v1_new, v1_lowers, v[j1] - v1_new); - if (rr_cnt < current * n) - { - if (v1_lowers) { v[j1] = v1_new; } - else if (i0 >= 0 && j2 >= 0) + int i0 = y[j1]; + lapjv_t v1_new = v[j1] - (v2 - v1); + bool v1_lowers = v1_new < v[j1]; + if (rr_cnt < current * n) { - j1 = j2; - i0 = y[j2]; + if (v1_lowers) { + v[j1] = v1_new; + } + else if (i0 >= 0 && j2 >= 0) { + j1 = j2; + i0 = y[j2]; + } + if (i0 >= 0) + { + if (v1_lowers) + free_rows[--current] = i0; + else + free_rows[new_free_rows++] = i0; + } } - if (i0 >= 0) - { - if (v1_lowers) { free_rows[--current] = i0; } - else { free_rows[new_free_rows++] = i0; } + else { + if (i0 >= 0) + free_rows[new_free_rows++] = i0; } + x[free_i] = j1; + y[j1] = free_i; } - else - { - PRINTF("rr_cnt=%d >= %d (current=%d * n=%d)\n", rr_cnt, current * n, - current, n); - if (i0 >= 0) { free_rows[new_free_rows++] = i0; } - } - x[free_i] = j1; - y[j1] = free_i; + return new_free_rows; } - return new_free_rows; -} -/** Find columns with minimum d[j] and put them on the SCAN list. - */ -uint_t _find_dense(const uint_t n, uint_t lo, cost_t *d, int_t *cols, int_t *y) -{ - uint_t hi = lo + 1; - cost_t mind = d[cols[lo]]; - for (uint_t k = hi; k < n; k++) + /** Find columns with minimum d[j] and put them on the SCAN list. + */ + size_t _find_dense(const size_t n, size_t lo, const std::vector& d, std::vector& cols) { - int_t j = cols[k]; - if (d[j] <= mind) + size_t hi = lo + 1; + lapjv_t mind = d[cols[lo]]; + for (size_t k = hi; k < n; k++) { - if (d[j] < mind) - { - hi = lo; - mind = d[j]; + int j = cols[k]; + if (d[j] <= mind) { + if (d[j] < mind) { + hi = lo; + mind = d[j]; + } + cols[k] = cols[hi]; + cols[hi++] = j; } - cols[k] = cols[hi]; - cols[hi++] = j; } + return hi; } - return hi; -} - -// Scan all columns in TODO starting from arbitrary column in SCAN -// and try to decrease d of the TODO columns using the SCAN column. -int_t _scan_dense(const uint_t n, cost_t *cost[], uint_t *plo, uint_t *phi, - cost_t *d, int_t *cols, int_t *pred, int_t *y, cost_t *v) -{ - uint_t lo = *plo; - uint_t hi = *phi; - cost_t h, cred_ij; - while (lo != hi) + // Scan all columns in TODO starting from arbitrary column in SCAN + // and try to decrease d of the TODO columns using the SCAN column. + int _scan_dense(const size_t n, const std::vector>& cost, + size_t* plo, size_t* phi, + std::vector& d, std::vector& cols, std::vector& pred, + const std::vector& y, const std::vector& v) { - int_t j = cols[lo++]; - const int_t i = y[j]; - const cost_t mind = d[j]; - h = cost[i][j] - v[j] - mind; - PRINTF("i=%d j=%d h=%f\n", i, j, h); - // For all columns in TODO - for (uint_t k = hi; k < n; k++) + size_t lo = *plo; + size_t hi = *phi; + + while (lo != hi) { - j = cols[k]; - cred_ij = cost[i][j] - v[j] - h; - if (cred_ij < d[j]) + int j = cols[lo++]; + const int i = y[j]; + const lapjv_t mind = d[j]; + lapjv_t h = cost[i][j] - v[j] - mind; + // For all columns in TODO + for (size_t k = hi; k < n; k++) { - d[j] = cred_ij; - pred[j] = i; - if (cred_ij == mind) + j = cols[k]; + lapjv_t cred_ij = cost[i][j] - v[j] - h; + if (cred_ij < d[j]) { - if (y[j] < 0) { return j; } - cols[k] = cols[hi]; - cols[hi++] = j; + d[j] = cred_ij; + pred[j] = i; + if (cred_ij == mind) + { + if (y[j] < 0) + return j; + + cols[k] = cols[hi]; + cols[hi++] = j; + } } } } + *plo = lo; + *phi = hi; + return -1; } - *plo = lo; - *phi = hi; - return -1; -} -/** Single iteration of modified Dijkstra shortest path algorithm as explained in the JV paper. - * - * This is a dense matrix version. - * - * \return The closest free column index. - */ -int_t find_path_dense(const uint_t n, cost_t *cost[], const int_t start_i, - int_t *y, cost_t *v, int_t *pred) -{ - uint_t lo = 0, hi = 0; - int_t final_j = -1; - uint_t n_ready = 0; - int_t *cols; - cost_t *d; + /** Single iteration of modified Dijkstra shortest path algorithm as explained in the JV paper. + * + * This is a dense matrix version. + * + * \return The closest free column index. + */ + int find_path_dense( + const size_t n, const std::vector>& cost, + const int start_i, + std::vector& y, std::vector& v, + std::vector& pred) + { + size_t lo = 0, hi = 0; + int final_j = -1; + size_t n_ready = 0; - NEW(cols, int_t, n); - NEW(d, cost_t, n); + std::vector cols(n); + std::vector d(n); - for (uint_t i = 0; i < n; i++) - { - cols[i] = i; - pred[i] = start_i; - d[i] = cost[start_i][i] - v[i]; - } - PRINT_COST_ARRAY(d, n); - while (final_j == -1) - { - // No columns left on the SCAN list. - if (lo == hi) + for (size_t i = 0; i < n; i++) { - PRINTF("%d..%d -> find\n", lo, hi); - n_ready = lo; - hi = _find_dense(n, lo, d, cols, y); - PRINTF("check %d..%d\n", lo, hi); - PRINT_INDEX_ARRAY(cols, n); - for (uint_t k = lo; k < hi; k++) - { - const int_t j = cols[k]; - if (y[j] < 0) { final_j = j; } - } + cols[i] = i; + pred[i] = start_i; + d[i] = cost[start_i][i] - v[i]; } - if (final_j == -1) + + while (final_j == -1) { - PRINTF("%d..%d -> scan\n", lo, hi); - final_j = _scan_dense(n, cost, &lo, &hi, d, cols, pred, y, v); - PRINT_COST_ARRAY(d, n); - PRINT_INDEX_ARRAY(cols, n); - PRINT_INDEX_ARRAY(pred, n); + // No columns left on the SCAN list. + if (lo == hi) + { + n_ready = lo; + hi = _find_dense(n, lo, d, cols); + for (size_t k = lo; k < hi; k++) + { + const int j = cols[k]; + if (y[j] < 0) + final_j = j; + } + } + if (final_j == -1) + final_j = _scan_dense(n, cost, &lo, &hi, d, cols, pred, y, v); } - } - PRINTF("found final_j=%d\n", final_j); - PRINT_INDEX_ARRAY(cols, n); - { - const cost_t mind = d[cols[lo]]; - for (uint_t k = 0; k < n_ready; k++) { - const int_t j = cols[k]; - v[j] += d[j] - mind; + const lapjv_t mind = d[cols[lo]]; + for (size_t k = 0; k < n_ready; k++) { + const int j = cols[k]; + v[j] += d[j] - mind; + } } - } - FREE(cols); - FREE(d); + return final_j; + } - return final_j; -} + /** Augment for a dense cost matrix. + */ + int _ca_dense( + const size_t n, const std::vector>& cost, + const size_t n_free_rows, + std::vector& free_rows, std::vector& x, std::vector& y, std::vector& v) + { + std::vector pred(n); -/** Augment for a dense cost matrix. - */ -int_t _ca_dense(const uint_t n, cost_t *cost[], const uint_t n_free_rows, - int_t *free_rows, int_t *x, int_t *y, cost_t *v) -{ - int_t *pred; + for (size_t pfree_i = 0; pfree_i < n_free_rows; ++pfree_i) + { + int i = -1; + size_t k = 0; - NEW(pred, int_t, n); + int j = find_path_dense(n, cost, free_rows[pfree_i], y, v, pred); + if (j < 0) + throw std::runtime_error("Error occured in _ca_dense(): j < 0"); - for (int_t *pfree_i = free_rows; pfree_i < free_rows + n_free_rows; - pfree_i++) - { - int_t i = -1, j; - uint_t k = 0; + if (j >= static_cast(n)) + throw std::runtime_error("Error occured in _ca_dense(): j >= n"); - PRINTF("looking at free_i=%d\n", *pfree_i); - j = find_path_dense(n, cost, *pfree_i, y, v, pred); - ASSERT(j >= 0); - ASSERT(j < n); - while (i != *pfree_i) - { - PRINTF("augment %d\n", j); - PRINT_INDEX_ARRAY(pred, n); - i = pred[j]; - PRINTF("y[%d]=%d -> %d\n", j, y[j], i); - y[j] = i; - PRINT_INDEX_ARRAY(x, n); - SWAP_INDICES(j, x[i]); - k++; - if (k >= n) { ASSERT(FALSE); } + while (i != free_rows[pfree_i]) + { + i = pred[j]; + y[j] = i; + std::swap(j, x[i]); + ++k; + if (k >= n) + throw std::runtime_error("Error occured in _ca_dense(): k >= n"); + } } + return 0; } - FREE(pred); - return 0; } - -/** Solve dense sparse LAP. - */ -int lapjv_internal(const uint_t n, cost_t *cost[], int_t *x, int_t *y) +/** Solve dense sparse LAP. */ +int lapjv_internal( + const size_t n, const std::vector>& cost, + std::vector& x, std::vector& y) { - int ret; - int_t *free_rows; - cost_t *v; + std::vector free_rows(n); + std::vector v(n, LARGE); - NEW(free_rows, int_t, n); - NEW(v, cost_t, n); - ret = _ccrrt_dense(n, cost, free_rows, x, y, v); + int ret = _ccrrt_dense(n, cost, free_rows, x, y, v); int i = 0; while (ret > 0 && i < 2) { ret = _carr_dense(n, cost, ret, free_rows, x, y, v); - i++; + ++i; } - if (ret > 0) { ret = _ca_dense(n, cost, ret, free_rows, x, y, v); } - FREE(v); - FREE(free_rows); + if (ret > 0) + ret = _ca_dense(n, cost, ret, free_rows, x, y, v); + return ret; -} \ No newline at end of file +} diff --git a/botsort/src/utils.cpp b/botsort/src/utils.cpp index 0c2d67b..28d430e 100644 --- a/botsort/src/utils.cpp +++ b/botsort/src/utils.cpp @@ -9,15 +9,15 @@ double lapjv(CostMatrix &cost, std::vector &rowsol, bool return_cost) { std::vector> cost_c; + cost_c.resize(cost.rows()); for (Eigen::Index i = 0; i < cost.rows(); i++) { - std::vector row; + cost_c[i].reserve(cost.cols()); for (Eigen::Index j = 0; j < cost.cols(); j++) { - row.push_back(cost(i, j)); + cost_c[i].push_back(cost(i, j)); } - cost_c.push_back(row); } std::vector> cost_c_extended; @@ -93,19 +93,10 @@ double lapjv(CostMatrix &cost, std::vector &rowsol, cost_c.assign(cost_c_extended.begin(), cost_c_extended.end()); } - double **cost_ptr; - cost_ptr = new double *[n]; - for (int i = 0; i < n; i++) cost_ptr[i] = new double[n]; + std::vector x_c(n, -1); + std::vector y_c(n, 0); - for (int i = 0; i < n; i++) - { - for (int j = 0; j < n; j++) { cost_ptr[i][j] = cost_c[i][j]; } - } - - int *x_c = new int[n]; - int *y_c = new int[n]; - - int ret = lapjv_internal(n, cost_ptr, x_c, y_c); + int ret = lapjv_internal(n, cost_c, x_c, y_c); if (ret != 0) { std::cout << "Calculate Wrong!" << std::endl; @@ -128,7 +119,7 @@ double lapjv(CostMatrix &cost, std::vector &rowsol, { for (int i = 0; i < rowsol.size(); i++) { - if (rowsol[i] != -1) { opt += cost_ptr[i][rowsol[i]]; } + if (rowsol[i] != -1) { opt += cost_c[i][rowsol[i]]; } } } } @@ -136,14 +127,8 @@ double lapjv(CostMatrix &cost, std::vector &rowsol, { for (int i = 0; i < rowsol.size(); i++) { - opt += cost_ptr[i][rowsol[i]]; + opt += cost_c[i][rowsol[i]]; } } - - for (int i = 0; i < n; i++) { delete[] cost_ptr[i]; } - delete[] cost_ptr; - delete[] x_c; - delete[] y_c; - return opt; } From 0affe30c676f9327cccba528bbf0164419d3a586 Mon Sep 17 00:00:00 2001 From: Nuzhny007 Date: Wed, 5 Nov 2025 19:17:04 +0300 Subject: [PATCH 4/8] Small optimization --- botsort/src/utils.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/botsort/src/utils.cpp b/botsort/src/utils.cpp index 28d430e..38f4434 100644 --- a/botsort/src/utils.cpp +++ b/botsort/src/utils.cpp @@ -9,15 +9,16 @@ double lapjv(CostMatrix &cost, std::vector &rowsol, bool return_cost) { std::vector> cost_c; - cost_c.resize(cost.rows()); + cost_c.reserve(cost.rows()); for (Eigen::Index i = 0; i < cost.rows(); i++) { - cost_c[i].reserve(cost.cols()); + std::vector row; for (Eigen::Index j = 0; j < cost.cols(); j++) { - cost_c[i].push_back(cost(i, j)); + row.emplace_back(cost(i, j)); } + cost_c.emplace_back(row); } std::vector> cost_c_extended; From 938d61b8ff81bfe1dd2fcc0e41e1514a3a6c1d37 Mon Sep 17 00:00:00 2001 From: Nuzhny007 Date: Wed, 5 Nov 2025 23:08:30 +0300 Subject: [PATCH 5/8] Add ReID based on opencv_dnn when CUDA not founed --- botsort/CMakeLists.txt | 8 +- .../TensorRT_InferenceEngine.h | 8 - botsort/src/ReID.cpp | 175 +++++++++++++++++- .../TensorRT_InferenceEngine.cpp | 1 + 4 files changed, 181 insertions(+), 11 deletions(-) diff --git a/botsort/CMakeLists.txt b/botsort/CMakeLists.txt index 619fb5a..e897c2a 100644 --- a/botsort/CMakeLists.txt +++ b/botsort/CMakeLists.txt @@ -51,7 +51,11 @@ target_link_libraries(${PROJECT_NAME} Eigen3::Eigen) find_package(CUDA QUIET) if(NOT ${CUDA_FOUND}) - message(WARNING "CUDA not found, ReID won't be built") + message(WARNING "CUDA not found, ReID will be built with opencv_dnn") + target_sources(${PROJECT_NAME} PRIVATE + ${PROJECT_SOURCE_DIR}/src/ReID.cpp) + + remove_definitions(-DUSE_TRT_REID) else() message(STATUS "CUDA version ${CUDA_VERSION_STRING} found") target_include_directories(${PROJECT_NAME} PUBLIC ${CUDA_INCLUDE_DIRS}) @@ -74,6 +78,8 @@ else() ${PROJECT_SOURCE_DIR}/src/TRT_InferenceEngine/TensorRT_InferenceEngine.cpp ${PROJECT_SOURCE_DIR}/src/ReID.cpp) target_link_libraries(${PROJECT_NAME} ${CUDA_LIBRARIES}) + + add_definitions(-DUSE_TRT_REID) endif() if(CMAKE_BUILD_TYPE MATCHES Debug) diff --git a/botsort/include/TRT_InferenceEngine/TensorRT_InferenceEngine.h b/botsort/include/TRT_InferenceEngine/TensorRT_InferenceEngine.h index e9d7230..45da725 100644 --- a/botsort/include/TRT_InferenceEngine/TensorRT_InferenceEngine.h +++ b/botsort/include/TRT_InferenceEngine/TensorRT_InferenceEngine.h @@ -1,13 +1,5 @@ #pragma once -#include -#include -#include -#include -#include -#include -#include - #include #include diff --git a/botsort/src/ReID.cpp b/botsort/src/ReID.cpp index f1915ae..9a212f4 100644 --- a/botsort/src/ReID.cpp +++ b/botsort/src/ReID.cpp @@ -1,7 +1,14 @@ #include "ReID.h" #include "INIReader.h" + +#ifdef USE_TRT_REID #include "TRT_InferenceEngine/TensorRT_InferenceEngine.h" +#else +#include +#include +#include +#endif /// class ReIDModel::InferenceImpl @@ -16,8 +23,9 @@ class ReIDModel::InferenceImpl virtual FeatureVector extract_features(cv::Mat &image_patch) = 0; }; +#ifdef USE_TRT_REID /// -class ReIDInferenceImpl final : public ReIDModel::InferenceImpl +class ReIDInferenceTRT final : public ReIDModel::InferenceImpl { public: bool Init(const ReIDParams& params, const std::string& onnx_model_path) override @@ -99,13 +107,176 @@ class ReIDInferenceImpl final : public ReIDModel::InferenceImpl } }; +#else // USE_TRT_REID +/// +class ReIDInferenceOCV final : public ReIDModel::InferenceImpl +{ +public: + bool Init(const ReIDParams ¶ms, + const std::string &onnx_model_path) override + { + _onnx_model_path = onnx_model_path; + + _load_params_from_config(params); + + _net = cv::dnn::readNet(onnx_model_path); + + std::cout << "Re-id model " << onnx_model_path + << " loaded: " << (!_net.empty()) << std::endl; + + if (!_net.empty()) + { + std::map dictTargets; + dictTargets[cv::dnn::DNN_TARGET_CPU] = "DNN_TARGET_CPU"; + dictTargets[cv::dnn::DNN_TARGET_OPENCL] = "DNN_TARGET_OPENCL"; + dictTargets[cv::dnn::DNN_TARGET_OPENCL_FP16] = + "DNN_TARGET_OPENCL_FP16"; + dictTargets[cv::dnn::DNN_TARGET_MYRIAD] = "DNN_TARGET_MYRIAD"; + dictTargets[cv::dnn::DNN_TARGET_CUDA] = "DNN_TARGET_CUDA"; + dictTargets[cv::dnn::DNN_TARGET_CUDA_FP16] = "DNN_TARGET_CUDA_FP16"; +#if (CV_VERSION_MAJOR > 4) + dictTargets[cv::dnn::DNN_TARGET_HDDL] = "DNN_TARGET_HDDL"; + dictTargets[cv::dnn::DNN_TARGET_NPU] = "DNN_TARGET_NPU"; + dictTargets[cv::dnn::DNN_TARGET_CPU_FP16] = "DNN_TARGET_CPU_FP16"; +#endif + + std::map dictBackends; + dictBackends[cv::dnn::DNN_BACKEND_DEFAULT] = "DNN_BACKEND_DEFAULT"; + dictBackends[cv::dnn::DNN_BACKEND_INFERENCE_ENGINE] = + "DNN_BACKEND_INFERENCE_ENGINE"; + dictBackends[cv::dnn::DNN_BACKEND_OPENCV] = "DNN_BACKEND_OPENCV"; + dictBackends[cv::dnn::DNN_BACKEND_VKCOM] = "DNN_BACKEND_VKCOM"; + dictBackends[cv::dnn::DNN_BACKEND_CUDA] = "DNN_BACKEND_CUDA"; +#if (CV_VERSION_MAJOR > 4) + dictBackends[cv::dnn::DNN_BACKEND_WEBNN] = "DNN_BACKEND_WEBNN"; + dictBackends[cv::dnn::DNN_BACKEND_TIMVX] = "DNN_BACKEND_TIMVX"; + dictBackends[cv::dnn::DNN_BACKEND_CANN] = "DNN_BACKEND_CANN"; +#endif + dictBackends[1000000] = "DNN_BACKEND_INFERENCE_ENGINE_NGRAPH"; + dictBackends[1000000 + 1] = + "DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019"; + + std::cout << "Avaible pairs for Target - backend:" << std::endl; + std::vector> pairs = + cv::dnn::getAvailableBackends(); + for (auto p: pairs) + { + std::cout << dictBackends[p.first] << " (" << p.first << ") - " + << dictTargets[p.second] << " (" << p.second << ")" + << std::endl; + + if (p.first == cv::dnn::DNN_BACKEND_CUDA) + { + //_net.setPreferableTarget(p.second); + //_net.setPreferableBackend(p.first); + //std::cout << "Set!" << std::endl; + } + } + + auto outNames = _net.getUnconnectedOutLayersNames(); + auto outLayers = _net.getUnconnectedOutLayers(); + auto outLayerType = _net.getLayer(outLayers[0])->type; + +#if (CV_VERSION_MAJOR < 5) + std::vector outputs; + std::vector internals; + _net.getLayerShapes(cv::dnn::MatShape(), 0, outputs, internals); +#else + std::vector outputs; + std::vector internals; + _net.getLayerShapes(cv::MatShape(), CV_32F, 0, outputs, internals); +#endif + std::cout << "REID: getLayerShapes: outputs (" << outputs.size() + << ") = " << (outputs.size() > 0 ? outputs[0].size() : 0) + << ", internals (" << internals.size() << ") = " + << (internals.size() > 0 ? internals[0].size() : 0) + << std::endl; + if (outputs.size() && outputs[0].size() > 3) + std::cout << "outputs = [" << outputs[0][0] << ", " + << outputs[0][1] << ", " << outputs[0][2] << ", " + << outputs[0][3] << "], internals = [" + << internals[0][0] << ", " << internals[0][1] << ", " + << internals[0][2] << ", " << internals[0][3] << "]" + << std::endl; + } + return !_net.empty(); + } + + FeatureVector extract_features(cv::Mat &image_patch) override + { + FeatureVector feature_vector; + + if (!_net.empty()) + { + + cv::Mat obj; + cv::resize(image_patch, obj, _input_size, 0., 0., cv::INTER_CUBIC); + cv::Mat blob = + cv::dnn::blobFromImage(obj, 1.0 / 255.0, cv::Size(), + cv::Scalar(), false, false, CV_32F); + + _net.setInput(blob); + + cv::Mat output; + cv::normalize(_net.forward(), output); + + feature_vector = FeatureVector::Zero(1, FEATURE_DIM); + for (int i = 0; i < FEATURE_DIM; i++) + { + feature_vector(0, i) = output.at(i); + } + } + return feature_vector; + } + + const std::string &get_distance_metric() const noexcept override + { + return _distance_metric; + } + +private: + cv::dnn::Net _net; + + cv::Size _input_size{128, 256}; + std::string _input_layer_name; + std::string _onnx_model_path; + std::string _distance_metric; + std::vector _output_layer_names; + bool _swapRB = true; + + void _load_params_from_config(const ReIDParams ¶ms) + { + _distance_metric = params.distance_metric; + _input_layer_name = params.input_layer_name; + + std::cout << "Trying to get input dims" << std::endl; + _input_size = cv::Size(params.input_layer_dimensions[3], + params.input_layer_dimensions[2]); + + std::cout << "Read input dims" << std::endl; + std::cout << "Input dims: " << params.input_layer_dimensions[0] << " " + << params.input_layer_dimensions[1] << " " + << params.input_layer_dimensions[2] << " " + << params.input_layer_dimensions[3] << std::endl; + + _swapRB = params.swap_rb; + + _output_layer_names = params.output_layer_names; + } +}; +#endif // USE_TRT_REID + /// ReIDModel::ReIDModel(const ReIDParams ¶ms, const std::string &onnx_model_path) { std::cout << "Initializing ReID model" << std::endl; - _inference_impl = new ReIDInferenceImpl(); +#ifdef USE_TRT_REID + _inference_impl = new ReIDInferenceTRT(); +#else + _inference_impl = new ReIDInferenceOCV(); +#endif bool net_initialized = _inference_impl->Init(params, onnx_model_path); if (!net_initialized) diff --git a/botsort/src/TRT_InferenceEngine/TensorRT_InferenceEngine.cpp b/botsort/src/TRT_InferenceEngine/TensorRT_InferenceEngine.cpp index 7b669e2..4d1454f 100644 --- a/botsort/src/TRT_InferenceEngine/TensorRT_InferenceEngine.cpp +++ b/botsort/src/TRT_InferenceEngine/TensorRT_InferenceEngine.cpp @@ -1,5 +1,6 @@ #include "TRT_InferenceEngine/TensorRT_InferenceEngine.h" +#include #include #include From 237c297ba15d373ca4bdbe48201a10bb8d7a4be0 Mon Sep 17 00:00:00 2001 From: Nuzhny007 Date: Thu, 13 Nov 2025 22:30:52 +0300 Subject: [PATCH 6/8] Fix swapRB --- botsort/src/ReID.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/botsort/src/ReID.cpp b/botsort/src/ReID.cpp index 9a212f4..293b616 100644 --- a/botsort/src/ReID.cpp +++ b/botsort/src/ReID.cpp @@ -208,12 +208,11 @@ class ReIDInferenceOCV final : public ReIDModel::InferenceImpl if (!_net.empty()) { - cv::Mat obj; cv::resize(image_patch, obj, _input_size, 0., 0., cv::INTER_CUBIC); cv::Mat blob = cv::dnn::blobFromImage(obj, 1.0 / 255.0, cv::Size(), - cv::Scalar(), false, false, CV_32F); + cv::Scalar(), _swapRB, false, CV_32F); _net.setInput(blob); From c4d43393f7ff257670f59bf5e719f630b27e6a6c Mon Sep 17 00:00:00 2001 From: Nuzhny007 Date: Thu, 13 Nov 2025 22:49:02 +0300 Subject: [PATCH 7/8] One more lapjv optimization --- botsort/src/utils.cpp | 74 +++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/botsort/src/utils.cpp b/botsort/src/utils.cpp index 38f4434..9b9b808 100644 --- a/botsort/src/utils.cpp +++ b/botsort/src/utils.cpp @@ -8,28 +8,16 @@ double lapjv(CostMatrix &cost, std::vector &rowsol, std::vector &colsol, bool extend_cost, float cost_limit, bool return_cost) { - std::vector> cost_c; - cost_c.reserve(cost.rows()); - - for (Eigen::Index i = 0; i < cost.rows(); i++) - { - std::vector row; - for (Eigen::Index j = 0; j < cost.cols(); j++) - { - row.emplace_back(cost(i, j)); - } - cost_c.emplace_back(row); - } - - std::vector> cost_c_extended; - int n_rows = static_cast(cost.rows()); int n_cols = static_cast(cost.cols()); rowsol.resize(n_rows); colsol.resize(n_cols); int n = 0; - if (n_rows == n_cols) { n = n_rows; } + if (n_rows == n_cols) + { + n = n_rows; + } else { if (!extend_cost) @@ -39,59 +27,71 @@ double lapjv(CostMatrix &cost, std::vector &rowsol, } } + std::vector> cost_c; if (extend_cost || cost_limit < LONG_MAX) { n = n_rows + n_cols; - cost_c_extended.resize(n); - for (int i = 0; i < cost_c_extended.size(); i++) - cost_c_extended[i].resize(n); + cost_c.resize(n); + for (int i = 0; i < cost_c.size(); i++) + cost_c[i].resize(n); if (cost_limit < LONG_MAX) { - for (int i = 0; i < cost_c_extended.size(); i++) + for (int i = 0; i < cost_c.size(); i++) { - for (int j = 0; j < cost_c_extended[i].size(); j++) + for (int j = 0; j < cost_c[i].size(); j++) { - cost_c_extended[i][j] = cost_limit / 2.0; + cost_c[i][j] = cost_limit / 2.0; } } } else { float cost_max = -1; - for (int i = 0; i < cost_c.size(); i++) + for (Eigen::Index i = 0; i < cost.rows(); ++i) { - for (int j = 0; j < cost_c[i].size(); j++) + for (Eigen::Index j = 0; j < cost.cols(); ++j) { - if (cost_c[i][j] > cost_max) cost_max = cost_c[i][j]; + if (cost(i, j) > cost_max) + cost_max = cost(i, j); } } - for (int i = 0; i < cost_c_extended.size(); i++) + for (int i = 0; i < cost_c.size(); i++) { - for (int j = 0; j < cost_c_extended[i].size(); j++) + for (int j = 0; j < cost_c[i].size(); j++) { - cost_c_extended[i][j] = cost_max + 1; + cost_c[i][j] = cost_max + 1; } } } - for (int i = n_rows; i < cost_c_extended.size(); i++) + for (int i = n_rows; i < cost_c.size(); i++) { - for (int j = n_cols; j < cost_c_extended[i].size(); j++) + for (int j = n_cols; j < cost_c[i].size(); j++) { - cost_c_extended[i][j] = 0; + cost_c[i][j] = 0; } } - for (int i = 0; i < n_rows; i++) + for (Eigen::Index i = 0; i < cost.rows(); ++i) { - for (int j = 0; j < n_cols; j++) + for (Eigen::Index j = 0; j < cost.cols(); ++j) { - cost_c_extended[i][j] = cost_c[i][j]; + cost_c[i][j] = cost(i, j); } } - - cost_c.clear(); - cost_c.assign(cost_c_extended.begin(), cost_c_extended.end()); + } + else + { + cost_c.reserve(cost.rows()); + for (Eigen::Index i = 0; i < cost.rows(); ++i) + { + std::vector row; + for (Eigen::Index j = 0; j < cost.cols(); ++j) + { + row.emplace_back(cost(i, j)); + } + cost_c.emplace_back(row); + } } std::vector x_c(n, -1); From bb7fc7cebc77d18d6042485fc5bbfa5d5b684c3b Mon Sep 17 00:00:00 2001 From: Nuzhny007 Date: Thu, 13 Nov 2025 22:59:40 +0300 Subject: [PATCH 8/8] Fix types --- botsort/src/utils.cpp | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/botsort/src/utils.cpp b/botsort/src/utils.cpp index 9b9b808..4d5cd92 100644 --- a/botsort/src/utils.cpp +++ b/botsort/src/utils.cpp @@ -8,12 +8,12 @@ double lapjv(CostMatrix &cost, std::vector &rowsol, std::vector &colsol, bool extend_cost, float cost_limit, bool return_cost) { - int n_rows = static_cast(cost.rows()); - int n_cols = static_cast(cost.cols()); + size_t n_rows = cost.rows(); + size_t n_cols = cost.cols(); rowsol.resize(n_rows); colsol.resize(n_cols); - int n = 0; + size_t n = 0; if (n_rows == n_cols) { n = n_rows; @@ -32,14 +32,14 @@ double lapjv(CostMatrix &cost, std::vector &rowsol, { n = n_rows + n_cols; cost_c.resize(n); - for (int i = 0; i < cost_c.size(); i++) + for (size_t i = 0; i < cost_c.size(); i++) cost_c[i].resize(n); if (cost_limit < LONG_MAX) { - for (int i = 0; i < cost_c.size(); i++) + for (size_t i = 0; i < cost_c.size(); i++) { - for (int j = 0; j < cost_c[i].size(); j++) + for (size_t j = 0; j < cost_c[i].size(); j++) { cost_c[i][j] = cost_limit / 2.0; } @@ -56,18 +56,18 @@ double lapjv(CostMatrix &cost, std::vector &rowsol, cost_max = cost(i, j); } } - for (int i = 0; i < cost_c.size(); i++) + for (size_t i = 0; i < cost_c.size(); i++) { - for (int j = 0; j < cost_c[i].size(); j++) + for (size_t j = 0; j < cost_c[i].size(); j++) { cost_c[i][j] = cost_max + 1; } } } - for (int i = n_rows; i < cost_c.size(); i++) + for (size_t i = n_rows; i < cost_c.size(); i++) { - for (int j = n_cols; j < cost_c[i].size(); j++) + for (size_t j = n_cols; j < cost_c[i].size(); j++) { cost_c[i][j] = 0; } @@ -108,25 +108,30 @@ double lapjv(CostMatrix &cost, std::vector &rowsol, if (n != n_rows) { - for (int i = 0; i < n; i++) + for (size_t i = 0; i < n; i++) { - if (x_c[i] >= n_cols) x_c[i] = -1; - if (y_c[i] >= n_rows) y_c[i] = -1; + if (x_c[i] >= n_cols) + x_c[i] = -1; + if (y_c[i] >= n_rows) + y_c[i] = -1; } - for (int i = 0; i < n_rows; i++) { rowsol[i] = x_c[i]; } - for (int i = 0; i < n_cols; i++) { colsol[i] = y_c[i]; } + for (size_t i = 0; i < n_rows; i++) + rowsol[i] = x_c[i]; + for (size_t i = 0; i < n_cols; i++) + colsol[i] = y_c[i]; if (return_cost) { - for (int i = 0; i < rowsol.size(); i++) + for (size_t i = 0; i < rowsol.size(); i++) { - if (rowsol[i] != -1) { opt += cost_c[i][rowsol[i]]; } + if (rowsol[i] != -1) + opt += cost_c[i][rowsol[i]]; } } } else if (return_cost) { - for (int i = 0; i < rowsol.size(); i++) + for (size_t i = 0; i < rowsol.size(); i++) { opt += cost_c[i][rowsol[i]]; }