refer to:
https://pyimagesearch.com/2015/01/26/multi-scale-template-matching-using-python-opencv/
结论:
最好还是用手动截取的template
缩放截取的,匹配度比较低。
关键代码:
# 缩放模板图像 scale_percent = 60 # 缩放比例为60% width = int(template_image.shape[1] * scale_percent / 100) height = int(template_image.shape[0] * scale_percent / 100) dim = (width, height) template_image_scaled = cv2.resize(template_image, dim, interpolation=cv2.INTER_AREA)
完整代码:
import cv2 source_image_name = "test_003.jpg" threadhold = 0.88 #对该页面的所有区域进行匹配, 并且对template进行缩放 x 0.6 target_left, target_top = 1016, 222 target_right, target_bottom = 1280, 304 source_image = cv2.imread(source_image_name, cv2.IMREAD_COLOR)[target_top:target_bottom, target_left:target_right] cv2.imshow('source_image',source_image) cv2.waitKey(0) # 先获得所有牌的模板 from os import listdir from os.path import isfile, join found_cards = [] onlyfiles = [f for f in listdir("cards_images") if isfile(join("cards_images", f)) and f.endswith(".jpg")] for template_file_name in onlyfiles: template_image = cv2.imread(f"cards_images/{template_file_name}", cv2.IMREAD_COLOR) result = cv2.matchTemplate(source_image, template_image, cv2.TM_CCOEFF_NORMED) # 对template 缩放为 0.6 scale_percent = 0.614 width = int(template_image.shape[1] * scale_percent) height = int(template_image.shape[0] * scale_percent ) template_image = cv2.resize( template_image, (width, height), interpolation=cv2.INTER_AREA) #template_image = cv2.imread(f"cards_images/{template_file_name}", cv2.IMREAD_GRAYSCALE) result = cv2.matchTemplate(source_image, template_image, cv2.TM_CCOEFF_NORMED) min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result) print(f"== max_val: {max_val}") # 如果匹配到,则把对应的目标区域整个覆盖 if max_val >= threadhold: #print(f"== 匹配到了, 牌:{template_file_name}, 准确率:{max_val}") top_left = max_loc # shape: 返回的是 height, width, channel. 所以 0 是高,1 是宽 bottom_right = (top_left[0] + template_image.shape[1], top_left[1] + template_image.shape[0]) cv2.rectangle(source_image, top_left, bottom_right, (0, 255, 0), -1) card_name = template_file_name.split(".")[0] found_cards.append(card_name) print(f"== 找到了:{card_name}, {max_val}") cv2.imshow('result', source_image) cv2.waitKey(0) else: pass # 打印出所有的牌 print(f"== cards: {found_cards}") short_names = [] for card_full_name in found_cards: short_names.append(card_full_name.split("_")[0]) print(f"== short name cards: {short_names}")
结果如下: