如何修复HOG以检测场景中的所有人?

时间:2016-05-16 14:36:57

标签: opencv image-processing

我想使用HOG描述符和SVM检测场景中的人物,但程序没有检测到场景中的所有当前人物:

#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv/cv.h>
#include <iostream>
#include <vector>




using namespace std;
using namespace cv;


vector <Rect> drawBoundingBox (vector<vector<Point> > contours)
{
    vector <Rect> listOfRectangles; 
    for (int i = 0; i< contours.size(); i++)
    {
        // Get bounding box for contour
        Rect roi = boundingRect(contours[i]);
        if (roi.area() > 1000)
        {
            listOfRectangles.push_back(roi);
        }
    }
    //merge rectangles
    int size = listOfRectangles.size();
    for( int k = 0; k < size; k++ )
    {
        listOfRectangles.push_back(Rect(listOfRectangles[k]));
    }
    groupRectangles(listOfRectangles, 1, 0.7);
    return listOfRectangles; 
}


//! main program 
int main(int argc, char* argv[])
{

    Mat frame_capture,frame_capture2;  
    VideoCapture capture("Baseline/PETS2006/input/in%06d.jpg");   // path to input images
    VideoCapture capture2("Baseline/PETS2006/groundtruth/gt%06d.png"); // path to groundtruth images



    if((!capture.isOpened())&(!capture2.isOpened() )) 
    {
        printf("Could not open video file!!!");
        cin.get();
        return -1;
    }

    Mat gray;

    //! do detection and tracking
    int i=0;


    //Hog Descriptor
    cv::HOGDescriptor hog;
    hog.setSVMDetector(cv::HOGDescriptor::getDefaultPeopleDetector());

    while (1)
    {   ++i;
        capture >> frame_capture;
        capture2 >> frame_capture2;
        if(i >= 300){

        cv::cvtColor(frame_capture2,gray, CV_RGB2GRAY);


        cv::Mat im_gray;
        cv::equalizeHist( gray, im_gray );
        vector<vector<Point> > contours;
        vector<Vec4i> hierarchy;
        findContours(gray,contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
        vector <Rect> listOfRectangles;
        listOfRectangles = drawBoundingBox(contours);


         // HOG person detector
            vector <Rect>  detected_person;


         //Hog detectMultiscale
           hog.detectMultiScale(im_gray, detected_person, 0.0, cv::Size(8, 8), cv::Size(0,0), 1.05, 4); 



    if(!frame_capture.empty()){
        for (int i =0; i<detected_person.size();++i)
        {
            //rectangle (frame_capture, listOfRectangles[i], Scalar(255,255,0),1,8,0); //! display detections


            //detected persons
            rectangle(frame_capture, detected_person[i], Scalar(255,255,0),2,8,0);
            //putText(frame_capture,"person", detected_person[i].tl(),FONT_HERSHEY_COMPLEX_SMALL,0.8,cvScalar(200,200,250),1,CV_AA);

        }


    //oVideoWriter.write(frame_capture);
        imshow("video",frame_capture);
        waitKey(25);
    }    
    }
    }
    destroyAllWindows();
    return 0;

}

我得到了这样一个结果detecte person。我怎样才能用这种方法检测场景中的所有人?有谁知道如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

HOG不是一次应用于整个图像,而是应用于从图像中提取的窗口。这些窗口默认为64x128,重叠为8像素。这种检测方法依赖于假设,人类必须粗略地填充整个检测窗口并适合它。当你想要检测大小不同于~64x128的人时,你应该创建一组缩放图像,这样就有更高的机会让人类适应其中一个窗口。

但是,在您的代码中,您使用Form进行分类,并使用getDefaultPeopleDetector(),这基本上可以为您进行扩展。可能还有其他一些问题 - 请注意那两个人在背景中融合了一点,因此他们的边缘可能被HOG误算,分类器可以将它们视为非人物。遮挡可能是另一个问题。

您应该使用其他图像测试您的代码,并检查是否始终出现问题。尝试使用detectMultiScale() - detectMultiScale()的不同参数,其中描述了缩放步骤,scaleFactor描述了将SVM分类为包含人的相邻窗口需要将对象标记为最终。使用RGB而不是灰度也应该改善分类。最后,您还可以尝试训练自己的SVM。

然而,请记住,不可能获得100%的探测器准确度(至少到目前为止)。最好查看Dalal and Triggs article关于行人检测的HOG,了解OpenCV实施过程中发生的事情(部分基于该文章)