Hi folks,
In this edition of the blog I will be writing about a unique feature of openCV, haar classifier training. This methodology allows us to train machines to recognize any object of our choice by learning features of the object. Though the method is pretty easy to execute and will end up with good results, the process is extremely time consuming. For our project, we are interested in getting the machine to recognize human palm. This will be useful for us to define gestures through continuous detection. After the previous post on Introduction to openCV, where we have explored many possibilities for hand gesture detection, we settled on using haar cascade training method.
Now how do we train a machine and make it self learn to recognize a particular object? This sure sounds very intriguing. This can be achieved by telling the machine how the object looks like and what the object does NOT look like and by also by teaching it about any special features of the object that stands out. Now once the machine knows the features of the object, this machine trained data can be used on the input images to check the presence of the object.
As mentioned earlier, our intention is to detect human palm. Hence we collected around 80 positive images, all cropped to the same ratio(0.64) and around 1000 negative images. Its important that we crop all the positive images to the same ratio and also they must contain only the object of interest preferably with different background and lighting. Negative images must not contain the object of interest. More the number of image samples, better the results! (Takes longer time to train too!). Once we had the images, we were all set to start the training process. The steps we followed is derived from this blog which proved to be extremely helpful. The width and height used for training was 64 and 100 respectively. Here are a few examples of positive images
and negative images included everything(well almost!) that is not human palm.
Until next time.
In this edition of the blog I will be writing about a unique feature of openCV, haar classifier training. This methodology allows us to train machines to recognize any object of our choice by learning features of the object. Though the method is pretty easy to execute and will end up with good results, the process is extremely time consuming. For our project, we are interested in getting the machine to recognize human palm. This will be useful for us to define gestures through continuous detection. After the previous post on Introduction to openCV, where we have explored many possibilities for hand gesture detection, we settled on using haar cascade training method.
Now how do we train a machine and make it self learn to recognize a particular object? This sure sounds very intriguing. This can be achieved by telling the machine how the object looks like and what the object does NOT look like and by also by teaching it about any special features of the object that stands out. Now once the machine knows the features of the object, this machine trained data can be used on the input images to check the presence of the object.
As mentioned earlier, our intention is to detect human palm. Hence we collected around 80 positive images, all cropped to the same ratio(0.64) and around 1000 negative images. Its important that we crop all the positive images to the same ratio and also they must contain only the object of interest preferably with different background and lighting. Negative images must not contain the object of interest. More the number of image samples, better the results! (Takes longer time to train too!). Once we had the images, we were all set to start the training process. The steps we followed is derived from this blog which proved to be extremely helpful. The width and height used for training was 64 and 100 respectively. Here are a few examples of positive images
and negative images included everything(well almost!) that is not human palm.
Steps to get training started:
Assuming that openCV is installed, the necessary scripts can be found here :
git clone https://github.com/Srip/HaarTraining.git
Below are the steps for training :
1. Organize the data
Save all the positive images in a directory, say positive_images and all the negative images in negative_images.
2. Once we have the images, all cropped to the same ratio lets save the relative paths of all images to a file.
find ./positive_images -iname "*.jpg" >postives.txt
find ./negative_images -iname "*.jpg" > negatives.txt
3. Next step is to create samples from the existing positive images (2000 samples for our cascade classifier). For this I will be using a perl script found in this blog and also a tool from openCV "opencv_createsamples".Both these scripts can be found in the repository mentioned earlier.
mkdir samples
perl createsamples.pl positives.txt negatives.txt samples 2000 "opencv_createsamples -bgcolor 0\
-bgthresh 0 -maxxangle 1.1 -maxyangle 1.1 maxzangle 0.5 -maxidev 40 -w 64 -h 100"
4. Once the samples are created, we will need to merge these samples into a single *.vec file. For this purpose, we use the mergevec.cpp file.
cp mergevec.cpp ~/opencv-2.4.6.1/apps/haartraining
cd ~/opencv-2.4.6.1/apps/haartraining
g++ -I. -o mergevec mergevec.cpp cvboost.cpp cvcommon.cpp cvsamples.cpp\
cvhaarclassifier.cpp cvhaartraining.cpp `pkg-config --libs --cflags opencv`
5. Once the execution is done, take the executable to the directory where all the scripts and images are stored. This can be used to merge all the *.vec files generated in the samples directory.
find ./samples -name '*.vec' > samples.txt
./mergevec samples.txt samples.vec
6. Now for the final training command. Opencv_traincascade is the tool used to training the
machine to detect objects. The meaning of the various arguments in the command can be
understood here. Looking at what the parameter does, appropriate values can be set.
mkdir classifier
opencv_traincascade -data classifier -vec samples.vec -bg negatives.txt -numStages 20\
-minHitRate 0.999 -maxFalseAlarmRate 0.5 -numPos 1500 -numNeg 992 -w 64 -h 100\
-mode ALL -precalcValBufSize 2048 -precalcIdxBufSize 3072
The width and height parameters should have the same value as used when creating samples. Now this is going to take ALOT (about a week!) of time to execute and the final result will be in the form of an xml document. Since an xml file is generated for each stage of the classifier and later it is combined to give a single file, it is called as cascade classifier. A great advantage of this is that the program can be stopped at any point and on restarting the training continues from the last stopped stage.find ./positive_images -iname "*.jpg" >postives.txt
find ./negative_images -iname "*.jpg" > negatives.txt
3. Next step is to create samples from the existing positive images (2000 samples for our cascade classifier). For this I will be using a perl script found in this blog and also a tool from openCV "opencv_createsamples".Both these scripts can be found in the repository mentioned earlier.
mkdir samples
perl createsamples.pl positives.txt negatives.txt samples 2000 "opencv_createsamples -bgcolor 0\
-bgthresh 0 -maxxangle 1.1 -maxyangle 1.1 maxzangle 0.5 -maxidev 40 -w 64 -h 100"
4. Once the samples are created, we will need to merge these samples into a single *.vec file. For this purpose, we use the mergevec.cpp file.
cp mergevec.cpp ~/opencv-2.4.6.1/apps/haartraining
cd ~/opencv-2.4.6.1/apps/haartraining
g++ -I. -o mergevec mergevec.cpp cvboost.cpp cvcommon.cpp cvsamples.cpp\
cvhaarclassifier.cpp cvhaartraining.cpp `pkg-config --libs --cflags opencv`
5. Once the execution is done, take the executable to the directory where all the scripts and images are stored. This can be used to merge all the *.vec files generated in the samples directory.
find ./samples -name '*.vec' > samples.txt
./mergevec samples.txt samples.vec
6. Now for the final training command. Opencv_traincascade is the tool used to training the
machine to detect objects. The meaning of the various arguments in the command can be
understood here. Looking at what the parameter does, appropriate values can be set.
mkdir classifier
opencv_traincascade -data classifier -vec samples.vec -bg negatives.txt -numStages 20\
-minHitRate 0.999 -maxFalseAlarmRate 0.5 -numPos 1500 -numNeg 992 -w 64 -h 100\
-mode ALL -precalcValBufSize 2048 -precalcIdxBufSize 3072
Conclusion:
The training process took around 9 days to complete . The results are not bad, but the rate of false positives is quite high. Hence we have decided the train the machine for the third time with more positive and negative images. As for the results, here is a screenshot.Until next time.