markers detection
Greetings everyone! :)
I'm working on the solution that will detect markers in the image. I'd like to ask which method available in OpenCV will be a good choice for this task. The detection should be fast enough to work in real time on a modern computer.
After a quick research I've decided to use markers similar to those used in car crash-tests.
The method should be able to detect multiple markers which are visible from a slight perspective and also with some rotation - just like in the following example:
My first idea was to use the cascadeclassifier. I've started with creating positive samples .vec file using:
./opencv_createsamples -vec positive_samples/vec/positive_images.vec -img positive_samples/marker.png -bg negative_samples/negative_images.dat -num 1020 -bgcolor -1 -bgthresh 0 -maxidev 40 -maxxangle 0.6 -maxyangle 0.6 -maxzangle 0.2 -show -w 24 -h 24
I used "-bgcolor -1 -bgthresh 0" to avoid making any part of the image transparent. Parameters "-maxxangle 0.6 -maxyangle 0.6 -maxzangle 0.2" gives rotation and distortion variance that seems to be quite enough.
Negative images dataset was taken from the SUN2012 - I've chosen 1000 images from this set.
Then I've done some trainings:
./opencv_haartraining -data cascade -vec positive_samples/vec/positive_images.vec -bg negative_samples/negative_images.dat -npos 1000 -nneg 1000 -nstages 10 -nsplits 2 -mem 15000 -nonsym -minhitrate 0.999 -maxfalsealarm 0.5 -mode ALL -minpos 200 -w 24 -h 24
and tests, however the results were not satisfying - in example: very low detection rate of markers seen in live camera image.
After all, I've also tried training cascadeclassifier to detect my face and in this case results were much better.
So my question is whether cascadeclassifier is a good choice for recognizing simple markers? And if yes - what values of the training parameters would give good detection results? Or maybe some other detecting method is better for such task?
Thank you in advance for your help.
Below is the log from one of many cascade trainings I've done.
./opencv_haartraining \
-data cascade \
-vec positive_samples/vec/positive_images.vec \
-bg negative_samples/negative_images.dat \
-npos 1000 \
-nneg 1000 \
-nstages 10 \
-nsplits 2 \
-maxtreesplits 10 \
-mem 15000 \
-nonsym \
-minhitrate 0.999 \
-maxfalsealarm 0.5 \
-mode ALL \
-minpos 200 \
-w 24 -h 24
Data dir name: cascade
Vec file name: positive_samples/vec/positive_images.vec
BG file name: negative_samples/negative_images.dat, is a vecfile: no
Num pos: 1000
Num neg: 1000
Num stages: 10
Num splits: 2 (tree as weak classifier)
Mem: 15000 MB
Symmetric: FALSE
Min hit rate: 0.999000
Max false alarm rate: 0.500000
Weight trimming: 0.950000
Equal weights: FALSE
Mode: ALL
Width: 24
Height: 24
Applied boosting algorithm: GAB
Error (valid only for Discrete and Real AdaBoost): misclass
Max number of splits in tree cascade: 10
Min number of positive samples per cluster: 200
Required leaf false alarm rate: 8.87784e-05
Tree Classifier
Stage
+---+
| 0|
+---+
Number of features used : 261600
Parent node: NULL
*** 1 cluster ***
POS: 1000 1000 1 ...
I'd rather use template matching
Depends on how much the markers will rotate or change the appearance, but multi-scale template matching or feature matching (finely tuned) should work much better than classifiers.
Cascade classifiers in OpenCV will not be able to learn enough discriminative properties from these simple markers to distinct them from background structures. A possibility would be to use advanced cascades that incorporate color information like ICF or ACF. But I would also start with template matching.
Also seriously, skip the
opencv_haartraining
and go toopencv_traincascade
which is far more optimized and not as buggy as the first one!what about taking into account in some way the use of rotation invariant Local Binary Patterns?
Take also a look at this post: