- Get link
- X
- Other Apps
Or rather, how to experiment with using OpenCV to train a classifier and ultimately fail.
The following two links were my guides. They might make better guides than what follows here, but I'm going to write this stuff down for myself.
I wanted to try training my own OpenCV Haar Cascaded Classifier. OpenCV comes with some pre-trained ones for faces and body parts and whatnot. For fun, I tried to train it to recognize my cat Jpeg, which Picasa humorously recognized as a person in a handful of photos last month:
I added my flickr API key and changed the main of that python file to look through MY pictures for things tagged 'cat'.
if __name__ == '__main__':
pix = photos_search('16977922@N00', False, '', '', 'cat')
for p in pix:
print p.getLarge()
Then, because bash is one of my best friends these days:
python flickr.py > cat_pix.txt && for i in `cat cat_pix.txt`; do wget $i; done
Actually the first time I downloaded the pictures, I wanted to resize them with Imagemagick's mogrify (in-place image editing) command so I ran:
for i in *.jpg; do mogrify -resize 1024x1024 $i; done
http://achuwilson.wordpress.com/2011/07/01/create-your-own-haar-classifier-for-detecting-objects-in-opencv/
I compiled it with the following command after commenting out two useless includes that were complaining at me. BRIEF INTERJECTION: I just installed OpenCV with Macports. If you do that, your OpenCV stuff will probably be in the same place. Installation of OpenCV didn't work properly until I made sure my macports was up to date.
g++ -I/opt/local/include -L/opt/local/lib -lopencv_core -lopencv_highgui -lopencv_imgproc -lopencv_objdetect objectmarker.cpp -o objectmarker
For context, I'm inside a directory of cat images. Running that objectmarker program is as so:
../objectmarker positive_examples.txt ./
Right, so, run that program from the directory with your images in it because the code doesn't actually build the right path to the image file if you run it from a different directory, even though it looks like it intended to. Then click boxes and press the appropriate SPACE and Capital B keys until all the objects/cats are marked.
The command went something like this:
ls eddie/ > negative_examples.txt
So I had these two files:
I had 19 positive examples and 17 negative images so I ran this:
/opt/local/bin/opencv_createsamples -vec jpeg_pos.vec -info postive_examples.txt -show -w 32 -h 32
One very important thing I learned is that you should not put a number like 100 into the height and width fields because that will make your computer freak out (have a lot to process) at the next step.
/opt/local/bin/opencv_traincascade -data output_jpeg_cascade/ -vec jpeg_pos.vec -bg negative_examples.txt -numPos 19 -numNeg 17 -w 32 -h 32
Your -w and -h numbers have to be the same. When I tried them at 100, the program was trying to use 6GB of ram and making very slow progress. When I knocked it down to 32x32, it finished in under 30 seconds. I hear from those other links on the internet that training can take 5 days with 2000 positive and negative examples. Maybe that'll be me some day, and maybe it wont.
In many cases, it completely failed to detect Jpeg. Even though this image was part of the training:
In another instance, it got different ends of the cat confused:
The following two links were my guides. They might make better guides than what follows here, but I'm going to write this stuff down for myself.
- http://docs.opencv.org/doc/user_guide/ug_traincascade.html
- http://www.prodigyproductionsllc.com/articles/programming/how-to-train-opencv-haar-classifiers/
I wanted to try training my own OpenCV Haar Cascaded Classifier. OpenCV comes with some pre-trained ones for faces and body parts and whatnot. For fun, I tried to train it to recognize my cat Jpeg, which Picasa humorously recognized as a person in a handful of photos last month:
Step 1: Download pictures from my own Flickr account
I use this python program to get Flickr image urls: https://code.google.com/p/flickrpy/I added my flickr API key and changed the main of that python file to look through MY pictures for things tagged 'cat'.
if __name__ == '__main__':
pix = photos_search('16977922@N00', False, '', '', 'cat')
for p in pix:
print p.getLarge()
Then, because bash is one of my best friends these days:
python flickr.py > cat_pix.txt && for i in `cat cat_pix.txt`; do wget $i; done
Actually the first time I downloaded the pictures, I wanted to resize them with Imagemagick's mogrify (in-place image editing) command so I ran:
for i in *.jpg; do mogrify -resize 1024x1024 $i; done
Step 2: Mark "objects" to make positive examples
One of the links above has an object marking program for windows. This link has one that I was able to compile on my mac. It's kind of amateur code and I have vague plans to rewrite it.http://achuwilson.wordpress.com/2011/07/01/create-your-own-haar-classifier-for-detecting-objects-in-opencv/
I compiled it with the following command after commenting out two useless includes that were complaining at me. BRIEF INTERJECTION: I just installed OpenCV with Macports. If you do that, your OpenCV stuff will probably be in the same place. Installation of OpenCV didn't work properly until I made sure my macports was up to date.
g++ -I/opt/local/include -L/opt/local/lib -lopencv_core -lopencv_highgui -lopencv_imgproc -lopencv_objdetect objectmarker.cpp -o objectmarker
For context, I'm inside a directory of cat images. Running that objectmarker program is as so:
../objectmarker positive_examples.txt ./
Right, so, run that program from the directory with your images in it because the code doesn't actually build the right path to the image file if you run it from a different directory, even though it looks like it intended to. Then click boxes and press the appropriate SPACE and Capital B keys until all the objects/cats are marked.
Step 3: Get negative examples by making a list of images that don't have the object in them
I wound up using images from flickr tagged "eddie", which is the name of my mom's chubby chihuahua. Pictures of other dogs named Eddie were also included, but that didn't matter. The only thing that mattered was that Jpeg was not in any of the images. Which is true because he's never met any dogs.The command went something like this:
ls eddie/ > negative_examples.txt
Step 4: Fix the paths
My images were in folders called "jpeg/" and "eddie/" and some of the jpeg images didn't actually have jpeg's face clearly shown. I had to change the image paths in positive_examples.txt and negative_examples.txt from "eddie_4787878333_4dd7bcd3d8_o.jpg" to "eddie/eddie_4787878333_4dd7bcd3d8_o.jpg". I did that with vim and the mass insert thing!Step 5: Run opencv_createsamples
Finally! Getting to the running of the actual training code. Almost.So I had these two files:
- positive_examples.txt
- negative_examples.txt
I had 19 positive examples and 17 negative images so I ran this:
/opt/local/bin/opencv_createsamples -vec jpeg_pos.vec -info postive_examples.txt -show -w 32 -h 32
One very important thing I learned is that you should not put a number like 100 into the height and width fields because that will make your computer freak out (have a lot to process) at the next step.
Step 6: Run opencv_traincascade
Finally, for reals. Let's do it./opt/local/bin/opencv_traincascade -data output_jpeg_cascade/ -vec jpeg_pos.vec -bg negative_examples.txt -numPos 19 -numNeg 17 -w 32 -h 32
Your -w and -h numbers have to be the same. When I tried them at 100, the program was trying to use 6GB of ram and making very slow progress. When I knocked it down to 32x32, it finished in under 30 seconds. I hear from those other links on the internet that training can take 5 days with 2000 positive and negative examples. Maybe that'll be me some day, and maybe it wont.
Step 7: Detect cat
I hacked some code online that used the face detector classifier and replaced "haarcascade_frontalface_alt2.xml" or whatever with "output_jpeg_cascade/cascade.xml". I don't remember where the code came from so I don't have a good link that particular resource.In many cases, it completely failed to detect Jpeg. Even though this image was part of the training:
In another instance, it got different ends of the cat confused:
Voodoo magic
This was the first time I ever tried anything like this. There's probably a lot I could learn about how to make it work better. At the same time, I wish I could teach the classifier more specific things to look for, or have it tell me exactly why it thinks the cat butt is the face. Feeding lots of data into a black box and crossing my fingers doesn't seem like a fun approach.- Get link
- X
- Other Apps
Comments
Hai, can you share your objectmarker executable file after you compiled? I've compiled on mac os x but the executable file can't work. thanks
ReplyDeleteI'm working on a similar project. The quality of the classifier depends on the training. Perhaps you should have included many (1-5 thousand) positive and negative. Also the sample size w/h don't have to be equal, just scaled to match the original scale.
ReplyDeleteHi, I'm working with similiar project with you, I'm using opencv with python to detect car, I already found converted program to python in google, and I run it, it doesn't work get stuck in here:
ReplyDeleteif (len(sys.argv) != 3):
sys.stderr.write("%s output_info.txt raw/data/directory\n"
% sys.argv[0])
return -1
could you help me??