Meghar
Meghar

Reputation: 15

Template matching a smaller (cropped) image from a larger whole image

I am attempting to template match a cropped template image from the image it was cropped from.

Here's my attempt:

import cv2
import numpy as np
 
def main()
    img_rgb = cv2.imread('whole_image.jpg')
    img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)
    template = cv2.imread('cropped_image_from_whole_image.jpg', 0)
    res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED)
    threshold = 0.8

    for i in res:
        for x in i:
            # Finally check if x >= threshold (means a match?).
            if x >= threshold:
                print('Match found!') 

if __name__ == '__main__':
    main()

Whole image:

whole_image.jpg

Cropped image from whole image:

cropped_image_from_whole_image.jpg

My overarching goal is to accurately check if a given template image is a image cropped from a larger whole image. If there's a match: print to standard output 'Match found!' (No GUI involved, only command line). Is the issue in how I'm handling the res/results? What am I doing wrong?

Upvotes: 1

Views: 1312

Answers (1)

Markus
Markus

Reputation: 6288

For matchTemplate the whole image and the template must have the same resolution.

In your case the whole image has 1600x1200px, the cropped image has 640x640px, while the cropped image contains the full height of the original image.

If you know the factor you can align the resolution:

import cv2


img_rgb = cv2.imread('whole_image.jpg', 0)
template = cv2.imread('cropped_image_from_whole_image.jpg', 0)
template = cv2.resize(template, (1200, 1200))
res = cv2.matchTemplate(img_rgb, template, cv2.TM_CCOEFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)

if max_val >= 0.8:
    print('Match found!')

If not, you can try this: https://stackoverflow.com/a/5364427/18667225

Or you can search the net for something like "multi scale template matching".

Upvotes: 1

Related Questions