【Deepsort】C++版本Deepsort编译(依赖opencv,eigen3)

66 篇文章 1 订阅
44 篇文章 4 订阅

下载源码

https://github.com/shaoshengsong/DeepSORT

安装onnxruntime

安装方法参考博客

安装Eigen3

当谈及线性代数计算库时,Eigen3是一个强大而受欢迎的选择。Eigen3是一个C++模板库,提供了许多用于线性代数运算的功能,如向量、矩阵、矩阵运算、线性方程组求解等。以下是Eigen3的一些主要特点和功能:

高性能:Eigen3使用了优化的算法和技术,具有出色的运行速度和高效的内存使用。它通过使用表达式模板技术来在编译时生成高效的计算代码,避免了一些运行时的开销。

简洁易用:Eigen3提供了直观且易于使用的API,使得进行线性代数计算变得简单和直观。它的API设计简洁明了,提供了丰富的运算符重载和友好的语法,使得代码编写更加简单和可读。

广泛的功能:Eigen3支持多种线性代数运算,包括向量和矩阵的基本运算、线性方程组的求解、特征值和特征向量的计算、矩阵分解(如LU分解、QR分解等)、广义特征值问题的求解等。它还提供了一些高级功能,如支持稀疏矩阵和动态大小矩阵等。

跨平台支持:Eigen3是一个跨平台的库,可以在各种操作系统和编译器上使用。它使用标准的C++语法和特性,并且不依赖于任何特定的硬件或操作系统。

开源免费:Eigen3是一个开源库,遵循MPL2.0协议,可以免费使用和修改。它的源代码可在GitHub上获得,方便用户进行定制和扩展。
Eigen3已被广泛应用于科学计算、机器学习、计算机图形学等领域。无论是在学术研究还是实际应用中,Eigen3都是一个强大而可靠的线性代数库。

sudo apt-get install libeigen3-dev

编译opencv

编译命令:下载opencv4的源码包后解压,并下载contrib扩展包,开启dnn
读取视频需要安装ffmpeg:

sudo apt-get install build-essential
sudo apt-get install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
sudo apt-get install python-dev python-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libjasper-dev libdc1394-22-dev

对于libjasper-dev安装失败:

apt-get install software-properties-common
add-apt-repository "deb http://security.ubuntu.com/ubuntu xenial-security main"
apt update
apt-get install libjasper-dev
sudo apt-get install ffmpeg

获取ffmpeg的相关安装目录:

pkg-config --cflags libavformat

编译:

cmake    -DCMAKE_BUILD_TYPE=Release -DOPENCV_EXTRA_MODULES_PATH=/home/opencv_contrib-4.7.0/opencv_contrib-4.7.0/modules -DWITH_OPENCL=OFF -DBUILD_DOCS=OFF -DBUILD_EXAMPLES=OFF -DBUILD_WITH_DEBUG_INFO=OFF -DBUILD_TESTS=OFF -DWITH_1394=OFF -DWITH_CUDA=OFF -DWITH_CUBLAS=OFF -DWITH_CUFFT=OFF -DWITH_OPENCLAMDBLAS=OFF -DWITH_OPENCLAMDFFT=OFF -DINSTALL_C_EXAMPLES=OFF -DINSTALL_PYTHON_EXAMPLES=OFF -DINSTALL_TO_MANGLED_PATHS=OFF -DBUILD_ANDROID_EXAMPLES=OFF -DBUILD_opencv_python=OFF -DBUILD_opencv_python_bindings_generator=OFF -DBUILD_opencv_apps=OFF -DBUILD_opencv_calib3d=OFF -DBUILD_opencv_features2d=OFF -DBUILD_opencv_flann=OFF -DBUILD_opencv_java_bindings_generator=OFF -DBUILD_opencv_js=OFF -DBUILD_opencv_ml=OFF -DBUILD_opencv_objdetect=OFF -DBUILD_opencv_photo=OFF -DBUILD_opencv_python3=OFF -DBUILD_opencv_python_tests=OFF -DBUILD_opencv_shape=OFF -DBUILD_opencv_stitching=OFF -DBUILD_opencv_superres=OFF -DBUILD_opencv_ts=OFF -DBUILD_opencv_videostab=OFF -DBUILD_opencv_world=ON -DBUILD_opencv_dnn=ON -D WITH_FFMPEG=ON -D WITH_TIFF=OFF -D BUILD_TIFF=OFF -DWITH_FFMPEG=ON  -DFFMPEG_LIBRARIES=/usr/local/lib/ -D FFMPEG_INCLUDE_DIRS=/usr/local/include/ ..

make install

更改deepsort对应的cpp文件:

#include <fstream>
#include <sstream>
#include <opencv2/imgproc.hpp>
#include <opencv2/opencv.hpp>
#include <opencv2/dnn.hpp>
#include "YOLOv5Detector.h"

#include "FeatureTensor.h"
#include "BYTETracker.h" //bytetrack
#include "tracker.h"//deepsort
//Deep SORT parameter

const int nn_budget=100;
const float max_cosine_distance=0.2;

void get_detections(DETECTBOX box,float confidence,DETECTIONS& d)
{
    DETECTION_ROW tmpRow;
    tmpRow.tlwh = box;//DETECTBOX(x, y, w, h);

    tmpRow.confidence = confidence;
    d.push_back(tmpRow);
}


void test_deepsort(cv::Mat& frame, std::vector<detect_result>& results,tracker& mytracker)
{
    std::vector<detect_result> objects;

    DETECTIONS detections;
    for (detect_result dr : results)
    {
        //cv::putText(frame, classes[dr.classId], cv::Point(dr.box.tl().x+10, dr.box.tl().y - 10), cv::FONT_HERSHEY_SIMPLEX, .8, cv::Scalar(0, 255, 0));
        if(dr.classId == 0) //person
        {
            objects.push_back(dr);
            cv::rectangle(frame, dr.box, cv::Scalar(255, 0, 0), 2);
            get_detections(DETECTBOX(dr.box.x, dr.box.y,dr.box.width,  dr.box.height),dr.confidence,  detections);
        }
    }

    std::cout<<"begin track"<<std::endl;
    if(FeatureTensor::getInstance()->getRectsFeature(frame, detections))
    {
        std::cout << "get feature succeed!"<<std::endl;
        mytracker.predict();
        mytracker.update(detections);
        std::vector<RESULT_DATA> result;
        for(Track& track : mytracker.tracks) {
            if(!track.is_confirmed() || track.time_since_update > 1) continue;
            result.push_back(std::make_pair(track.track_id, track.to_tlwh()));
        }
        for(unsigned int k = 0; k < detections.size(); k++)
        {
            DETECTBOX tmpbox = detections[k].tlwh;
            cv::Rect rect(tmpbox(0), tmpbox(1), tmpbox(2), tmpbox(3));
            cv::rectangle(frame, rect, cv::Scalar(0,0,255), 4);
            // cvScalar的储存顺序是B-G-R,CV_RGB的储存顺序是R-G-B

            for(unsigned int k = 0; k < result.size(); k++)
            {
                DETECTBOX tmp = result[k].second;
                cv::Rect rect = cv::Rect(tmp(0), tmp(1), tmp(2), tmp(3));
                rectangle(frame, rect, cv::Scalar(255, 255, 0), 2);

                std::string label = cv::format("%d", result[k].first);
                cv::putText(frame, label, cv::Point(rect.x, rect.y), cv::FONT_HERSHEY_SIMPLEX, 0.8, cv::Scalar(255, 255, 0), 2);
            }
        }
    }
    std::cout<<"end track"<<std::endl;
}


void test_bytetrack(cv::Mat& frame, std::vector<detect_result>& results,BYTETracker& tracker)
{
    std::vector<detect_result> objects;


    for (detect_result dr : results)
    {

        if(dr.classId == 0) //person
        {
            objects.push_back(dr);
        }
    }


    std::vector<STrack> output_stracks = tracker.update(objects);

    for (unsigned long i = 0; i < output_stracks.size(); i++)
    {
        std::vector<float> tlwh = output_stracks[i].tlwh;
        bool vertical = tlwh[2] / tlwh[3] > 1.6;
        if (tlwh[2] * tlwh[3] > 20 && !vertical)
        {
            cv::Scalar s = tracker.get_color(output_stracks[i].track_id);
            cv::putText(frame, cv::format("%d", output_stracks[i].track_id), cv::Point(tlwh[0], tlwh[1] - 5),
                    0, 0.6, cv::Scalar(0, 0, 255), 2, cv::LINE_AA);
            cv::rectangle(frame, cv::Rect(tlwh[0], tlwh[1], tlwh[2], tlwh[3]), s, 2);
        }
    }


}
int main(int argc, char *argv[])
{
    //deepsort
    tracker mytracker(max_cosine_distance, nn_budget);
    //bytetrack
    int fps=20;
    BYTETracker bytetracker(fps, 30);
    //-----------------------------------------------------------------------
    // 加载类别名称
    std::vector<std::string> classes;
    std::string file="./coco_80_labels_list.txt";
    std::ifstream ifs(file);
    if (!ifs.is_open())
        CV_Error(cv::Error::StsError, "File " + file + " not found");
    std::string line;
    while (std::getline(ifs, line))
    {
        classes.push_back(line);
    }
    //-----------------------------------------------------------------------

    std::cout<<"classes:"<<classes.size();
    std::shared_ptr<YOLOv5Detector> detector(new YOLOv5Detector());

    detector->init("/home/DeepSORT-master/DeepSORT-master/build/yolov5x.onnx");

    std::cout<<"begin read video"<<std::endl;
    const std::string source = "/home/DeepSORT-master/DeepSORT-master/build/test.mp4";
    cv::VideoCapture capture(source);

    if (!capture.isOpened()) {
        printf("could not read this video file...\n");
        return -1;
    }
    std::cout<<"end read video"<<std::endl;
    std::vector<detect_result> results;
    int num_frames = 0;

    cv::VideoWriter video("out.avi",cv::VideoWriter::fourcc('M','J','P','G'),10, cv::Size(1920,1080));

    while (true)
    {
        cv::Mat frame;


        if (!capture.read(frame)) // if not success, break loop
        {
            std::cout<<"\n Cannot read the video file. please check your video.\n";
            break;
        }

        num_frames ++;
        //Second/Millisecond/Microsecond  秒s/毫秒ms/微秒us
        auto start = std::chrono::system_clock::now();
        detector->detect(frame, results);
        auto end = std::chrono::system_clock::now();
        auto detect_time =std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();//ms
        std::cout<<classes.size()<<":"<<results.size()<<":"<<num_frames<<std::endl;


        //test_deepsort(frame, results,mytracker);
        test_bytetrack(frame, results,bytetracker);

        //cv::imshow("YOLOv5-6.x", frame);

        video.write(frame);

        if(cv::waitKey(30) == 27) // Wait for 'esc' key press to exit
        {
            break;
        }

        results.clear();


    }
    capture.release();
    video.release();
    cv::destroyAllWindows();


}

编译并运行:

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
### 回答1: OpenCV是一款开源的计算机视觉库,它提供了丰富的图像处理和计算机视觉算法,可以帮助开发者实现各种视觉任务。CMake是一个跨平台的构建工具,可以帮助开发者在不同的操作系统上进行项目的构建和管理。Eigen是一个C++模板库,提供了高级的矩阵和向量运算功能,适用于各种数学计算和线性代数操作。 在使用OpenCV进行开发时,我们可以使用CMake进行项目的构建。CMake可以根据不同操作系统的情况生成相应的构建文件,方便开发者在不同系统上进行开发和部署。在构建OpenCV项目时,我们可以使用CMakeFile.txt文件来描述项目的结构和依赖关系,然后通过CMake生成对应的构建文件。 而Eigen可以与OpenCV一起使用,为OpenCV提供更强大的数学计算能力。Eigen提供了高性能的矩阵和向量操作,可以进行矩阵运算、特征值计算、线性代数等数学计算。通过集成Eigen,我们可以在OpenCV项目中更方便地处理各种数学计算任务。 在使用OpenCV和Eigen时,可以选择使用Visual Studio 2017进行开发。Visual Studio 2017是一款强大的集成开发环境,提供了丰富的开发工具和调试能力。通过Visual Studio 2017,我们可以方便地进行OpenCV和Eigen项目的编写、构建和调试,提高开发效率。 综上所述,OpenCV、CMake、Eigen和Visual Studio 2017可以相互配合使用,实现图像处理和计算机视觉相关的项目开发。通过使用CMake进行项目构建,集成Eigen库进行数学计算,使用Visual Studio 2017进行开发,可以提高开发效率,快速实现各种视觉任务。 ### 回答2: OpenCV 是一个开源的计算机视觉库,它提供了丰富的图像处理和计算机视觉算法。CMake 是一个跨平台的构建工具,用于生成编译项目所需的 Makefile 或者 Visual Studio 的解决方案文件。Eigen 是一个 C++ 模板库,提供了线性代数的相关功能。 在使用 OpenCV 进行开发时,我们可以使用 CMake 来配置和生成项目,以便在不同的开发环境中进行编译和构建。CMake 可以自动检测并配置 Opencv 的相关路径,以便正确地链接和使用库文件。 而 Eigen 则是一个非常常用的线性代数库,它提供了矩阵、向量和矢量等数学对象的定义和操作。在使用 OpenCV 进行图像处理时,我们经常需要使用到矩阵操作,而 Eigen 提供了更高效和方便的矩阵运算,可以更好地满足我们的需求。 对于在 Visual Studio 2017 上使用 OpenCV、CMake 和 Eigen 进行开发,我们首先需要确保已经正确安装并配置了这些工具。然后,我们可以使用 CMake 来生成一个 Visual Studio 的解决方案,其中将包含我们要开发的项目以及所需的库文件链接。 在 CMake 中,我们需要添加相应的路径信息,以便 CMake 可以找到 OpenCV 和 Eigen 的安装路径。然后将这些路径信息与我们的项目相关内容一起配置,并生成 Visual Studio 的解决方案。 在 Visual Studio 2017 中,我们可以打开生成的解决方案,并进行编写和调试我们的代码。可以使用 OpenCV、CMake 和 Eigen 的相关函数和类,进行图像处理、线性代数计算等任务。 总之,使用 OpenCV、CMake 和 Eigen 进行 Visual Studio 2017 上的开发,可以方便地进行图像处理和计算机视觉算法的开发,以及进行高效的线性代数计算。 ### 回答3: OpenCV是一个流行的计算机视觉库,用于处理图像和视频。依靠cmake进行项目构建。Eigen是一个C ++模板库,提供了用于线性代数运算的高性能数学工具。现在我来回答关于OpenCV、CMake和Eigen在VS2017中的问题。 首先,你需要确保已经在你的计算机上安装了Visual Studio 2017和CMake。在安装完成后,你可以开始设置OpenCV、CMake和Eigen。 首先,你需要下载并安装OpenCV库。你可以从OpenCV官方网站下载最新版本OpenCV,并按照官方文档提供的说明进行安装。在安装完成后,你需要设置OpenCV的环境变量,以便在VS2017中使用OpenCV。 接下来,你可以使用CMake来构建你的OpenCV项目。在CMake中,你需要指定OpenCV的安装路径,并设置你的工程文件路径。你可以使用CMake的GUI界面或命令行界面来完成这一步骤。 然后,你需要下载并安装Eigen库。你可以从Eigen官方网站下载最新版本的Eigen,并按照官方文档提供的说明进行安装。 在设置完OpenCV和Eigen后,你可以在VS2017中创建一个新的项目。你需要在项目配置中链接OpenCV和Eigen库,并将必要的头文件包含到你的代码中。你可以在项目属性中进行这些配置。 最后,你可以在你的代码中使用OpenCV、CMake和Eigen来进行图像和视频处理、线性代数运算等操作。你可以通过查看OpenCV、Eigen和CMake的官方文档来学习更多关于这些库的用法和特性。 总结来说,你需要安装OpenCV、设置CMake并安装Eigen,然后在VS2017中配置你的项目,以使用OpenCV、CMake和Eigen来进行图像处理和数学运算。希望这些信息对你有所帮助!
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

颢师傅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值