Skip to content

Instantly share code, notes, and snippets.

@hcl14
Forked from foundry/peopledetect.cpp
Last active October 10, 2016 20:51
Show Gist options
  • Select an option

  • Save hcl14/fcd37f8a68ad4747c748bec68688b3a9 to your computer and use it in GitHub Desktop.

Select an option

Save hcl14/fcd37f8a68ad4747c748bec68688b3a9 to your computer and use it in GitHub Desktop.
OpenCV Hog Descriptor trial
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <stdio.h>
#include <string.h>
#include <ctype.h>
//#include "openCVUtils.h"
using namespace cv;
using namespace std;
// variables needed for face detection
//need full path there
String face_cascade_name = "/usr/local/share/OpenCV/haarcascades/haarcascade_frontalface_alt.xml";
String eyes_cascade_name = "/usr/local/share/OpenCV/haarcascades/haarcascade_eye_tree_eyeglasses.xml";
CascadeClassifier face_cascade;
CascadeClassifier eyes_cascade;
string window_name = "Capture - Face detection";
RNG rng(12345);
// result from face and eye detection function
struct one_face {
Rect face;
std::vector<Rect> eyes;
};
typedef std::vector<one_face> faces_eyes_result;
// face detection
//http://docs.opencv.org/2.4/doc/tutorials/objdetect/cascade_classifier/cascade_classifier.html
/** @function detectAndDisplay */
// function is called from inside hogDetect();
static faces_eyes_result face_eyes_detect( Mat frame )
{
std::vector<Rect> faces;
faces_eyes_result res;
Mat frame_gray;
cvtColor( frame, frame_gray, CV_BGR2GRAY );
equalizeHist( frame_gray, frame_gray );
//-- Detect faces
face_cascade.detectMultiScale( frame_gray, faces, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(30, 30) );
for( size_t i = 0; i < faces.size(); i++ )
{
//Point center( faces[i].x + faces[i].width*0.5, faces[i].y + faces[i].height*0.5 );
//ellipse( frame, center, Size( faces[i].width*0.5, faces[i].height*0.5), 0, 0, 360, Scalar( 255, 0, 255 ), 4, 8, 0 );
Mat faceROI = frame_gray( faces[i] );
std::vector<Rect> eyes;
//-- In each face, detect eyes
eyes_cascade.detectMultiScale( faceROI, eyes, 1.1, 2, 0 |CV_HAAR_SCALE_IMAGE, Size(30, 30) );
//adding new element to result
one_face tmp;
tmp.face=faces[i];
tmp.eyes=eyes;
res.push_back(tmp);
/*for( size_t j = 0; j < eyes.size(); j++ )
{
Point center( faces[i].x + eyes[j].x + eyes[j].width*0.5, faces[i].y + eyes[j].y + eyes[j].height*0.5 );
int radius = cvRound( (eyes[j].width + eyes[j].height)*0.25 );
circle( frame, center, radius, Scalar( 255, 0, 0 ), 4, 8, 0 );
}*/
}
//-- Show what you got
//imshow( window_name, frame );
return res;
}
//-------------------------------------------------------------------
// variables needed for human detection
static Mat _inImage;
static Mat _outImage;
static HOGDescriptor _hog;
static const char* _windowName = "people detector";
static float _hitThreshold = 0;
static float _scaleFactor = 1.059;
static float _groupThreshold = 0.0;
static int MAX_TRACKBAR = 200;
static int _trackbar1 = _scaleFactor * MAX_TRACKBAR/2.0;
// people detection
// http://stackoverflow.com/questions/31660271/improving-people-detection-with-opencv
static int imshowWithCaption(const char* windowName, Mat inImage, const char* caption )
{
putText( inImage, caption,
Point( MIN(10,inImage.cols), MIN(20,inImage.rows)),
FONT_HERSHEY_PLAIN, 1, Scalar(0, 0, 255) );
imshow( windowName, inImage );
return 0;
}
static void hogDetect () {
_inImage.copyTo(_outImage);
vector<Rect> found;
vector <Rect> found_filtered;
_hog.detectMultiScale(
_inImage //const Mat&
//Matrix of the type CV_8U containing an image where objects are detected.
, found // vector<Rect>& objects
//Vector of rectangles where each rectangle contains the detected object.
, _hitThreshold // hit_threshold=0
//hit_threshold – Threshold for the distance between features and SVM classifying plane. Usually it is 0 and should be specfied in the detector coefficients (as the last free coefficient). But if the free coefficient is omitted (which is allowed), you can specify it manually here.
, Size(8,8)//winSize
//win_stride – Window stride. It must be a multiple of block stride
, Size(32,32)//padding
//padding – Mock parameter to keep the CPU interface compatibility. It must be (0,0).
, _scaleFactor // double scale = 1.05
//scale0 – Coefficient of the detection window increase.
//scaleFactor - Parameter specifying how much the image size is reduced at each image scale.
, _groupThreshold //group_threshold=2
//group_threshold – Coefficient to regulate the similarity threshold. When detected, some objects can be covered by many rectangles. 0 means not to perform grouping. See groupRectangles() .
);
size_t i, j;
for( i = 0; i < found.size(); i++ )
{
Rect r = found[i];
for( j = 0; j < found.size(); j++ ) {
//filter out overlapping rectangles
if ( j!=i ) {
Rect iRect = r;
Rect jRect = found[j];
Rect intersectRect = (iRect & jRect);
if (intersectRect.area()>=iRect.area()*0.9) break;
}
}
if( j == found.size() )
found_filtered.push_back(r);
}
// draw human rectangles
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.5);
// hacky shift right by 40px - rects seem to be shifted consistently
r.x +=-40;
r.width = cvRound(r.width*0.3);
r.y += cvRound(r.height*0.07);
r.height = cvRound(r.height*0.8);
rectangle(_outImage, r.tl(), r.br(), cv::Scalar(0,255,0), 3);
}
//draw faces & eyes
faces_eyes_result f_e = face_eyes_detect(_inImage);
for( size_t i = 0; i < f_e.size(); i++ )
{
// current face
Rect face = f_e[i].face;
Point center( face.x + face.width*0.5, face.y + face.height*0.5 );
ellipse( _outImage, center, Size( face.width*0.5, face.height*0.5), 0, 0, 360, Scalar( 255, 0, 255 ), 4, 8, 0 );
// eyes
std::vector<Rect> eyes = f_e[i].eyes;
for( size_t j = 0; j < f_e[i].eyes.size(); j++ )
{
Point center( face.x + eyes[j].x + eyes[j].width*0.5, face.y + eyes[j].y + eyes[j].height*0.5 );
int radius = cvRound( (eyes[j].width + eyes[j].height)*0.25 );
circle( _outImage, center, radius, Scalar( 255, 0, 0 ), 4, 8, 0 );
}
}
// end drawing faces
//eliminate overlaps
//imshow(_windowName, _outImage);
string param1string = std::string("hitThreshold ") + to_string((int)_hitThreshold);
string param2string = std::string(" groupThreshold ") + to_string((int)_groupThreshold);
string param3string = std::string(" scaleFactor ") + to_string(_scaleFactor);
string combinedString = param1string + param2string + param3string;
const char* captionString = combinedString.c_str();
imshowWithCaption(_windowName, _outImage, captionString);
}
static void hogTrackbarCallback1 (int trackbarPos, void*) {
_trackbar1 = trackbarPos;
_scaleFactor = trackbarPos/100.0;
hogDetect();
}
static void setupHogWindow() {
namedWindow( _windowName, WINDOW_AUTOSIZE );
createTrackbar( "scaleFactor" //– Name of the created trackbar.
, _windowName //– Name of the window that will be used as a parent of the created trackbar.
, &_trackbar1 //– Optional pointer to an integer variable whose value reflects the position of the slider. Upon creation, the slider position is defined by this variable.
, MAX_TRACKBAR //– Maximal position of the slider. The minimal position is always 0.
, hogTrackbarCallback1 //– Pointer to the function to be called every time the slider changes position. This function should be prototyped as void Foo(int,void*); , where the first parameter is the trackbar position and the second parameter is the user data (see the next parameter). If the callback is the NULL pointer, no callbacks are called, but only value is updated.
, nullptr// – User data that is passed as is to the callback. It can be used to handle trackbar events without using global variables.
);
}
//-------------------------------------------------------------------
int main(int argc, char** argv) {
//string filenamestr = assetPath("queue.jpg");
if ( argc != 2 )
{
printf("usage: peopledetect.out <Image_Path>\n");
return -1;
}
//Mat _inImage;
_inImage = imread( argv[1], 1 );
if ( !_inImage.data )
{
printf("No image data \n");
return -1;
}
//-- 1. Load the cascades for face and eyes
if( !face_cascade.load( face_cascade_name ) ){ printf("--(!)Error loading\n"); return -1; };
if( !eyes_cascade.load( eyes_cascade_name ) ){ printf("--(!)Error loading\n"); return -1; };
//imshow("image", _inImage);
//_inImage = imread(filenamestr);
//_hog = HOGDescriptor::HOGDescriptor();
_hog = HOGDescriptor();
_hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());
namedWindow(_windowName, 1);
setupHogWindow();
hogDetect();
//namedWindow("Display Image", WINDOW_AUTOSIZE );
waitKey(0);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment