Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

HoG detectMultiScale API not able to detect exact object

Hello Sir,

I want detect object from image. Study Hog from https://www.learnopencv.com/histogram-of-oriented-gradients/

1)Create 100 positive image . Please see below images as a some positive sample.

C:\fakepath\AppService.png C:\fakepath\filename=4075.png C:\fakepath\filename=12068.png C:\fakepath\filename=12936.png C:\fakepath\filename=31908.png

2)Create 30 negative image. Please see below images as a some negative sample.

C:\fakepath\filename=4037.png
C:\fakepath\filename=7277.png
C:\fakepath\Negative=2300.png

3)Using this example for train and test HOG https://github.com/opencv/opencv/blob/master/samples/cpp/train_HOG.cpp I modify main function only to give fix path for above image .

int main()
{
    const char* keys =
    {
        "{help h|     | show help message}"
        "{pd    |     | path of directory contains positive images}"
        "{nd    |     | path of directory contains negative images}"
        "{td    |     | path of directory contains test images}"
        "{tv    |     | test video file name}"
        "{dw    |     | width of the detector}"
        "{dh    |     | height of the detector}"
        "{d     |false| train twice}"
        "{t     |false| test a trained detector}"
        "{v     |false| visualize training steps}"
        "{fn    |my_detector.yml| file name of trained SVM}"
    };


    string pos_dir = "D:\\HogImage\\Positive ";
    string neg_dir = "D:\\HogImage\\Negative";

    //String pos_dir = parser.get< String >("pd");
    //String neg_dir = parser.get< String >("nd");
    String test_dir = "D:\\1\\P";// parser.get< String >("td");
    String obj_det_filename = "D:\\1\\de.ylm";// parser.get< String >("fn");
    int detector_width = 80;// 83;
    int detector_height = 16;
    bool test_detector = false;  //parser.get< bool >("t");
    bool train_twice = true;// parser.get< bool >("d");
    bool visualization = true;// parser.get< bool >("v");
    string videofilename = "D:\\1\\sa.png";
    if (test_detector)
    {
        test_trained_detector(obj_det_filename, test_dir, videofilename);
        return 0;
    }

    if (pos_dir.empty() || neg_dir.empty())
    {   
        }

    vector< Mat > pos_lst, full_neg_lst, neg_lst, gradient_lst;
    vector< int > labels;

    clog << "Positive images are being loaded...";
    load_images(pos_dir, pos_lst, visualization);

    if (pos_lst.size() > 0)
    {
        clog << "...[done]" << endl;
    }
    else
    {
        clog << "no image in " << pos_dir << endl;
        return 1;
    }

    Size pos_image_size = pos_lst[0].size();

    for (size_t i = 0; i < pos_lst.size(); ++i)
    {
        if (pos_lst[i].size() != pos_image_size)
        {
            cout << "All positive images should be same size!" << endl;
            exit(1);
        }
    }

    pos_image_size = pos_image_size / 8 * 8;

    if (detector_width && detector_height)
    {
        pos_image_size = Size(detector_width, detector_height);
    }

    labels.assign(pos_lst.size(), +1);
    const unsigned int old = (unsigned int)labels.size();

    clog << "Negative images are being loaded...";
    load_images(neg_dir, full_neg_lst, false);
    sample_negex(full_neg_lst, neg_lst, pos_image_size);
    clog << "...[done]" << endl;

    labels.insert(labels.end(), neg_lst.size(), -1);
    CV_Assert(old < labels.size());

    clog << "Histogram of Gradients are being calculated for positive images...";
    computeHOGs(pos_image_size, pos_lst, gradient_lst);
    clog << "...[done]" << endl;

    clog << "Histogram of Gradients are being calculated for negative images...";
    computeHOGs(pos_image_size, neg_lst, gradient_lst);
    clog << "...[done]" << endl;

    Mat train_data;
    convert_to_mlex(gradient_lst, train_data);

    clog << "Training SVM...";
    Ptr< SVM > svm = SVM::create();
    /* Default values to train SVM */
    svm->setCoef0(0.0);
    svm->setDegree(3);
    svm->setTermCriteria(TermCriteria(CV_TERMCRIT_ITER + CV_TERMCRIT_EPS, 1000, 1e-3));
    svm->setGamma(0);
    svm->setKernel(SVM::LINEAR);
    svm->setNu(0.5);
    svm->setP(0.1); // for EPSILON_SVR, epsilon in loss function?
    svm->setC(0.01); // From paper, soft classifier
    svm->setType(SVM::EPS_SVR); // C_SVC; // EPSILON_SVR; // may be also NU_SVR; // do regression task
    svm->train(train_data, ROW_SAMPLE, Mat(labels));
    clog << "...[done]" << endl;

    if (train_twice)
    {
        clog << "Testing trained detector on negative images. This may take a few minutes...";
        HOGDescriptor my_hog;
        my_hog.winSize = pos_image_size;

        // Set the trained svm to my_hog
        vector< float > hog_detector;
        get_svm_detectorex(svm, hog_detector);
        my_hog.setSVMDetector(hog_detector);

        vector< Rect > detections;
        vector< double > foundWeights;

        for (size_t i = 0; i < full_neg_lst.size(); i++)
        {
            my_hog.detectMultiScale(full_neg_lst[i], detections, foundWeights);
            for (size_t j = 0; j < detections.size(); j++)
            {
                Mat detection = full_neg_lst[i](detections[j]).clone();
                resize(detection, detection, pos_image_size);
                neg_lst.push_back(detection);
            }
            if (visualization)
            {
                for (size_t j = 0; j < detections.size(); j++)
                {
                    rectangle(full_neg_lst[i], detections[j], Scalar(0, 255, 0), 2);
                }
                imshow("testing trained detector on negative images", full_neg_lst[i]);
                waitKey(5);
            }
        }
        clog << "...[done]" << endl;

        labels.clear();
        labels.assign(pos_lst.size(), +1);
        labels.insert(labels.end(), neg_lst.size(), -1);

        gradient_lst.clear();
        clog << "Histogram of Gradients are being calculated for positive images...";
        computeHOGs(pos_image_size, pos_lst, gradient_lst);
        clog << "...[done]" << endl;

        clog << "Histogram of Gradients are being calculated for negative images...";
        computeHOGs(pos_image_size, neg_lst, gradient_lst);
        clog << "...[done]" << endl;

        clog << "Training SVM again...";
        convert_to_mlex(gradient_lst, train_data);
        svm->train(train_data, ROW_SAMPLE, Mat(labels));
        clog << "...[done]" << endl;
    }

    vector< float > hog_detector;
    get_svm_detectorex(svm, hog_detector);
    HOGDescriptor hog;
    hog.winSize = pos_image_size;
    hog.setSVMDetector(hog_detector);
    hog.save(obj_det_filename);

    test_trained_detector(obj_det_filename, test_dir, videofilename);

    return 0;
}

VOID TrainHOGEx::TestEx()
{
    mainTestEx();
}

4) Test result result. C:\fakepath\Result.png It suppose to detect this image C:\fakepath\AppService.png .

Please guide my how to fix this issue?

Thanks, Mahendra

HoG detectMultiScale API not able to detect exact object

Hello Sir,

I want detect object from image. Study Hog from https://www.learnopencv.com/histogram-of-oriented-gradients/

Source image with different scale

C:\fakepath\AppService.png C:\fakepath\filename=4075.png C:\fakepath\filename=12068.png C:\fakepath\filename=12936.png C:\fakepath\filename=31908.png

2)Create 30 negative image. Please see below images as a some negative sample.

C:\fakepath\filename=4037.png
C:\fakepath\filename=7277.png
C:\fakepath\Negative=2300.png

3)Using this example for train and test HOG https://github.com/opencv/opencv/blob/master/samples/cpp/train_HOG.cpp I modify main function only to give fix path for above image .

int main()
{
    const char* keys =
    {
        "{help h|     | show help message}"
        "{pd    |     | path of directory contains positive images}"
        "{nd    |     | path of directory contains negative images}"
        "{td    |     | path of directory contains test images}"
        "{tv    |     | test video file name}"
        "{dw    |     | width of the detector}"
        "{dh    |     | height of the detector}"
        "{d     |false| train twice}"
        "{t     |false| test a trained detector}"
        "{v     |false| visualize training steps}"
        "{fn    |my_detector.yml| file name of trained SVM}"
    };


    string pos_dir = "D:\\HogImage\\Positive ";
    string neg_dir = "D:\\HogImage\\Negative";

    //String pos_dir = parser.get< String >("pd");
    //String neg_dir = parser.get< String >("nd");
    String test_dir = "D:\\1\\P";// parser.get< String >("td");
    String obj_det_filename = "D:\\1\\de.ylm";// parser.get< String >("fn");
    int detector_width = 80;// 83;
    int detector_height = 16;
    bool test_detector = false;  //parser.get< bool >("t");
    bool train_twice = true;// parser.get< bool >("d");
    bool visualization = true;// parser.get< bool >("v");
    string videofilename = "D:\\1\\sa.png";
    if (test_detector)
    {
        test_trained_detector(obj_det_filename, test_dir, videofilename);
        return 0;
    }

    if (pos_dir.empty() || neg_dir.empty())
    {   
        }

    vector< Mat > pos_lst, full_neg_lst, neg_lst, gradient_lst;
    vector< int > labels;

    clog << "Positive images are being loaded...";
    load_images(pos_dir, pos_lst, visualization);

    if (pos_lst.size() > 0)
    {
        clog << "...[done]" << endl;
    }
    else
    {
        clog << "no image in " << pos_dir << endl;
        return 1;
    }

    Size pos_image_size = pos_lst[0].size();

    for (size_t i = 0; i < pos_lst.size(); ++i)
    {
        if (pos_lst[i].size() != pos_image_size)
        {
            cout << "All positive images should be same size!" << endl;
            exit(1);
        }
    }

    pos_image_size = pos_image_size / 8 * 8;

    if (detector_width && detector_height)
    {
        pos_image_size = Size(detector_width, detector_height);
    }

    labels.assign(pos_lst.size(), +1);
    const unsigned int old = (unsigned int)labels.size();

    clog << "Negative images are being loaded...";
    load_images(neg_dir, full_neg_lst, false);
    sample_negex(full_neg_lst, neg_lst, pos_image_size);
    clog << "...[done]" << endl;

    labels.insert(labels.end(), neg_lst.size(), -1);
    CV_Assert(old < labels.size());

    clog << "Histogram of Gradients are being calculated for positive images...";
    computeHOGs(pos_image_size, pos_lst, gradient_lst);
    clog << "...[done]" << endl;

    clog << "Histogram of Gradients are being calculated for negative images...";
    computeHOGs(pos_image_size, neg_lst, gradient_lst);
    clog << "...[done]" << endl;

    Mat train_data;
    convert_to_mlex(gradient_lst, train_data);

    clog << "Training SVM...";
    Ptr< SVM > svm = SVM::create();
    /* Default values to train SVM */
    svm->setCoef0(0.0);
    svm->setDegree(3);
    svm->setTermCriteria(TermCriteria(CV_TERMCRIT_ITER + CV_TERMCRIT_EPS, 1000, 1e-3));
    svm->setGamma(0);
    svm->setKernel(SVM::LINEAR);
    svm->setNu(0.5);
    svm->setP(0.1); // for EPSILON_SVR, epsilon in loss function?
    svm->setC(0.01); // From paper, soft classifier
    svm->setType(SVM::EPS_SVR); // C_SVC; // EPSILON_SVR; // may be also NU_SVR; // do regression task
    svm->train(train_data, ROW_SAMPLE, Mat(labels));
    clog << "...[done]" << endl;

    if (train_twice)
    {
        clog << "Testing trained detector on negative images. This may take a few minutes...";
        HOGDescriptor my_hog;
        my_hog.winSize = pos_image_size;

        // Set the trained svm to my_hog
        vector< float > hog_detector;
        get_svm_detectorex(svm, hog_detector);
        my_hog.setSVMDetector(hog_detector);

        vector< Rect > detections;
        vector< double > foundWeights;

        for (size_t i = 0; i < full_neg_lst.size(); i++)
        {
            my_hog.detectMultiScale(full_neg_lst[i], detections, foundWeights);
            for (size_t j = 0; j < detections.size(); j++)
            {
                Mat detection = full_neg_lst[i](detections[j]).clone();
                resize(detection, detection, pos_image_size);
                neg_lst.push_back(detection);
            }
            if (visualization)
            {
                for (size_t j = 0; j < detections.size(); j++)
                {
                    rectangle(full_neg_lst[i], detections[j], Scalar(0, 255, 0), 2);
                }
                imshow("testing trained detector on negative images", full_neg_lst[i]);
                waitKey(5);
            }
        }
        clog << "...[done]" << endl;

        labels.clear();
        labels.assign(pos_lst.size(), +1);
        labels.insert(labels.end(), neg_lst.size(), -1);

        gradient_lst.clear();
        clog << "Histogram of Gradients are being calculated for positive images...";
        computeHOGs(pos_image_size, pos_lst, gradient_lst);
        clog << "...[done]" << endl;

        clog << "Histogram of Gradients are being calculated for negative images...";
        computeHOGs(pos_image_size, neg_lst, gradient_lst);
        clog << "...[done]" << endl;

        clog << "Training SVM again...";
        convert_to_mlex(gradient_lst, train_data);
        svm->train(train_data, ROW_SAMPLE, Mat(labels));
        clog << "...[done]" << endl;
    }

    vector< float > hog_detector;
    get_svm_detectorex(svm, hog_detector);
    HOGDescriptor hog;
    hog.winSize = pos_image_size;
    hog.setSVMDetector(hog_detector);
    hog.save(obj_det_filename);

    test_trained_detector(obj_det_filename, test_dir, videofilename);

    return 0;
}

VOID TrainHOGEx::TestEx()
{
    mainTestEx();
}

4) Test result result. C:\fakepath\Result.png It suppose to detect this image C:\fakepath\AppService.png .

Please guide my how to fix this issue?

Thanks, Mahendra