latentsvm_multidetect.cpp 5 KB
Newer Older
1 2 3 4 5
#include <iostream>
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/contrib/contrib.hpp"

6
#if defined(WIN32) || defined(_WIN32)
7
#include <io.h>
8 9 10 11
#else
#include <dirent.h>
#endif

12 13
#ifdef HAVE_CVCONFIG_H
#include <cvconfig.h>
14 15 16 17 18 19 20 21 22
#endif

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

using namespace std;
using namespace cv;

23
static void help()
24 25
{
    cout << "This program demonstrated the use of the latentSVM detector." << endl <<
26
            "It reads in a trained object models and then uses them to detect the objects in an images." << endl <<
27 28
             endl <<
            "Call:" << endl <<
29 30 31
            "./latentsvm_multidetect <imagesFolder> <modelsFolder> [<overlapThreshold>][<threadsNumber>]" << endl <<
            "<overlapThreshold> - threshold for the non-maximum suppression algorithm." << endl <<
            "Example of <modelsFolder> is opencv_extra/testdata/cv/latentsvmdetector/models_VOC2007" << endl <<
32 33 34 35 36 37 38
             endl <<
            "Keys:" << endl <<
            "'n' - to go to the next image;" << endl <<
            "'esc' - to quit." << endl <<
            endl;
}

39
static void detectAndDrawObjects( Mat& image, LatentSvmDetector& detector, const vector<Scalar>& colors, float overlapThreshold, int numThreads )
40 41 42 43 44
{
    vector<LatentSvmDetector::ObjectDetection> detections;

    TickMeter tm;
    tm.start();
45
    detector.detect( image, detections, overlapThreshold, numThreads);
46 47 48 49 50 51 52 53 54 55
    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];
56
        rectangle( image, od.rect, colors[od.classID], 3 );
57 58 59 60 61 62
    }
    // put text over the all rectangles
    for( size_t i = 0; i < detections.size(); i++ )
    {
        const LatentSvmDetector::ObjectDetection& od = detections[i];
        putText( image, classNames[od.classID], Point(od.rect.x+4,od.rect.y+13), FONT_HERSHEY_SIMPLEX, 0.55, colors[od.classID], 2 );
63 64 65
    }
}

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

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

74 75
    intptr_t h_file = _findfirst( str.c_str(), &s_file );
    if( h_file != static_cast<intptr_t>(-1.0) )
76 77 78 79 80 81 82 83 84 85 86
    {
        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 );
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
#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) );
        }
    }
#endif

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

int main(int argc, char* argv[])
{
107
    help();
108 109

    string images_folder, models_folder;
110
    float overlapThreshold = 0.2f;
111 112
    int numThreads = -1;
    if( argc > 2 )
113
    {
114 115
        images_folder = argv[1];
        models_folder = argv[2];
116
        if( argc > 3 ) overlapThreshold = (float)atof(argv[3]);
117 118 119 120 121 122 123
        if( overlapThreshold < 0 || overlapThreshold > 1)
        {
            cout << "overlapThreshold must be in interval (0,1)." << endl;
            exit(-1);
        }

        if( argc > 4 ) numThreads = atoi(argv[4]);
124
    }
125 126 127 128 129 130 131 132 133 134 135 136

    vector<string> images_filenames, models_filenames;
    readDirectory( images_folder, images_filenames );
    readDirectory( models_folder, models_filenames );

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

137 138 139 140 141 142 143 144 145 146
    const vector<string>& classNames = detector.getClassNames();
    cout << "Loaded " << classNames.size() << " models:" << endl;
    for( size_t i = 0; i < classNames.size(); i++ )
    {
        cout << i << ") " << classNames[i] << "; ";
    }
    cout << endl;

    cout << "overlapThreshold = " << overlapThreshold << endl;

147 148
    vector<Scalar> colors;
    generateColors( colors, detector.getClassNames().size() );
149 150 151 152 153 154 155

    for( size_t i = 0; i < images_filenames.size(); i++ )
    {
        Mat image = imread( images_filenames[i] );
        if( image.empty() )  continue;

        cout << "Process image " << images_filenames[i] << endl;
156
        detectAndDrawObjects( image, detector, colors, overlapThreshold, numThreads );
157 158 159

        imshow( "result", image );

160
        for(;;)
161 162 163 164 165 166 167 168
        {
            int c = waitKey();
            if( (char)c == 'n')
                break;
            else if( (char)c == '\x1b' )
                exit(0);
        }
    }
169 170

    return 0;
171
}