使用潜在SVMDetector检测视频中的对象

detect object from video using LatentSVMDetector

本文关键字:视频 对象 检测 SVMDetector      更新时间:2023-10-16

我在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. 调整为10x5像素是车架中可能最小的汽车的大小;
  2. 先做一个模糊; 有可能得到很多误报,因为有噪音会产生与汽车相似的边缘;
  3. 我想探测器是针对边车的(我还没有测试过),它不会检测到旋转超过60度的汽车,它是在与你的环境不相似的数据库上训练的;所以也许最好训练你自己的探测器(car.xml)。

HOG是基于边缘和边缘对光影非常敏感。在检测汽车之前,尝试对帧进行预处理(对比度增强)。