cv2.matchTemplate finds wrong template in image

非 Y 不嫁゛ 提交于 2021-02-04 05:11:54

问题


I'm trying to create a program that knows what number is on an image with the following 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

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

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 thats the wrong image.

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

wich prints True, but it does that for every number png I saved.

How do I make my program recognize the 7.png in the img.png without recognizing every single number png?

img.png:

6.png:

7.png:


回答1:


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). '




回答2:


Here is an example of using a template mask to do template matching at one resolution level using 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. 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.

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)



来源:https://stackoverflow.com/questions/59759374/cv2-matchtemplate-finds-wrong-template-in-image

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!