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
Integer Division Rounding with Negatives in C++
Why Is a Constexpr Function on a Reference Not Constexpr
Beyond Stack Sampling: C++ Profilers
How to Solve Memory Fragmentation
Video Stabilization with Opencv
How to Link a Plain File into My Executable
Is There Any Lame C++ Wrapper\Simplifier (Working on Linux MAC and Win from Pure Code)
What Happens If 'Throw' Fails to Allocate Memory for Exception Object
Converting Between Local Times and Gmt/Utc in C/C++
How to Target Windows Xp in Microsoft Visual Studio C++
How to Get the Window Handle of the Desktop
Friend Class with Limited Access
Why Is There No Support for Concatenating Std::String and Std::String_View
How to Use Identical Names for Fields and Constructor Parameters
How to Print 0X0A Instead of 0Xa Using Cout