我想使用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;
}
答案 0 :(得分:1)
HOG不是一次应用于整个图像,而是应用于从图像中提取的窗口。这些窗口默认为64x128,重叠为8像素。这种检测方法依赖于假设,人类必须粗略地填充整个检测窗口并适合它。当你想要检测大小不同于~64x128的人时,你应该创建一组缩放图像,这样就有更高的机会让人类适应其中一个窗口。
但是,在您的代码中,您使用Form
进行分类,并使用getDefaultPeopleDetector()
,这基本上可以为您进行扩展。可能还有其他一些问题 - 请注意那两个人在背景中融合了一点,因此他们的边缘可能被HOG误算,分类器可以将它们视为非人物。遮挡可能是另一个问题。
您应该使用其他图像测试您的代码,并检查是否始终出现问题。尝试使用detectMultiScale()
- detectMultiScale()
的不同参数,其中描述了缩放步骤,scaleFactor
描述了将SVM分类为包含人的相邻窗口需要将对象标记为最终。使用RGB而不是灰度也应该改善分类。最后,您还可以尝试训练自己的SVM。
然而,请记住,不可能获得100%的探测器准确度(至少到目前为止)。最好查看Dalal and Triggs article关于行人检测的HOG,了解OpenCV实施过程中发生的事情(部分基于该文章)