0

Template Source Image 1 Source Image 2

I have a template "X"(symbol) which is cropped out of "Image1". I am using OpenCV's matchTemplate() method to match the template "X" with "Image1" and it does that successfully. However, I have another image called "Image2" which has contains the X symbol, but when I'm using the template "X" to match with "Image2" , it's showing an invalid match. Any help would be much appreciated.


def match_template(img_path, img_template_path):
    if img_path is not None:
        img = cv.imread(img_path, 0)
        if img is not None:
            template = cv.imread(img_template_path, 0)
            temp_h, temp_w, img_h, img_w = None, None, None, None

            if len(img.shape) > 2:
                print("This image is in color..")
                print("Converting it into a grayscale image")
                img = cv.cvtColor(src=img, code=cv.COLOR_BGR2GRAY)
            else:
                temp_w, temp_h = template.shape[::-1]
                img_w, img_h = img.shape[::-1]
            # ims = cv.resize(img, (960, 540))

            if temp_h and img_h is not None:
                if temp_w < img_w and temp_h < img_h:
                    res = cv.matchTemplate(img, template, cv.TM_SQDIFF)
                    # loc = np.where(res >= 0.9)
                    min_val, max_val, min_loc, max_loc = cv.minMaxLoc(res)

                    threshold = 0.9
                    match = False

                    if np.max(res) > threshold:
                        match = True

                    # Take minimum since we are using TM_SQDIFF
                    if match is True:
                        top_left = min_loc
                        bottom_right = (top_left[0] + temp_w, top_left[1] + temp_h)
                        cv.rectangle(img=img, pt1=top_left, pt2=bottom_right, color=(0, 255, 0), thickness=5)
                        # plt.subplot(121), plt.imshow(res, cmap='gray')
                        # plt.title('Matching Result'), plt.xticks([]), plt.yticks([])
                        plt.imshow(img, cmap='gray')
                        plt.title('Detected Point'), plt.xticks([]), plt.yticks([])
                        plt.show()
                        print("Coordinates of the plotted image are ", top_left, " ", bottom_right)
                        cv.waitKey(0)
                    else:
                        print("Template not matched with the image")
                else:
                    print("Template height and width must be less than origninal image's height and width \n")
            else:
                print("Image heigth and template height are None")
        else:
            print("Image not read successfully!!")
    else:
        print("Image path not provided")

Ashlin Karkada
  • 1,320
  • 1
  • 12
  • 20

1 Answers1

0

First of all, TemplateMatching only works in the images almost same. Small changes on the desired objects included in new frames can create difficulties to make a good match.

In your case, the first example is working properly because you just cropped the template from it. Like the examples also did exactly like that: Example 1 and Example 2.

I dont suggest using TemplateMatching alone. matchShape function is also a very effective function. You can get the contour arrays of your template image(for example symbol x contour) and compare with the other contours. My suggestion is you should support your TemplateMatching function with the other OpenCV structural functions.

The same problems are also mentioned in these posts: here and also here

Yunus Temurlenk
  • 4,085
  • 4
  • 18
  • 39