使用LatentSVMDetector从视频中检测对象

时间:2014-02-13 10:37:40

标签: c++ opencv computer-vision

我在opencv中使用Hog + SVM来检测Video avi文件中的汽车。我正在使用car.xml模型文件。 当我使用LatentSvmDetetction检测汽车时,我的效果不佳

  • 框架内有大量错误检测。
  • 这很慢。检测帧中的对象大约需要5秒钟。

请建议我如何改善物体检测时间。

我的代码如下:

#include <iostream>
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/contrib/contrib.hpp"

#if defined(WIN32) || defined(_WIN32)
#include <io.h>
#else
#include <dirent.h>
#endif

#ifdef HAVE_CVCONFIG_H
#include <cvconfig.h>
#endif

#ifdef HAVE_TBB
#include "tbb/task_scheduler_init.h"
#endif

using namespace std;
using namespace cv;

static void detectAndDrawObjects( Mat& frame, LatentSvmDetector& detector, const vector<Scalar>& colors, float overlapThreshold, int numThreads )
{
    vector<LatentSvmDetector::ObjectDetection> detections;

    TickMeter tm;
    tm.start();
    detector.detect( frame, detections, overlapThreshold, numThreads);
    tm.stop();

    cout << "Detection time = " << tm.getTimeSec() << " sec" << endl;

    const vector<string> classNames = detector.getClassNames();
    CV_Assert( colors.size() == classNames.size() );

    for( size_t i = 0; i < detections.size(); i++ )
    {
        const LatentSvmDetector::ObjectDetection& od = detections[i];
        rectangle( frame, od.rect, colors[od.classID], 3 );
        putText( frame, classNames[od.classID], Point(od.rect.x+4,od.rect.y+13), FONT_HERSHEY_SIMPLEX, 0.55, colors[od.classID], 2 );
    }
}

static void readDirectory( const string& directoryName, vector<string>& filenames, bool addDirectoryName=true )
{
    filenames.clear();

#if defined(WIN32) | defined(_WIN32)
    struct _finddata_t s_file;
    string str = directoryName + "\\*.*";

    intptr_t h_file = _findfirst( str.c_str(), &s_file );
    if( h_file != static_cast<intptr_t>(-1.0) )
    {
        do
        {
            if( addDirectoryName )
                filenames.push_back(directoryName + "\\" + s_file.name);
            else
                filenames.push_back((string)s_file.name);
        }
        while( _findnext( h_file, &s_file ) == 0 );
    }
    _findclose( h_file );
#else
    DIR* dir = opendir( directoryName.c_str() );
    if( dir != NULL )
    {
        struct dirent* dent;
        while( (dent = readdir(dir)) != NULL )
        {
            if( addDirectoryName )
                filenames.push_back( directoryName + "/" + string(dent->d_name) );
            else
                filenames.push_back( string(dent->d_name) );
        }

        closedir( dir );
    }
#endif

    sort( filenames.begin(), filenames.end() );
}

int main()
{
        string frames_folder, models_folder;
        float overlapThreshold = 0.2f;
        int numThreads = -1;
        models_folder = "D:\\Downloads\\models_VOC2007";
        VideoCapture cap("D:\\images\\videos\\vid2.AVI"); // open the video file for reading
        cvNamedWindow("MyVideo", CV_WINDOW_AUTOSIZE);
        if ( !cap.isOpened() )  // if not success, exit program
        {
            cout << "Cannot open the video file" << endl;
            return -1;
        }

        LatentSvmDetector detector( models_filenames );
        if( detector.empty() )
        {
            cout << "Models cann't be loaded" << endl;
            exit(-1);
        }

        vector<Scalar> colors;
        generateColors( colors, detector.getClassNames().size() );

        Mat frame;
        while(1)
        {

            bool bSuccess = cap.read(frame);
            if (!bSuccess) //if not success, break loop
            {
                cout << "Cannot read the frame from video file" << endl;
                break;
            }
            detectAndDrawObjects( frame, detector, colors, overlapThreshold, numThreads );
            imshow( "MyVideo", frame );
            //imshow("video", frame); //show the frame in "MyVideo" window
              if(waitKey(30) == 27) //wait for 'esc' key press for 30 ms. If 'esc' key is pressed, break loop
              {
                cout << "esc key is pressed by user" << endl;
                break;
              }
        }
        return 0;
}

1 个答案:

答案 0 :(得分:1)

我建议你

  1. 将帧的大小调整为10x5像素是帧中可能最小的汽车的大小;
  2. 先做模糊;可能会产生大量误报,因为有噪音会产生类似于汽车的边缘;
  3. 我认为探测器适用于侧面车(我没有测试过),它不会检测到旋转超过60度的车辆,而且它在一些与您的环境不相似的数据库上进行训练;所以也许最好训练你自己的探测器(car.xml)。
  4. HOG基于边缘,边缘对光线和阴影非常敏感。尝试在检测车辆之前对帧进行预处理(对比度增强)。