本文介绍了单个模板与多个源图像的模板匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个模板X"(符号),它是从Image1"中裁剪出来的.我正在使用 OpenCV 的 matchTemplate() 方法将模板X"与Image1"匹配,并且它成功地做到了这一点.但是,我有另一个名为 "Image2" 的图像,其中包含 X 符号,但是当我使用模板 "X" 与 "Image2" 匹配时,它显示无效匹配.任何帮助将不胜感激.

def match_template(img_path, img_template_path):如果 img_path 不是 None:img = cv.imread(img_path, 0)如果 img 不是 None:模板 = cv.imread(img_template_path, 0)temp_h、temp_w、img_h、img_w = 无、无、无、无如果 len(img.shape) >2:print("这张图片是彩色的..")print("将其转换为灰度图像")img = cv.cvtColor(src=img, 代码=cv.COLOR_BGR2GRAY)别的:temp_w, temp_h = template.shape[::-1]img_w, img_h = img.shape[::-1]# ims = cv.resize(img, (960, 540))如果 temp_h 和 img_h 不是 None:如果 temp_w 临界点:匹配 = 真# 取最小值,因为我们使用的是 TM_SQDIFF如果匹配为真:top_left = min_locbottom_right = (top_left[0] + temp_w, top_left[1] + temp_h)cv.rectangle(img=img, pt1=top_left, pt2=bottom_right, 颜色=(0, 255, 0), 厚度=5)# plt.subplot(121), plt.imshow(res, cmap='gray')# plt.title('匹配结果'), plt.xticks([]), plt.yticks([])plt.imshow(img, cmap='gray')plt.title('检测到的点'), plt.xticks([]), plt.yticks([])plt.show()print("绘制图像的坐标为", top_left, " ", bottom_right)cv.waitKey(0)别的:print("模板与图片不匹配")别的:print("模板高度和宽度必须小于原始图像的高度和宽度\n")别的:print("图片高度和模板高度为无")别的:print("图片读取不成功!!")别的:print("未提供图片路径")
解决方案

首先,TemplateMatching 仅适用于几乎相同的图像.新框架中包含的所需对象的微小变化可能会导致难以进行良好匹配.

就您而言,第一个示例工作正常,因为您刚刚从中裁剪了模板.就像示例也完全一样:示例 1示例 2.

我不建议单独使用 TemplateMatching.matchShape 函数也是一个非常有效的函数.您可以获取模板图像的轮廓数组(例如 symbol x 轮廓)并与其他轮廓进行比较.我的建议是您应该使用其他 OpenCV 结构函数来支持您的 TemplateMatching 函数.

这些帖子中也提到了同样的问题:此处也在这里

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")

解决方案

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

这篇关于单个模板与多个源图像的模板匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-22 12:39