我也面临同样的挑战。
更快的解决方案 - 相同大小减法的模板匹配
正如您所建议的,“为每种类型的棋子调用 64 次模板匹配函数,以匹配相同大小的每个单独的正方形”要快得多。
但是您不需要获得 64 个屏幕截图。只需 1 个屏幕截图即可,然后您会得到 64 个减法。
full_image= cv2.imread('path_to_screenshot')
square_subtraction = full_image[yi:yf,xi:xf]
如果棋盘不在屏幕上的同一位置,则应先在全屏上搜索,然后进行减法。
最快的解决方案 - 像素签名
也有可能每件作品都有一个特定的 x,y 坐标的唯一像素,这将使它与所有其他 11 件作品不同。我称之为“像素签名”。
如果你能找到这个签名,你可以使用像素匹配而不是第一个解决方案的模板匹配。
这是我在一组模板中查找唯一像素的代码。
from os import walk
def compare_pixel_RGB(rgb_to_compare, row, column):
n = 0
for item in templates:
rgb = templates[item][row][column]
if (rgb_to_compare == rgb).all() :
n += 1
return n
#Load template images. They should all have the same size.
templates = dict()
for (dirpath, dirnames, filenames) in walk('templates_board/'):
for filename in filenames:
if filename.endswith('.png'):
template = cv2.imread('templates_board/'+filename)
templates.update({filename: template})
#Create and populate matching DataFrame with same dimensions of the templates.
#Each cell of the DataFrame corresponds to a pixel of the templates and has the sum of matching pixels for all pieces on this specific coordinate.
#We are hoping to find a cell = 12, meaning that each piece only matches itself and not any other one.
matching_list = list()
random_item = list(templates.keys())[0]
matching = pd.DataFrame(np.zeros((templates[random_item].shape[0],templates[random_item].shape[1])))
for item in templates:
for row in range(templates[item].shape[0]):
for column in range(templates[item].shape[1]):
rgb = templates[item][row][column]
count_same_pixel = compare_pixel_RGB(rgb, row, column)
matching_list.append([item, row, column, count_same_pixel])
matching[column][row] = matching[column][row] + count_same_pixel
如果您找到像素签名坐标(上面的column x row),您可以使用它来为棋盘的 64 个正方形中的每一个进行像素减法,并与您的模板像素签名进行比较:
full_image = cv2.imread('path_to_screenshot')
square_subtraction = full_image[yi:yf,xi:xf]
square_pixel = square_subtraction[column][row]
template = cv2.imread('path_to_template')
template_signature = template[column][row]
只需遍历棋盘的每个方格并与每个模板进行比较,就像第一种解决方案一样,但不是模板匹配,您只需要比较像素。
template_signature == square_pixel