匹配多个模板,并选择最佳匹配。打开简历

Matching multiple templates, and selecting best match. OpenCV

我正在构建一个程序,它将根据选定的 'split' 运行 某个宏命令。 我有截图中的所有图标 (splits and selected_splits)

def read_all_icons(folder): #read all icons for LiveSplit recognition
    onlyfiles = [f for f in listdir(folder) if isfile(join(folder, f))]
    #print(onlyfiles)
    for file in onlyfiles: #add all icons as readed CV objects in one array
        #  filter selected split icons and not selected split icons
        if "x" in file:
            selected_splits.append(cv.imread(r"" + os.path.dirname(__file__)+ "\img" + "\%s" % file))
            #print(selected_splits)
        else:
            splits.append(cv.imread(r"" + os.path.dirname(__file__)+ "\img" + "\%s" % file))
            #print(splits)
    return 

我想通过遍历数组并检索数组索引来获得 selected_split 最接近的精确匹配(按置信度) 我遇到的问题是从一组已加载的 cv.imread 图标中匹配选定的拆分图像。

这是我尝试过的:

def sel_split(screenshot):
    
    for icon in selected_splits: # select an icon from icon array
        result = cv.matchTemplate(screenshot,icon, cv.TM_CCORR_NORMED)
        min_val, max_val, min_loc, max_loc = cv.minMaxLoc(result)
        threshold = 0.96
        if max_val >= threshold:
            conf_list.append(max_val)
            top_left = max_loc
            bottom_right= (top_left[0] + icon.shape[1], top_left[1] + icon.shape[0])
            cv.rectangle(screenshot, top_left, bottom_right, color=(0,255,0), thickness=2 , lineType=cv.LINE_4)
            print(conf_list)
    return    

wincap = WindowCapture('LiveSplit')
while(True):

    # get an updated image of the software
    screenshot = wincap.get_screenshot()
    sel_split(screenshot)
    cv.imshow('Computer Vision', screenshot)
    

    # press 'q' with the output window focused to exit.
    # waits 1 ms every loop to process key presses
    if cv.waitKey(1) == ord('q'):
        cv.destroyAllWindows()
        break

调试时代码只匹配了部分元素(列出时),不是很一致。

解决方案非常简单,我实际上没有等待它完成就调用了 sel_split。 考虑了一段时间后,我决定实施 asyncio 并在主 while(True) 循环中使用 asyncio.run(sel_split(screenshot)) 到 运行 模板匹配循环。

async  def sel_split(screenshot):
    i = 0
    for icon in selected_splits: # select an icon from icon array  
        i += 1
        result = cv.matchTemplate(screenshot, icon, cv.TM_CCORR_NORMED)
        min_val, max_val, min_loc, max_loc = cv.minMaxLoc(result)
        threshold = 0.96
        if max_val >= threshold:
            selectedsplit = i
            conf_list.append(max_val)
            top_left = max_loc
            bottom_right= (top_left[0] + icon.shape[1], top_left[1] + icon.shape[0])
            cv.rectangle(screenshot, top_left, bottom_right, color=(0,255,0), thickness=2 , lineType=cv.LINE_4)
            print(selectedsplit)

while(True):
    # get an updated image of the game
    screenshot = wincap.get_screenshot()
    asyncio.run(sel_split(screenshot))
    cv.imshow('Computer Vision', screenshot)
    loop_time = time()
    if cv.waitKey(1) == ord('q'):
        cv.destroyAllWindows()
        break

并使用 int i 打印出选定的拆分