4

I’m a making an iOS application that will find instances of a smaller (similar) image inside a larger image. For example, something like:

The image we are searching inside The image we are searching inside

enter image description here

The image we are searching for

enter image description here

The matched image

The main things to consider are, the smallImage size will match the size of the target in the bigImage, but the object may be slightly obscured in the bigImage (as in they won’t always be identical). Also, the images I am dealing with are quite a bit smaller than my examples here, the image that I am trying to match (the smallImage) is between 32 x 32 pixels and 80 x 80 pixels, and the big image around 1000 x 600 pixels. Other than potentially being slightly obscured, the smallImage will match the object in the big image in every way (size, color, rotation etc..)

I have tried out a few methods using OpenCV. Feature matching didn’t seem accurate enough and gave me hundreds of meaningless results, so I am trying template matching. My code looks something like:

cv::Mat ref = [bigImage CVMat];
cv::Mat tpl = [smallImage CVMat];
cv::Mat gref, gtpl;
cv::cvtColor(ref, gref, CV_LOAD_IMAGE_COLOR);
cv::cvtColor(tpl, gtpl, CV_LOAD_IMAGE_COLOR);
cv::Mat res(ref.rows-tpl.rows+1, ref.cols-tpl.cols+1, CV_32FC1);
cv::matchTemplate(gref, gtpl, res, CV_TM_CCOEFF_NORMED);
cv::threshold(res, res, [tolerance doubleValue], 1., CV_THRESH_TOZERO);


    double minval, maxval, threshold = [tolerance doubleValue]; 
    cv::Point minloc, maxloc;
    cv::minMaxLoc(res, &minval, &maxval, &minloc, &maxloc);

    if (maxval >= threshold) {
       // match
  • bigImage is the large image in which we are tryign to find the target

  • smallImage is the image we are looking for within the bigImage

  • tolerance is the tolerance for matches (between 0 and 1)

This does work, but there are a few issues.

I originally tried using a full image of the image object that I am trying to match (ie; an image of the entire fridge), but I found that it was very inaccurate, when the tolerance was high it found nothing, and when it was low it found many incorrect matches.

Next I tested out using smaller portions of the image, for example:

enter image description here

This increased the accuracy of finding the target in the big image, but also results in a lot of incorrect matches as well.

I have tried all the available methods for matchTemplate from here, and they all return a large amount of false matches, except CV_TM_CCOEFF_NORMED which returns less matches (but also mostly false matches)

How can I improve the accuracy of image matching using OpenCV in iOS?

Edit: I have googled loads, the most helpful posts are:

I can't find any suggestions on how to improve the accuracy

Community
  • 1
  • 1
Brett Gregson
  • 5,867
  • 3
  • 42
  • 60
  • 2
    Did you read [that question](https://stackoverflow.com/questions/10168686/algorithm-improvement-for-coca-cola-can-shape-recognition) and its answers? The problem seems close to yours. – BConic Sep 07 '14 at 11:43
  • @AldurDisciple I have, the answer recommends using feature matching instead of template matching, which I have tried, and as far as I understand works best for cases when the match image is rotated/skewed/scaled. My implementation of feature matching worked but gave a huge number of false matches, and not enough correct matches to be able to confidently identify the matched image – Brett Gregson Sep 07 '14 at 13:58
  • 1
    will the object which you are searching for, be rotated in the image? – Bharat Sep 07 '14 at 16:50
  • @BharatSingh nope, the template image is exactly how is appears in the search image, no rotation/skewing/color variation/distortion of any kind (other than potentially being partially obscured, but by no more than maybe 20%) – Brett Gregson Sep 07 '14 at 17:49
  • 1
    try adding a mask to the template, such that the uniform white background is masked out, and thus wont interfere with the score. you may need to leave a small boundary there such that the edges of the fridge are not masked out. – QED Sep 07 '14 at 20:00
  • @QED Sorry I should have said, the template image is a PNG with a transparent background – Brett Gregson Sep 07 '14 at 21:32
  • hey did you ever solve this? – geekay Feb 01 '16 at 15:06

1 Answers1

3

If the template image is not rotated (or under some projective distortion) in the image in which you are searching for - since all geometric and texture properties are preserved (assuming occlusion is not very large), the only variable left is the scale. Hence, running a template matching algorithm, at multiple scales of the original template and then taking the maximum normalized response over all scales should give a perfect match. One issue may be that for a perfect match, guessing (optimizing over) the exact scale will be computationally expensive or involve some heuristics. One heuristic can be, run template matching at 3 different scales (1, 2, 4), suppose you get the best response at a particular scale, (say 2), try between (1.5, 2.25, 3) and keep on refining. Ofcourse, this is a heuristic which may work well in practice, but is not a theoretically correct way of finding the right scale and can get stuck in local minima.

The reason why feature based methods will not work on this kind of image is because they rely on texture/sharp gradients which are not very evident in the homogeneous template image you have shown.

Bharat
  • 2,139
  • 2
  • 16
  • 35
  • Thanks for the answer. The template image is the exact size as it appears in the search image.+1 for the reason feature matching doesn't work, I figured feature matching was more for "organic" images such as photos. – Brett Gregson Sep 07 '14 at 17:46
  • Running through a variation of scales ended up working for me, thanks. – AgnosticDev Jun 04 '15 at 20:48