目标跟踪实践笔记四

OpenTracker指标对比输出

    关于OpenTracker的编译安装参考我的上一篇文章目标跟踪实践笔记三。这一篇是我自己在项目源码的基础上进行一些输出显示的修改,来对比显示各个跟踪器的指标。

1、编译trackerscompare


make all
sudo make install
./trackerscompare.bin

在执行最后一步的时候我出现了问题,

./trackerscompare.bin: error while loading shared libraries: libopencv_tracking.so.3.4: cannot open shared object file: No such file or directory

解决办法:

sudo /bin/bash -c 'echo "/usr/local/lib" > /etc/ld.so.conf.d/opencv.conf'
sudo ldconfig

然后重新执行 trackerscompare 的编译即可。

2、浏览 trackerscompare.cpp 文件


    打开文件可以看出来,项目提供了三个跟踪图像的来源,openpose(网络摄像头)video(本地的视频)datasets(图像数据集)。自己可以根据自己的条件来进行选择。像我虽然最后是需要放在无人机上进行目标识别跟踪,但得先在数据集上验证好才能跑视频流,所以就用最后一个,也是这里的默认选项。


提示:Ubuntu下用自己的USB摄像头跑的话,将72 - 79行程序注释掉,增加以下程序:

cv::Rect2f bboxGroundtruth;
cv::Mat frame, frameDraw;
cv::VideoCapture capture;

VideoCapture capture(0); // open the default camera
if (!capture.isOpened()) // check if we succeeded
        return -1;
        
capture.set(CV_CAP_PROP_FRAME_WIDTH, 1280);  //设置分辨率
capture.set(CV_CAP_PROP_FRAME_HEIGHT, 720);

capture >> frame;
frameDraw.copyTo(frame);

std::string window_name = "OpenTracker";
cv::namedWindow(window_name);
//ReadVideo readvideo;  
//readvideo.IniRead(bboxGroundtruth, frameDraw, window_name, capture);

同时注释掉 241行 readdatasets.ReadNextFrame(bboxGroundtruth, frame);
打开 243 - 245 行内容

capture >> frame;
if (frame.empty())
     return false;

出来图像之后需要自己用鼠标选择目标物,然后就会自动跟踪了。


这个流程其实很类似ECO的流程,都是第一帧先从Groundtruth里面选择跟踪的目标物,然后跑自己的算法。这里对比了OpenCV自带的一些算法、KCF、DSST、ECO几个跟踪算法。实际测试来看OpenCV内部带的明显没有后面三个好,我也把这个删了。

3、更改trackercompare.cpp,输出各算法对比指标


这个文件没有输出相关的指标,只是直观的看一下,所以我才对文件进行一些改动,改动后的程序能够在终端显示出三个跟踪算法的PrecisionIouSuccessRate 以及 ECO 的 AvgFps
因为需要用到一些计算,可以直接调用 eco / metrics.cc 文件中的函数,需要改 makefile 文件,在27行后面加上eco/metrics.o\,最后的程序是这样的:

OBJS=kcf/fhog.o \
	kcf/kcftracker.o \
	eco/ffttools.o \
	eco/fhog.o \
	eco/interpolator.o \
	eco/optimize_scores.o \
	eco/regularization_filter.o \
	eco/feature_extractor.o \
	eco/feature_operator.o  \
	eco/training.o \
	eco/sample_update.o \
	eco/scale_filter.o \
	eco/eco.o \
	eco/metrics.o\   //加上这个
	inputs/readdatasets.o inputs/readvideo.o
TARGET_LIB = libopentracker.so

最后的tarckerscomper.cpp文件内容如下:

#include "kcf/kcftracker.hpp"
#include "eco/eco.hpp"
#include "eco/parameters.hpp"

#include "eco/metrics.hpp"  //Add

#ifdef USE_CAFFE
#include "goturn/network/regressor.h"
#include "goturn/tracker/tracker.h"
#endif

#include "inputs/readdatasets.hpp"
#include "inputs/readvideo.hpp"
//#include "inputs/openpose.hpp"

#include <gflags/gflags.h>
#include <glog/logging.h>

#include <opencv2/opencv.hpp>
#include <opencv2/tracking.hpp>
#include <opencv2/core/ocl.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

#include <iostream>
#include <fstream>
#include <string>

using namespace cv;
using namespace std;

// Convert to string
int main(int argc, char **argv)
{
    // Database settings  Now only Demo can work
    string databaseTypes[5] = {"Demo","VOT-2017", "TB-2015", "TLP", "UAV123"};
    string databaseType = databaseTypes[0];  //chose one databaseType

    // Set the index of target   KCF ====================================================
    std::vector<float> KCFCenterError;
    std::vector<float> KCFIou;
    std::vector<float> KCFFpsEco;
    float KCFSuccessRate = 0.0f;
    float KCFAvgPrecision = 0.0f;
    float KCFAvgIou = 0.0f;
    float KCFAvgFps = 0.0f;
   //Set the index of target   DSST ====================================================
    std::vector<float> DSSTCenterError;
    std::vector<float> DSSTIou;
    std::vector<float> DSSTFpsEco;
    float DSSTSuccessRate = 0.0f;
    float DSSTAvgPrecision = 0.0f;
    float DSSTAvgIou = 0.0f;
    float DSSTAvgFps = 0.0f;
   //Set the index of target   ECO ====================================================
    std::vector<float> ECOCenterError;
    std::vector<float> ECOIou;
    std::vector<float> ECOFpsEco;
    float ECOSuccessRate = 0.0f;
    float ECOAvgPrecision = 0.0f;
    float ECOAvgIou = 0.0f;
    float ECOAvgFps = 0.0f;

    //metrics is computing toll
    Metrics metrics;

    int f, isLost;
    float x, y, w, h;
    std::string s;
    std::string path;
    ifstream *groundtruth;
    ostringstream osfile;

    if (databaseType == "Demo")
    {
        path = "sequences/Crossing";
        // some of the dataset has '\t' as the delimiter, change it to ','.
        fstream gt(path + "/groundtruth_rect.txt");
        string tmp;
        size_t index = 1;
        while (gt >> tmp)
        {
            if(tmp.find(',')<10)
            {
                break;
            }
            if (index%4 == 0)
            {
            }
            else
            {
                gt << ",";
            }
            index++;
        }
        gt.close();
        // Read the groundtruth bbox
        groundtruth = new ifstream(path + "/groundtruth_rect.txt");
        f = 1;
        getline(*groundtruth, s, ',');
        x = atof(s.c_str());
        getline(*groundtruth, s, ',');
        y = atof(s.c_str());
        getline(*groundtruth, s, ',');
        w = atof(s.c_str());
        getline(*groundtruth, s);
        h = atof(s.c_str());
        cout << f << " " << x << " " << y << " " << w << " " << h << " " << endl;
        // Read images in a folder
        osfile << path << "/img/" << setw(4) << setfill('0') << f << ".jpg";
        cout << osfile.str() << endl;
    }

    Rect2f bboxGroundtruth(x, y, w, h);

    cv::Mat frame = cv::imread(osfile.str().c_str(), CV_LOAD_IMAGE_UNCHANGED);
    cv::Mat frameDraw;
    frame.copyTo(frameDraw);
    if (!frame.data)
    {
        cout << "Could not open or find the image" << std::endl;
        return -1;
    }
    // Draw gt;
    if (databaseType == "Demo")
    {
        rectangle(frameDraw, bboxGroundtruth, Scalar(0, 0, 0), 2, 1);
    }

    // Init the trackers=================================================
    // Create KCFTracker:
    bool HOG = true, FIXEDWINDOW = true, MULTISCALE = true, LAB = true, DSST = false; //LAB color space features
    kcf::KCFTracker kcftracker(HOG, FIXEDWINDOW, MULTISCALE, LAB, DSST);
    Rect2d kcfbbox((int)x, (int)y, (int)w, (int)h);
    kcftracker.init(frame, kcfbbox);

    // Create DSSTTracker:
    DSST = true;
    kcf::KCFTracker dssttracker(HOG, FIXEDWINDOW, MULTISCALE, LAB, DSST);
    Rect2d dsstbbox((int)x, (int)y, (int)w, (int)h);
    dssttracker.init(frame, dsstbbox);
#ifdef USE_CAFFE
    // Create GOTURN tracker:
    const string model_file = "goturn/nets/deploy.prototxt";
    const string pretrain_file = "goturn/nets/goturun_tracker.caffemodel";
    int gpu_id = 0;
    Regressor regressor(model_file, pretrain_file, gpu_id, false);
    goturn::Tracker goturntracker(false);
    cv::Rect goturnbbox(x, y, w, h);
    BoundingBox bbox_gt;
    BoundingBox bbox_estimate_uncentered;
    bbox_gt.getRect(goturnbbox);
    goturntracker.Init(frame, bbox_gt, &regressor);
#endif
   
    // Create ECO trakcer;
    eco::ECO ecotracker;
    Rect2f ecobbox(x, y, w, h);
    eco::EcoParameters parameters;
    //parameters.max_score_threshhold = 0.5;
    // when use cn feature:
    parameters.useCnFeature = false;  //false or true is all ok  
    parameters.cn_features.fparams.tablename = "/usr/local/include/opentracker/eco/look_tables/CNnorm.txt";
    ecotracker.init(frame, ecobbox, parameters);
   
    while (frame.data)
    {
        frame.copyTo(frameDraw);

        //KCF=========================
        double timerkcf = (double)getTickCount();
        bool okkcf = kcftracker.update(frame, kcfbbox);
        float fpskcf = getTickFrequency() / ((double)getTickCount() - timerkcf);
        if (okkcf)
        {
            rectangle(frameDraw, kcfbbox, Scalar(0, 255, 0), 2, 1);
        }
        else
        {
            putText(frameDraw, "Kcf tracking failure detected", cv::Point(10, 80), FONT_HERSHEY_SIMPLEX,
                    0.75, Scalar(0, 255, 0), 2);

            cout << "Kcf tracking failure detected!" << std::endl;
        }

        //DSST========================
        double timerdsst = (double)getTickCount();
        bool okdsst = dssttracker.update(frame, dsstbbox);
        float fpsdsst = getTickFrequency() / ((double)getTickCount() - timerdsst);
        if (okdsst)
        {
            rectangle(frameDraw, dsstbbox, Scalar(0, 0, 255), 2, 1);   //red
        }
        else
        {
            putText(frameDraw, "DSST tracking failure detected", cv::Point(10, 110), FONT_HERSHEY_SIMPLEX,
                    0.75, Scalar(0, 0, 255), 2);

            cout << "DSST tracking failure detected!" << std::endl;
        }


#ifdef USE_CAFFE
        //GOTURN=====================
        double timergoturn = (double)getTickCount();
        goturntracker.Track(frame, &regressor, &bbox_estimate_uncentered);
        bbox_estimate_uncentered.putRect(goturnbbox);
        float fpsgoturn = getTickFrequency() / ((double)getTickCount() - timergoturn);
        rectangle(frameDraw, goturnbbox, Scalar(255, 255, 0), 2, 1);
#endif 

        //ECO========================
        double timeeco = (double)getTickCount();
        bool okeco = ecotracker.update(frame, ecobbox);
        float fpseco = getTickFrequency() / ((double)getTickCount() - timeeco);
        if (okeco)
        {
            rectangle(frameDraw, ecobbox, Scalar(255, 0, 255), 2, 1);
        }
        else
        {
            putText(frameDraw, "ECO tracking failure detected", cv::Point(10, 140), FONT_HERSHEY_SIMPLEX,
                    0.75, Scalar(255, 0, 255), 2);

            cout << "ECO tracking failure detected!" << std::endl;
        }

        // Display FPS on frameDraw
        ostringstream os;
        os << float(fpseco);
        putText(frameDraw, "FPS: " + os.str(), Point(100, 30), FONT_HERSHEY_SIMPLEX,
                0.75, Scalar(255, 0, 255), 2);

        // Draw the label of trackers
        putText(frameDraw, "KCF ", cv::Point(frameDraw.cols - 180, 75), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(0, 255, 0), 2);
        line(frameDraw, cv::Point(frameDraw.cols - 100, 75), cv::Point(frameDraw.cols - 10, 75), Scalar(0, 255, 0), 2, 1);
        putText(frameDraw, "DSST ", cv::Point(frameDraw.cols - 180, 100), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(0, 0, 255), 2);
        line(frameDraw, cv::Point(frameDraw.cols - 100, 100), cv::Point(frameDraw.cols - 10, 100), Scalar(0, 0, 255), 2, 1);
        putText(frameDraw, "ECO ", cv::Point(frameDraw.cols - 180, 125), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(255, 0, 255), 2);
        line(frameDraw, cv::Point(frameDraw.cols - 100, 125), cv::Point(frameDraw.cols - 10, 125), Scalar(255, 0, 255), 2, 1);
#ifdef USE_CAFFE 
        putText(frameDraw, "GOTURN ", cv::Point(frameDraw.cols - 180, 150), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(255, 255, 0), 2);
        line(frameDraw, cv::Point(frameDraw.cols - 100, 150), cv::Point(frameDraw.cols - 10, 150), Scalar(255, 255, 0), 2, 1);
#endif
        // Display frameDraw
        imshow("OpenTracker", frameDraw);
       

        int c = cvWaitKey(1);
        if (c != -1)
            c = c % 256;
        if (c == 27)
        {
            cvDestroyWindow("OpenTracker");
            return 0;
        }
        waitKey(1);

        // Read the next frame======================================================
       // cout << "Frame:" << f << " FPS:" << fpseco << endl;
        f++;
        osfile.str("");
        if (databaseType == "Demo")
        {
            getline(*groundtruth, s, ',');
            x = atof(s.c_str());
            getline(*groundtruth, s, ',');
            y = atof(s.c_str());
            getline(*groundtruth, s, ',');
            w = atof(s.c_str());
            getline(*groundtruth, s);
            h = atof(s.c_str());
            //cout << f << " " << x << " " << y << " " << w << " " << h << " " << isLost << endl;
            // Read images in a folder
            osfile << path << "/img/" << setw(4) << setfill('0') << f << ".jpg";
            //cout << osfile.str() << endl;
        }

        bboxGroundtruth.x = x;
        bboxGroundtruth.y = y;
        bboxGroundtruth.width = w;
        bboxGroundtruth.height = h;
        frame = cv::imread(osfile.str().c_str(), CV_LOAD_IMAGE_UNCHANGED);
        if(!frame.data)
        {
            break;
        }

       // Calculate the metrics;
       // KCF index ===========================================================
        float kcfcentererror = metrics.center_error(kcfbbox, bboxGroundtruth);
        float kcfiou = metrics.iou(kcfbbox, bboxGroundtruth);
        KCFCenterError.push_back(kcfcentererror);
        KCFIou.push_back(kcfiou);
       //   KCFFpsEco.push_back(fpseco);

        if(kcfcentererror <= 20)
        {
            KCFAvgPrecision++;
        }
        if(kcfiou >= 0.5)
        {
           KCFSuccessRate++;
        }

        //DSST index =============================================================
        float dsstcentererror = metrics.center_error(dsstbbox, bboxGroundtruth);
        float dsstiou = metrics.iou(dsstbbox, bboxGroundtruth);
        DSSTCenterError.push_back(dsstcentererror);
        DSSTIou.push_back(dsstiou);
       // DSSTFpsEco.push_back(fpseco);

        if(dsstcentererror <= 20)
        {
            DSSTAvgPrecision++;
        }
        if(dsstiou >= 0.5)
        {
           DSSTSuccessRate++;
        }

        // ECO index ============================================================
        float ecocentererror = metrics.center_error(ecobbox, bboxGroundtruth);
        float ecoiou = metrics.iou(ecobbox, bboxGroundtruth);
        ECOCenterError.push_back(ecocentererror);
        ECOIou.push_back(ecoiou);
        ECOFpsEco.push_back(fpseco);

        if(ecocentererror <= 20)
        {
            ECOAvgPrecision++;
        }
        if(ecoiou >= 0.5)
        {
           ECOSuccessRate++;
        }
    }
#ifdef USE_MULTI_THREAD
    void *status;
    int rc = pthread_join(ecotracker.thread_train_, &status);
    if (rc)
    {
         cout << "Error:unable to join," << rc << std::endl;
         exit(-1);
    }
#endif
    cout << std::endl;
    cout << std::endl;
    cout << "Frames:" << f - 2 << std::endl << std::endl;

    //Cout KCF 
    KCFAvgPrecision /= (float)(f - 2);
    KCFSuccessRate /= (float)(f - 2);
    KCFAvgIou = std::accumulate(KCFIou.begin(), KCFIou.end(), 0.0f) / KCFIou.size();
   // KCFAvgFps = std::accumulate(FpsEco.begin(), FpsEco.end(), 0.0f) / FpsEco.size();
   cout << "KCF result:"
         << "\tKCFAvgPrecision:  " << KCFAvgPrecision  //Mean Average Precission 
         << "\tKCFAvgIou:  " << KCFAvgIou 
         << "\tKCFSuccessRate:  " << KCFSuccessRate
         << std::endl << std::endl;

    //Cout DSST
    DSSTAvgPrecision /= (float)(f - 2);
    DSSTSuccessRate /= (float)(f - 2);
    DSSTAvgIou = std::accumulate(DSSTIou.begin(), DSSTIou.end(), 0.0f) / DSSTIou.size();
   // KCFAvgFps = std::accumulate(FpsEco.begin(), FpsEco.end(), 0.0f) / FpsEco.size();
   cout << "DSST result:"
         << "\tDSSTAvgPrecision:  " << DSSTAvgPrecision  //Mean Average Precission 
         << "\tDSSTAvgIou:  " << DSSTAvgIou 
         << "\tDSSTSuccessRate:  " << DSSTSuccessRate
         << std::endl << std::endl;

    //Cout ECO
    ECOAvgPrecision /= (float)(f - 2);
    ECOSuccessRate /= (float)(f - 2);
    ECOAvgIou = std::accumulate(ECOIou.begin(), ECOIou.end(), 0.0f) / ECOIou.size();
    ECOAvgFps = std::accumulate(ECOFpsEco.begin(), ECOFpsEco.end(), 0.0f) / ECOFpsEco.size();
    cout << "ECO result:" 
         << "\tECOAvgPrecision:  " << ECOAvgPrecision  //Mean Average Precission 
         << "\tECOAvgIou:  " << ECOAvgIou 
         << "\tECOSuccessRate:  " << ECOSuccessRate
         << "\tECOAvgFps:  "<< ECOAvgFps
         << std::endl << std::endl;

    cvDestroyWindow("OpenTracker");
    return 0;
}

4、算法不足的分析及改进


未完待续

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

经纬的无疆

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

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

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

打赏作者

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

抵扣说明:

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

余额充值