Recommended Values for Opencv Detectmultiscale() Parameters

Meaning of Parameters of detectMultiScale(a, b, c)

Did you get the code (including the call to detectMultiScale) from somewhere, or write it yourself?

Is it just a matter of trial and error adjusting these last two parameters or can one know how to change them according to the images?

There is some trial and error in fine-tuning, but you should understand all the parameters and choose initial values which give a good level of performance. Then you can use some kind of automatic method for fine-tuning (i.e., iteratively re-train and re-test with different parameter values and see if detection improves or worsens, but be careful of overfitting). Since the parameters form a large multi-dimensional space, finding good parameters randomly is not practical.

Looking at the Python OpenCV bindings, it appears the two numeric parameters you use are scaleFactor and minNeighbors respectively. There is a good explanation of minNeighbours on this question: OpenCV detectMultiScale() minNeighbors parameter. Setting it higher should reduce your false positives, as described there.

The scaleFactor parameter determines a trade-off between detection accuracy and speed. The detection window starts out at size minSize, and after testing all windows of that size, the window is scaled up by scaleFactor and re-tested, and so on until the window reaches or exceeds maxSize. If scaleFactor is large (eg. 2.0), of course there will be fewer steps, so detection is faster, but you may miss objects whose size is in between two tested scales. But Haar-like features are inherently robust to some small variation in scale, so there's no need to make scaleFactor very small (eg. 1.001); that just wastes time with needless steps. That is why the default is 1.3 and not something smaller.

Setting minSize and maxSize is also important to maximise detection speed. Don't test windows that are smaller or larger than the size range you expect given your setup. So you should specify those in your call.

To be honest, I don't see Haar cascade classifiers being that good for detecting pens or spoons in unknown orientations (if that is your use case). Pens are long and thin which is poorly suited to a square detection window. You may have more success with LINEMOD for example.

According to me these two are really significant and make the code very sensitive as it affects false positives. How do I set them properly to reduce false positives ?

While your false negative rate and speed are OK, don't play with scaleFactor, instead work on improving your training data to reduce your high false positive rate. If speed falls to unacceptable levels while doing that (because the cascade grows to include too many classifier stages), revisit scaleFactor.

Can someone explain about detectMultiScale in openCV

Found the answer..! I've missed out the specified arguments for detectMultiScale function.

It's working fine..Rectified code as follows

#include<iostream>
#include "cv.h"
#include "highgui.h"
#include<vector>

using namespace cv;
using namespace std;

int main()
{

IplImage* img;
img = cvLoadImage( "test.jpg" );

vector<cv::Rect> objects;

/*** Resizing is optional***
*****************************

IplImage *resizeImage = cvCreateImage(cvSize(64,64),8,3);

cvResize(img,resizeImage,CV_INTER_LINEAR);
cvShowImage("Resize",resizeImage);
cvWaitKey(0);*/

/*** Change image into grayscale***
**********************************/

IplImage *grayImage = cvCreateImage(cvGetSize(img),8,1);
cvCvtColor(img,grayImage,CV_BGR2GRAY);

//cvEqualizeHist(grayImage,grayImage); This is optional

cvShowImage("gray",grayImage);
cvWaitKey(0);

CvMemStorage* storage = cvCreateMemStorage(0);
cout<<"Memory created\n";

/*** Load the XML generated through haartraining***
**************************************************/

cv::CascadeClassifier cascade;
cascade.load("cascade.xml");
//CvHaarClassifierCascade* cascade = (CvHaarClassifierCascade*)cvLoad( "cascade.xml" );
cout<<"cascade.xml loaded successfully\n";
double scale = 1.3;

static CvScalar colors[] = { {{0,0,255}}, {{0,128,255}}, {{0,255,255}},
{{0,255,0}}, {{255,128,0}}, {{255,255,0}}, {{255,0,0}}, {{255,0,255}} };

/*** Detect objects***
**********************/

cvClearMemStorage( storage );
objects.clear();
//CvSeq* objects = cvHaarDetectObjects( grayImage, cascade, storage, 1.1, 4, 0, cvSize( 40, 50 ));
//cascade.detectMultiScale(grayImage, objects, 1.2, 4, CV_HAAR_DO_CANNY_PRUNING, cvSize(30, 30)); if captured through WebCam
cascade.detectMultiScale(grayImage, objects, 1.1, 3, CV_HAAR_SCALE_IMAGE | CV_HAAR_DO_CANNY_PRUNING,cvSize(0,0), cvSize(100,100));

cout<<"Object size : "<<objects.size();

/***Draw Rectangle outside recognized pattern***
***********************************************/

for( vector<cv::Rect>::const_iterator r = objects.begin(); r != objects.end(); r++)
{ //rectangle(img, *r, Scalar(0,0,255), 2, 8, 0);
cvRectangle( grayImage, cvPoint( r->x, r->y ), cvPoint( r->x + r->width, r->y + r->height ),Scalar(0,0,255));
cout<<"In the loop\n";
}

cvNamedWindow( "Output" );
cvShowImage( "Output", grayImage );
cvWaitKey(0);

//cvReleaseImage(&resizeImage); If resized
cvReleaseImage(&grayImage);
cvReleaseImage( &img );

return 0;
}

And finally this worked..!

PS: This program holds good only when the input is taken through image unlike WebCam or Video.



Related Topics



Leave a reply



Submit