简体   繁体   English

cv2.matchTemplate 在图像中发现错误的模板

[英]cv2.matchTemplate finds wrong template in image

I'm trying to create a program that knows what number is on an image with the following function:我正在尝试创建一个程序,该程序知道具有以下 function 的图像上的数字:

def img_in_img(big_picture, small_picture, tamper):
    big_picture = str(big_picture)
    small_picture = str(small_picture)
    if os.path.isfile(big_picture) == False or os.path.isfile(small_picture) == False:
        return "Image does not exist"

    img = cv2.imread(big_picture,0)
    templace_loc = small_picture
    template = cv2.imread(templace_loc,0)
    w, h = template.shape[::-1]
    method = cv2.TM_CCOEFF
    
    tamper = int(tamper)

    res = cv2.matchTemplate(img,template,method)
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)

    top_left = max_loc
    bottom_right = (top_left[0] + w, top_left[1] + h)

    height, width, channels = cv2.imread(templace_loc).shape

    if int(top_left[0]) < int(height + tamper) and int(top_left[0]) > int(height - tamper) and int(top_left[1]) < int(width + tamper) and int(top_left[1]) > int(width - tamper):
        return True
    else:
        return False

But then when I check if 7.png is in img.png with the code但是当我用代码检查7.png是否在img.png中时

nur = "7"
if img_in_img("2020-01-14-17-36-08.537043/verification_image2.png", "verifynr/" + "old_orange" + "/" + nur + ".png", 25):
    print(Style.BRIGHT + Fore.GREEN + "Color: " + "old_orange" + ", Num: " + nur + Fore.RESET)
else:
    print(Style.BRIGHT + Fore.RED + "Color: " + "old_orange" + ", Num: " + nur + Fore.RESET)

it gives me in RED: Color: old_orange, Num: 7它给了我红色: Color: old_orange, Num: 7

but then if I check if 6.png is in img.png by changing nur from 7 to 6 it gives me in Green: Color: old_orange, Num: 6 , but that's the wrong image.但是如果我通过将nur7更改为6来检查6.png是否在img.png中,它会给我 Green: Color: old_orange, Num: 6 ,但这是错误的图像。

I've also tried the following code:我还尝试了以下代码:

img_rgb = cv2.imread("2020-01-14-17-36-08.537043/verification_image2.png")
img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)
template = cv2.imread('verifynr/old_orange/7.png',0)
w, h = template.shape[::-1]

res = cv2.matchTemplate(img_gray,template,cv2.TM_SQDIFF)
threshold = 0.8
loc = np.where( res >= threshold)
pt = list(zip(*loc[::-1]))

if len(pt) >= 1:
    print("True")

which prints True , but it does that for every number png I saved.它打印True ,但它对我保存的每个数字 png 都这样做。

How do I make my program recognize the 7.png in the img.png without recognizing every single number png?如何让我的程序识别7.png中的img.png而不识别每个数字 png?

img.png:图片.png:

图片.png

6.png: 6.png:

6.png

7.png: 7.png:

7.png

Template matching not for object detection or pattern recognition, it's function is to find the most similar patch position.模板匹配不是用于物体检测或模式识别,它的功能是找到最相似的补丁位置。 For detection use detectors (haar, dnn based ones, ...), for recognition use classifiers (descriptor based or nn based).对于检测使用检测器(haar,基于 dnn 的,...),对于识别使用分类器(基于描述符或基于 nn)。 ' '

Here is an example of using a template mask to do template matching at one resolution level using Python/OpenCV.这是使用模板掩码在一个分辨率级别使用 Python/OpenCV 进行模板匹配的示例。 The black region of the mask tells the template matching to ignore those regions when matching, so that when the template has a background color different from that in the larger image, it does not degrade the match score. mask 的黑色区域告诉模板匹配在匹配时忽略这些区域,这样当模板的背景颜色与较大图像中的背景颜色不同时,它不会降低匹配分数。 Only the color regions of the template corresponding to the white in the mask contribute to the matching score.只有与蒙版中白色相对应的模板颜色区域才对匹配分数有贡献。 Note that masked template matching in OpenCV only works for methods TM_SQDIFF and TM_CCORR_NORMED.请注意,OpenCV 中的屏蔽模板匹配仅适用于方法 TM_SQDIFF 和 TM_CCORR_NORMED。

Input:输入:

在此处输入图片说明

Template:模板:

在此处输入图片说明

Template Mask:模板掩码:

在此处输入图片说明

import cv2
import numpy as np

# read image
img = cv2.imread('logo.png')

# read template
tmplt = cv2.imread('hat.png')
hh, ww, cc = tmplt.shape

# read template mask as grayscale
tmplt_mask = cv2.imread('hat_mask.png', cv2.COLOR_BGR2GRAY)

# do template matching
corrimg = cv2.matchTemplate(img,tmplt,cv2.TM_CCORR_NORMED, mask=tmplt_mask)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(corrimg)
max_val_ncc = '{:.3f}'.format(max_val)
print("correlation match score: " + max_val_ncc)
xx = max_loc[0]
yy = max_loc[1]
print('xmatch =',xx,'ymatch =',yy)

# draw red bounding box to define match location
result = img.copy()
pt1 = (xx,yy)
pt2 = (xx+ww, yy+hh)
cv2.rectangle(result, pt1, pt2, (0,0,255), 1)

cv2.imshow('image', img)
cv2.imshow('template', tmplt)
cv2.imshow('template_mask', tmplt_mask)
cv2.imshow('result', result)
cv2.waitKey(0)
cv2.destroyAllWindows()

# save results
cv2.imwrite('logo_hat_match.png', result)


Result:结果:

在此处输入图片说明

Textual Information Listed:列出的文字信息:

correlation match score: 1.000
xmatch = 417 ymatch = 44

(Apologies for borrowing and modifying the ImageMagick logo. I already had that template matching example) (抱歉借用和修改 ImageMagick 标志。我已经有了那个模板匹配示例)

These are some few potential causes:这些是一些潜在的原因:

Scale and rotation difference: If the template image and the image you are searching for the template in have different scales or rotations, cv2.matchTemplate() may not find a match.比例和旋转差异:如果模板图像和您在其中搜索模板的图像具有不同的比例或旋转,cv2.matchTemplate() 可能找不到匹配项。 You can try using techniques such as scaling or rotating the template image to match the image you are searching in.您可以尝试使用缩放或旋转模板图像等技术来匹配您正在搜索的图像。

Lighting and contrast differences: If the lighting or contrast of the template image and the image you are searching in are different, it can affect the accuracy of the match.光照和对比度差异:如果模板图像和您正在搜索的图像的光照或对比度不同,会影响匹配的准确性。 You can try adjusting the brightness and contrast of the images to make them more similar.您可以尝试调整图像的亮度和对比度,使它们更相似。

Template size: If the template is too small or too big compared to the area you are searching in, it can affect the accuracy of the match.模板大小:如果模板与您正在搜索的区域相比太小或太大,都会影响匹配的准确性。 You should try using a template size that is similar to the expected size of the object in the image.您应该尝试使用与图像中 object 的预期大小相似的模板大小。

Similarity threshold: The matchTemplate() method has a threshold value that you can set to control the level of similarity required for a match.相似度阈值: matchTemplate() 方法有一个阈值,您可以设置该阈值来控制匹配所需的相似度级别。 If the threshold value is set too high, it may not find any matches even if there are similar templates in the image.如果阈值设置得太高,即使图像中有相似的模板也可能找不到匹配项。 If it's set too low, it may return false positives.如果它设置得太低,它可能会返回误报。

Similarity Measurement Algorithm: matchTemplate() uses a specific algorithm for measuring the similarity between the template and the search image.相似度测量算法: matchTemplate() 使用特定算法来测量模板和搜索图像之间的相似度。 Depending on the image and the template, one algorithm might work better than another.根据图像和模板,一种算法可能比另一种算法效果更好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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