0

I need find all images within image, for this idea I have found great solution:

import cv2
import numpy as np

img_rgb = cv2.imread('source.png')
img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)
template = cv2.imread('block.png', 0)
w, h = template.shape[::-1]

res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF)

threshold = 0.8
loc = np.where(res >= threshold)

for pt in zip(*loc[::-1]):
    cv2.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0, 0, 255), 2)

# cv2.imwrite('res.png', img_rgb)
cv2.imshow('output', img_rgb)
cv2.waitKey(0)

Source data:

https://i.stack.imgur.com/cE5bM.png (source)

https://i.stack.imgur.com/BgzAA.png (template)

I tried to use this code but failed.

What I see now: enter image description here

What I expected to get: enter image description here

What's wrong? I am using python 3.5 and opencv 3.3.0.10

PS: very interesting thing that another solution works perfect but finds only 1 match (best one)

ValueError
  • 125
  • 1
  • 15

1 Answers1

1

I am definitely no expert on OpenCV and it's various template matching methods (though coincidentally I had started to play around with it).

However, a couple of things in your example stand out.

You use the cv2.TM_CCOEFF method which gives results that are universally way above the 0.8 threshold. So everywhere in the image matches giving a massive red rectangle blob. If you want to use this method try cv2.TM_CCOEFF_NORMED to normalise the results to below 1.

But my best 10 minute attempt was using;

method = cv2.TM_CCORR_NORMED

and setting

threshold = 0.512

which gave;

enter image description here

This is fairly unsatisfactory though because the threshold had to be 'tuned' fairly precisely to remove most of the mismatches. There is undoubtedly a better way to get a more reliable stand-out match.

Paul
  • 360
  • 3
  • 14
  • Thanks a lot for participation, but I will use different images and it's not acceptable to tune threshold for each image, so that solution not ready to work. – ValueError Oct 15 '17 at 02:50
  • Also interesting thing [https://stackoverflow.com/a/15147009/6578528](that this solution) works perfect but find only 1 image instead of all, could you please change that solution to find all images? my skills too low here – ValueError Oct 15 '17 at 02:51
  • 1
    To be fair I was not trying to produce a complete solution for you. You asked why you got the solid red image result and that's what my answer attempted to explain. I think this template approach should still work well on your images, but it might take some additional research to work out how best to apply it. – Paul Oct 16 '17 at 00:07