简体   繁体   中英

How to reduce the search area of the image for template matching?

I'm using openCV template matching algorithm, but it takes a long time to search for a template image inside the base image. Is there any way to tell the algorithm to search only a specific area(like- Top, Bottom, Left, Right) of the given base image for the template image? My goal is to reduce the search time any other approach would be appreciated.

Here is my code -

template = cv2.imread(temp_img)
template = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY)
sigma=0.33
v = np.median(template)
lower = int(max(0, (1.0 - sigma) * v))
upper = int(min(255, (1.0 + sigma) * v))
template = cv2.Canny(template, lower, upper)
(tH, tW) = template.shape[:2]
baseImage = cv2.imread(base_img)
gray = cv2.cvtColor(baseImage, cv2.COLOR_BGR2GRAY)
found = None
threshold = 0.8
for scale in np.linspace(0.1, 0.5, 30)[::-1]:
    resized = imutils.resize(gray, width=int(gray.shape[1] * scale))
    r = gray.shape[1] / float(resized.shape[1])
    if resized.shape[0] < tH or resized.shape[1] < tW:
        break   
    v = np.median(resized)
    lower = int(max(0, (1.0 - sigma) * v))
    upper = int(min(255, (1.0 + sigma) * v))
    canny = cv2.Canny(resized, lower, upper)
    res = cv2.matchTemplate(canny, template, cv2.TM_CCOEFF_NORMED)
    (min_val, max_val, _, max_loc) = cv2.minMaxLoc(res) 
    if found is None or max_val > found[0]:
        found = (max_val, max_loc, r)               
(max_val, max_loc, r) = found
if max_val > threshold:
    (start_x, start_y) = (int(max_loc[0] * r), int(max_loc[1] * r))
    (end_x, end_y) = (int((max_loc[0] + tW) * r), int((max_loc[1] + tH) * r))
    cv2.rectangle(original_image, (start_x, start_y), (end_x, end_y), (0,255,0), 2)
    cv2.imshow('detected', original_image)
    cv2.imwrite('detected.png', original_image)
    cv2.waitKey(0)

The reason it takes a long time is that you are searching for each scale of the template image in the given image.

for scale in np.linspace(0.1, 0.5, 30)[::-1]:
    resized = imutils.resize(gray, width=int(gray.shape[1] * scale))

You can remove the for loop which reduce the search time. The trade-off might be the missing template images. For instance: if you have 5 template image in the given image, you might find 2 of them.

The second option is changing the linspace parameters:

  • Current params:

  • start: 0.1

  • stop: 0.5

  • num: 30

  • If we interpret the current params:


  • From the range of 0.1 to 0.5 ratios:

    • 在此处输入图片说明 在此处输入图片说明 在此处输入图片说明 在此处输入图片说明 在此处输入图片说明
    • you are generating 30 samples from each of them.
  • Possible Solutions:


  • You can do shorten range, ie from 0.4-0.5 np.linspace(0.4, 0.5, 30)

  • Or you can reduce the generated sample size, ie 20, np.linspace(0.1, 0.5, 20)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM