Reputation: 1507
I have an image of a mural painting which contains repetitions of some similar looking flowers. There is another image(smaller) of one of those flowers. I want to mark all the flowers similar to the flower in smaller image. How can I implement this in openCV? The similar looking flowers are not exactly the same. There are some distortions due to painter's inaccuracy.
NOTE: I have tried template matching, SIFT/SURF feature detector.
The image is like this image link: link below
The smaller image to be queried is image link: link below
The results that I want and the results that I get by template matching are shown in the following image. In the following image all the encircled flowers are similar and should be searched but template matching only gives me only the ones that are marked with red star. Even after many iterations template matching does not give me other flowers. image link: link below
All images are in this folder : https://drive.google.com/folderview?id=0Bx3-s7he2z7xZ2tHVzhGb1A4a3c&usp=sharing
Upvotes: 2
Views: 1586
Reputation: 1675
I believe the culprit is you're looking for a single resolution of template, which is much smaller than the flowers you want to find.
So, if you're using matchTemplate - you should run it several times. For different sizes of the template (make your flower bigger with resize). Another option is to scale the image down, and use the template of the same size.
Those approaches are rather simple, however, may be sub-optimal - you'll be doing a lot of work resizing and matching all over again. So, you should probably use feature matching and figure out what exactly goes wrong. Don't know if you've seen it, but you can follow the feature matching tutorial http://docs.opencv.org/doc/tutorials/features2d/feature_flann_matcher/feature_flann_matcher.html
UPD
I believe, I misinterpreted your image. I agree with you on the size now - it isn't such a big deal. Well, I don't know how you've done the matching, but the following code
Mat image = imread("/home/sergei/Documents/source.jpg");
Mat templ = imread("/home/sergei/Documents/template.jpg");
Mat dst;
matchTemplate(image, templ, dst, CV_TM_CCOEFF_NORMED);
threshold(dst, dst, 0.2, 0.0, THRESH_TOZERO);
for (int i = 0; i < dst.rows; i++)
{
for (int j = 0; j < dst.cols; j++)
{
if (dst.ptr<float>(i)[j] > 0.0)
{
imshow("candidate", image(Rect(j, i, templ.cols, templ.rows)));
waitKey(0);
}
}
}
misses, I believe, 2 of the matches you consider valid. It gives you few false positives as well, but that's a start.
You can improve further by playing with threshold value and matching metric.
Upvotes: 1