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:
Step 1: Download pictures from my own Flickr accountI 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:
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 examplesOne 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.
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 themI 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 pathsMy 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_createsamplesFinally! Getting to the running of the actual training code. Almost.
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.
Step 6: Run opencv_traincascadeFinally, 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 catI 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: