Detections too small with OpenCV Cascade classifier
Goal
I am trying to detect roofs in aerial images using Viola and Jones implementation provided by OpenCV. I have trained classifier with the following parameters:
opencv_traincascade -vec roof_samples.vec -bg bg.txt -numStages 20
-minHitRate 0.99999 -numPos 393 -numNeg 700 -w 25 -h 25
The problem
Roofs are being recognized, but if the roof is large, the detection windows is drawn around a part of the roof rather than around the entire roof. The image shows detections in red, green and blue. Green corresponds to the ground truth - notice how the green rectangle covers the whole roof, whereas all other rectangles do not.
Training images:
Below are 3 examples of training images I have used:
What I have tried
- I tried altering the scale parameter, but it didn't help
- I also modified -w and -h, but I don't expect that to help either (I increased them and the training phase is currently running, but as expected, it is extremely slowly). I really don't expect things to get better with this change though.
Question:
I'm wondering if anyone knows which parameters I can modify to ensure larger roofs are detected as a single roof rather than being detected in small patches.
hey, i'm not an expert on this, but it seems, your smallish(incomplete) detections all go for 'uniform' suface parts, while your actual roof consists of a 'center', and a 'border' part. looks, like your training images did not cover that situation
also, if above image is a 'typical' situation, you want to set the minSize param in the detectMultiScale call to something larger, like 1/2 of the img size, to get rid of the smaller false positives
Thanks for your suggestion! I added some of the images used in training. Does your first suggestion still apply?
The issue with setting the minSize to avoid small false positives is that I do have a few roofs that are very small and need to be detected. I guess I could have multiple detectors: one for smaller roofs and one for larger roofs, but that seems rather messy.
ah, nice, that you added the train images !
can't help it - looks to me, that your trained cascade quite accurately detects, what it was trained on - that is: light rectangular blobs with a dark border (while your actual roof is kinda the opposite).
it's more a conceptual problem now. it's impossible to train anything on X and ~X at the same time
changing -w and -h won't help much. also you want to keep it as small as possible, since this is the lower boundary size for the detection (it can't find anything smaller than that)
groupRectangles maybe useful to filter unuseful rectangles after detection