Search code examples
opencvhaar-classifier

opencv_traincascade - samplOpenCV Error: Bad argument


Background: I am trying to train my own OpenCV Haar Classifier for face detection. I am working on a VM with Ubuntu 16.04, my working directory has 2 sub-directories: face containing 2429 images of positives, non-face containing 4548 images of negatives. All images are png, gray scale and have both width and height 19 pixels. I have generated a file positives.info that contains the absolute path to every positive image followed by " 1 0 0 18 18", like so:

/home/user/ML-Trainer/face/face1.png 1 0 0 18 18
/home/user/ML-Trainer/face/face2.png 1 0 0 18 18
/home/user/ML-Trainer/face/face3.png 1 0 0 18 18

and another file negatives.txt that contains the absolute path to every positive image

/home/user/ML-Trainer/non-face/other1.png
/home/user/ML-Trainer/non-face/other2.png
/home/user/ML-Trainer/non-face/other3.png

First I ran the following command:

opencv_createsamples -info positives.info -vec positives.vec -num 2429 -w 19 -h 19

and I get the positives.vec as expected, I then created a empty directory data and ran the following:

opencv_traincascade -data data -vec positives.vec -bg negatives.txt -numPos 2429 -numNeg 4548 -numStages 10 -w 19 -h 19 &

It seems to run smoothly:

PARAMETERS:
cascadeDirName: data
vecFileName: positives.vec
bgFileName: negatives.txt
numPos: 2429
numNeg: 4548
numStages: 10
precalcValBufSize[Mb] : 1024
precalcIdxBufSize[Mb] : 1024
acceptanceRatioBreakValue : -1
stageType: BOOST
featureType: HAAR
sampleWidth: 19
sampleHeight: 19
boostType: GAB
minHitRate: 0.995
maxFalseAlarmRate: 0.5
weightTrimRate: 0.95
maxDepth: 1
maxWeakCount: 100
mode: BASIC
Number of unique features given windowSize [19,19] : 63960

===== TRAINING 0-stage =====
<BEGIN
POS count : consumed   2429 : 2429
NEG count : acceptanceRatio    4548 : 1
Precalculation time: 13
+----+---------+---------+
|  N |    HR   |    FA   |
+----+---------+---------+
|   1|        1|        1|
+----+---------+---------+
|   2|        1|        1|
+----+---------+---------+
|   3| 0.998765| 0.396218|
+----+---------+---------+
END>
Training until now has taken 0 days 0 hours 1 minutes 7 seconds.

But then I get the following error:

===== TRAINING 1-stage =====
<BEGIN
POS current samplOpenCV Error: Bad argument (Can not get new positive sample. The most possible reason is insufficient count of samples in given vec-file.
) in get, file /home/user/opencv-3.4.0/apps/traincascade/imagestorage.cpp, line 158
terminate called after throwing an instance of 'cv::Exception'
  what():  /home/user/opencv-3.4.0/apps/traincascade/imagestorage.cpp:158: error: (-5) Can not get new positive sample. The most possible reason is insufficient count of samples in given vec-file.
 in function get

How do I solve this:

samplOpenCV Error: Bad argument

Any help would be greatly appreciated.

EDIT: I have modified -numPos to a smaller number: 2186 (0.9 * 2429), I did this after reading this answer and it got me to

===== TRAINING 3-stage =====

and it gives me the same error. How should I tune the parameters for the opencv_createsamples command?


Solution

  • I eventually managed to make it work by respecting this formula:

    vec-file >= (numPos + (numStages-1) * (1-minHitRate) * (numPose) + S)

    numPose - number of positive samples which is used to train each stage

    numStages - the count of stages which a cascade classifier will have after the training

    S - the count of all the skipped samples from vec-file (for all stages)