Ask Your Question
2

OpenCV HOG is not detecting people

asked 2014-07-15 23:54:24 -0500

yohanrw gravatar image

updated 2014-07-16 02:33:54 -0500

berak gravatar image

Hi,

Please have a look at the below code

#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"

#include <stdio.h>
#include <string.h>
#include <ctype.h>

using namespace cv;
using namespace std;

void help()
{
    printf(
        "\nDemonstrate the use of the HoG descriptor using\n"
        "  HOGDescriptor::hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());\n"
        "Usage:\n"
        "./peopledetect (<image_filename> | <image_list>.txt)\n\n");
}

int main()
{
    Mat img;
    char _filename[1024];


    img = imread("C:/Users/yohan/Desktop/dogwalker.jpg");



    HOGDescriptor hog;
    hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());
    namedWindow("people detector", 1);

    for(;;)
    {
        vector<Rect> found, found_filtered;
        double t = (double)getTickCount();
        // run the detector with default parameters. to get a higher hit-rate
        // (and more false alarms, respectively), decrease the hitThreshold and
        // groupThreshold (set groupThreshold to 0 to turn off the grouping completely).
        hog.detectMultiScale(img, found, 0, Size(8,8), Size(32,32), 1.05, 2);
        t = (double)getTickCount() - t;
        printf("tdetection time = %gms\n", t*1000./cv::getTickFrequency());
        size_t i, j;
        for( i = 0; i < found.size(); i++ )
        {
            Rect r = found[i];
            for( j = 0; j < found.size(); j++ )
                if( j != i && (r & found[j]) == r)
                    break;
            if( j == found.size() )
                found_filtered.push_back(r);
        }
        for( i = 0; i < found_filtered.size(); i++ )
        {
            Rect r = found_filtered[i];
            // the HOG detector returns slightly larger rectangles than the real objects.
            // so we slightly shrink the rectangles to get a nicer output.
            r.x += cvRound(r.width*0.1);
            r.width = cvRound(r.width*0.8);
            r.y += cvRound(r.height*0.07);
            r.height = cvRound(r.height*0.8);
            rectangle(img, r.tl(), r.br(), cv::Scalar(0,255,0), 3);
        }
        imshow("people detector", img);
        int c = waitKey(0) & 255;
            break;
    }
    return 0;
}

This is the OpenCV code for detecting humans. But I noticed that this do not detect people in most cases, for an example, please have a look at the below image.

enter image description here

If you run the above code on this, this will not detect the person. What is wrong here? Please help.

edit retag flag offensive close merge delete

Comments

Actually, your step of found to found_filtered is probably screwing your detections up, not to mention the fact that it is completely useless since you are using the grouping parameter already. Remove that part and it will work just fine in 2.4.9.

StevenPuttemans gravatar imageStevenPuttemans ( 2014-07-16 02:34:39 -0500 )edit

@StevenPuttemans: Thanks for the reply and very sorry for the delay of my reply, I do not get email notifications! anyways, I did not understand what you mentioned. Mind providing a code sample?

yohanrw gravatar imageyohanrw ( 2014-07-25 01:47:17 -0500 )edit

Email notifications do not work on this forum, even if you ask to send them ... it is a known bug. I cannot provide full code samples. You have a piece of code like this:

    for( i = 0; i &lt; found.size(); i++ )
    {
        Rect r = found[i];
        for( j = 0; j &lt; found.size(); j++ )
            if( j != i &amp;&amp; (r &amp; found[j]) == r)
                break;
        if( j == found.size() )
            found_filtered.push_back(r);
    }

But afaik you do not need anything like this to filter out detections. Cut it out and retry your code!

StevenPuttemans gravatar imageStevenPuttemans ( 2014-07-25 02:27:18 -0500 )edit

2 answers

Sort by ยป oldest newest most voted
2

answered 2014-07-16 01:35:52 -0500

berak gravatar image

updated 2014-07-16 02:52:34 -0500

well, the latentsvm detector was slow as molasses, but ...

image description

(works nice with sitting people as well.)

just in case, you still want to try it (get the person.xml first):

    vector<String> fn(1,"person.xml"); // from opencv_extra/cv
    LatentSvmDetector late;
    bool ok = late.load(fn);
    //resize(m,m,Size(m.cols*2/3,m.rows*2/3)); // does not detect
    //Mat g; cvtColor(m,g,COLOR_BGR2GRAY);     // throws, it actually wants color !
    vector<LatentSvmDetector::ObjectDetection> dets;
    late.detect(m,dets,0.2f);
    cerr << "frame " << frameid << ",  " << dets.size() << " detections." << endl;
    for (size_t i=0; i<dets.size(); ++i)
    {
        cerr << dets[i].classID << " " << dets[i].rect << " " << dets[i].score << endl;
        if (dets[i].score>0)
            rectangle(m,dets[i].rect,Scalar(0,200,0));
        else if (dets[i].score>-1.0)
            rectangle(m,dets[i].rect,Scalar(0,0,200));
    }

again, the main takeaway seems to me, that this one was trained on the PASCAL/VOC data, while the hog descriptors/cascades used the inria and daimler set.

if you need more poses covered, your train data has to be more diverse.

edit flag offensive delete link more

Comments

1

@berak, think you are mixing stuff up. This solutions uses the LatentSVM, which is part based moddeling, and the topic author uses the Dallal&Triggs HOG + SVM approach which is basically a root model filter only :)

StevenPuttemans gravatar imageStevenPuttemans ( 2014-07-16 02:35:56 -0500 )edit
1

ok, thanks for clarifying. it is a confusing topic. (invalidated the offending part ;)

berak gravatar imageberak ( 2014-07-16 02:51:44 -0500 )edit
2

Haha no problem :) I have been digging in these detection topics for quite some while now, I get it when people get confused, I do too. Discovered today for example that all detection algorithms actually have a score function output but they are not documented ...

StevenPuttemans gravatar imageStevenPuttemans ( 2014-07-16 03:17:01 -0500 )edit

wow, you are awesome! How long did it take to do this task? I mean, how many seconds it took? very sorry for the delayed reply, I never get email notifications :(

yohanrw gravatar imageyohanrw ( 2014-07-25 01:43:42 -0500 )edit

latentSVM takes 1- 5 seconds depending on the size of your model and the size of your image! :)

StevenPuttemans gravatar imageStevenPuttemans ( 2014-07-25 02:28:03 -0500 )edit
1

yes, 3-5 seconds for above

berak gravatar imageberak ( 2014-07-25 02:52:57 -0500 )edit

@berak : The person.xml is not accessible now. Can you provide a new link please

Samjith888 gravatar imageSamjith888 ( 2018-08-22 06:29:09 -0500 )edit
1

Actually it is still there: https://docs.opencv.org/3.4/d5/d33/st... Use the defaultPeopleDetector or the DaimlerPeopleDetector (weights are stored in code, not as separate models anymore)

StevenPuttemans gravatar imageStevenPuttemans ( 2018-08-23 03:00:37 -0500 )edit
2

answered 2015-12-19 11:32:10 -0500

updated 2015-12-19 12:13:51 -0500

[ not an answer ]

i tried to add a border on the image and the result is like this image description

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main (int argc, const char * argv[])
{
    Mat img = imread(argv[1]);
    if( img.empty())
        return -1;

    HOGDescriptor hog;
    hog.setSVMDetector( HOGDescriptor::getDefaultPeopleDetector() );

    vector<Rect> rects;
    copyMakeBorder( img,img,50,50,50,50,0);
    hog.detectMultiScale(img, rects, 0, Size(8,8), Size(32,32), 1.05, 2);

    size_t i;

    for (i=0; i<rects.size(); i++)
    {
        rectangle( img, rects[i], cv::Scalar(0,255,0), 2);
    }

    imshow("result", img);
    waitKey();

    return 0;
}
edit flag offensive delete link more
Login/Signup to Answer

Question Tools

3 followers

Stats

Asked: 2014-07-15 23:54:24 -0500

Seen: 1,985 times

Last updated: Dec 19 '15