python-3.x - Python OpenCV 模板匹配结果不佳
问题描述
我正在尝试构建一个可以从在线网站识别扑克牌的工具。
我认为这项任务将是微不足道的。收集所有可能的卡片,将它们粘贴到一张图像中,获取一张“未知”卡片,在 all_cards_image 上运行模板匹配,收集匹配的点,将其与 (x,y) = "Ah" 的字典进行比较,瞧。
但是模板匹配给出了这样的命中和未命中结果,有些单卡根本无法识别,有些单卡同时识别为红桃4、红桃5和红桃6。梅花 8 被识别为黑桃 8,以此类推。当没有卡片存在时,它会匹配整个模板图像。
我找不到可以带来满意结果的阈值。
我附上了整个代码以及图像。
我很清楚,我可以走只识别卡片等级的路线,也许在黑白图像上并用颜色(蓝色,绿色,红色,黑色)掩盖西装,然后再匹配它们。我只是希望有一个简单的模板匹配解决方案而无需跳过箍。
代码中包含所有卡片(all_cards.jpg)的第一张图片:
第二张图片(随机截图),所有其他细节都改为白色,以免图像太大,在代码中命名为“Screenshot_to_test_card_recognition_reduced.png”:
import cv2
import numpy as np
import os
# defining constants for positions, card width and height in a screenshot
CARD_HEIGHT = 59
CARD_WIDTH = 90
HORIZONTAL_SPACE = 5
HORIZONTAL_OFFSET_2 = 1463
VERTICAL_OFFSET_2 = 1047
FIRST_CARD_X = 955
FIRST_CARD_Y = 370
FLOPS_STARTING_POINTS = [(FIRST_CARD_X, FIRST_CARD_Y), (FIRST_CARD_X + HORIZONTAL_OFFSET_2, FIRST_CARD_Y), \
(FIRST_CARD_X, FIRST_CARD_Y + VERTICAL_OFFSET_2), \
(FIRST_CARD_X + HORIZONTAL_OFFSET_2, FIRST_CARD_Y + VERTICAL_OFFSET_2)]
# show image function
def show_image(img, title = "Unnamed"):
cv2.imshow(title, img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# INSERT FOLDER WITH FILES
saved_folder = "D:\\WinPython 32 3.4\\WinPython-32bit-3.4.4.6Qt5\\notebooks\\Named cards"
template_image = os.path.join(saved_folder, 'all_cards.jpg')
screenshot = os.path.join(saved_folder, 'Screenshot_to_test_card_recognition_reduced.png')
img_rgb = cv2.imread(screenshot)
img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)
CORRECTION_FOR_SEARCH_WIDTH = 0 #60
CORRECTION_FOR_SEARCH_HEIGTH = 0 #20
# LOOP THROUGH ALL FIVE CARDS FOR EACH FLOP ON 4 TABLES
for point in FLOPS_STARTING_POINTS:
flop_starting_x, flop_starting_y = point
for card in range (0,5):
start_x = flop_starting_x + ((HORIZONTAL_SPACE) * card) + ((CARD_WIDTH) * card)
end_x = start_x + CARD_WIDTH - CORRECTION_FOR_SEARCH_WIDTH
start_y = flop_starting_y
end_y = start_y + CARD_HEIGHT - CORRECTION_FOR_SEARCH_HEIGTH
template = img_gray[start_y:end_y,start_x:end_x]
w, h = template.shape[::-1]
show_image(template)
all_cards_image = cv2.imread(template_image)
grey_all_cards_image = cv2.cvtColor(all_cards_image, cv2.COLOR_BGR2GRAY)
res = cv2.matchTemplate(grey_all_cards_image,template,cv2.TM_CCOEFF_NORMED)
threshold = 0.85
loc = np.where( res >= threshold)
for pt in zip(*loc[::-1]):
cv2.rectangle(all_cards_image, pt, (pt[0] + w, pt[1] + h), (0,0,255), 2)
print(loc)
show_image(all_cards_image)
解决方案
推荐阅读
- kubernetes - 处理多容器场景下 Kubernetes 中 Pod 的优雅终止
- java - JAVA,有没有办法在我的输出中显示 ArrayList 中的对象名称
- mysql - mysql max 条件在 where 子句中的使用
- python-3.x - Django表单问题
- kubernetes - 在 k8s 中将容器文件系统挂载到 sidecar
- mongodb - MongoDB聚合合并字段
- flutter - 我需要在同一页面中的水平和垂直 listView 构建器。顶部的水平和底部的垂直列表视图
- c - 在 MinGW 上编译和链接 DirectX
- azure - 使用 ARM 模板将密钥添加到 azure 中的现有密钥库
- asp.net - 尝试使用 .Net Framework 连接到 Azure 应用程序配置时出现奇怪的行为