LBP based getMultiScale object detection. [closed]
I trained my system using opencv's traincascade using LBP features for faster training. The result of training is shown below. I used 14 stages.
cascadeDirName: data_cascade/
vecFileName: opencv_createsamples/positive_samples.vec
bgFileName: Doors/negatives.txt
numPos: 4350
numNeg: 2400
numStages: 14
precalcValBufSize[Mb] : 4000
precalcIdxBufSize[Mb] : 5000
stageType: BOOST
featureType: LBP
sampleWidth: 30
sampleHeight: 50
boostType: GAB
minHitRate: 0.999
maxFalseAlarmRate: 0.5
weightTrimRate: 0.95
maxDepth: 1
maxWeakCount: 100
===== TRAINING 13-stage =====
<BEGIN
POS count : consumed 4350 : 4370
NEG count : acceptanceRatio 2400 : 0.000223963
Precalculation time: 72
+----+---------+---------+
| N | HR | FA |
+----+---------+---------+
| 1| 1| 1|
+----+---------+---------+
| 2| 1| 1|
+----+---------+---------+
| 3| 0.99977| 0.559583|
+----+---------+---------+
| 4| 0.99931| 0.240417|
+----+---------+---------+
END>
Training until now has taken 0 days 1 hours 57 minutes 53 seconds.
I have just showed the output of the final stage to show the acceptance ratio. Now, in order to detect using this classifier, I modified an existing opencv example using detectMultiScale(). The code is shown below
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <cctype>
#include <iostream>
#include <iterator>
#include <stdio.h>
using namespace cv;
using namespace std;
void detectAndDraw(Mat &img, CascadeClassifier& cascade,double scale)
{
vector<Rect> double_doors;
Mat gray;
Mat smallImg( cvRound (img.rows/scale), cvRound(img.cols/scale), CV_8UC1 );
Scalar color = Scalar(0,0,255);
cvtColor( img, gray, CV_BGR2GRAY );
resize( gray, smallImg, smallImg.size(), 0, 0, INTER_LINEAR );
equalizeHist( smallImg, smallImg );
cout<<"equalization done"<<endl;
cascade.detectMultiScale( smallImg, double_doors,scale,1,0,Size(10,10),Size(100,140));
cout<<"multiscale detect complete"<<endl;
for(int i=0;i<double_doors.size();i++)
{
rectangle(img,double_doors[i],color,1,8,0);
}
cout<<"rectangles drawn"<<endl;
imwrite("/home/tonystark/Project_awesome/Dataset/Training_set/Results/Double_Doors/Door_Detect1.jpg",img);
imshow("Output Image",img);
}
int main(int argc, char **argv)
{
CascadeClassifier cascade, nestedCascade;
cascade.load(argv[1]);
double scale = atof(argv[2]);
Mat img = imread(argv[3],1);
cout<<"inputs read"<<endl;
namedWindow("Input Image",WINDOW_NORMAL);
namedWindow("Output Image",WINDOW_NORMAL);
detectAndDraw(img,cascade,scale);
cout<<"detection complete"<<endl;
imwrite("/home/tonystark/Project_awesome/Dataset/Training_set/Results/Double_Doors/Door_Detect1.jpg",img);
imshow("Input Image",img);
waitKey(0);
return 0;
}
The input image for detection is 3000X2250 and I started the detection. Its been about 1:30 hours since and I am not sure what is exactly happening. From reading the documentation here, it tells me more or less like it supports only Haar. But from this here, I get that it can be used for both. I can see a parameter from the code, for Haar, in that link, for the function,
face_cascade.detectMultiScale( frame_gray, faces, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(30, 30) );
In my code, this is how I call the function
cascade.detectMultiScale( smallImg, double_doors,scale,1,0,Size(10,10),Size(100,140));
Am I missing something here? Could you please point me in the right direction?
On a sidenote, I always train my models to have a factor 10e^-5 before I find the result of the detector satisfyable.
As to why it takes so long, I am guessing that the amount of patches in a 3000x2250 image that need to be checked on every scale between [10,10] and [100,140] grows enourmous. So that will probably take a lot of time... However you trained your model with size [30,30] so take that as lower dimension, you can never go lower than the model size (it will basically not get processed unless you manually upscale the image first)
I agree with @StevenPuttemans, with such dimensions it will take a long time to process each little window.
Regarding LBP descriptors, the Cascade Classifier works with Haar, LBP and also HOG (although it's not documented).
And now, a comment about your code: both imwrite's and imshow's do the exact thing over the exact same matrix. Therefore, both Input window and Output window will show the original image plus the drawn rectangles
@StevenPuttemans Thank you for your input. could you please explain what you meant by factor of 10e^-5? Did you mean the acceptance ratio?
@Tonystark124 yes I mean the value for the acceptanceRatio. If I keep it above that value, it seems there are to many false positives, if I train further and reach values of 10e-7 to 10e-8 than it seems i overfitted my training data.
@StevenPuttemans if the detectMultiScale function is used for both Haar and LBP, how do I mention in the function to use LBP features?? I am sorry about my earlier comment. I knew how to set acceptance ratio. But while detecting, I get it the image is scanned and LBP features have to be obtained to compare. But if no argument is given to mention the same, how does the function differentiate.?
@StevenPuttemans will the cascade function xml file details be considered? Since the function is used as "cascade_classifier.detectMultiScale()".?
The function knows which feature to use due to the fact that it is embedded in the model that you are using. Open up and xml file and you will see that it is specified there. The detection software first validates those parameters.