Home > Software design >  Matching multiple templates, and selecting best match. OpenCV
Matching multiple templates, and selecting best match. OpenCV

Time:11-14

I'm building a program that will depending on selected 'split' run a certain macro command. I have all of the icons from screenshot (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 

I want to get the closest exact match (by confidence) for the selected_split by looping trough the array and retrieving the array index The issue i have is matching the selected split image from an array of loaded cv.imread icons. LiveSplit

Here is what i tried:

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

When debugging the code only matches some of the elements (when listing) and it is not very consistent.

enter image description here

CodePudding user response:

The solution was really quite simple, i was calling sel_split without actualy waiting for it to finish. After thinking for a while i decided to implement asyncio and in the main while(True) loop use asyncio.run(sel_split(screenshot)) to run the template matching loop.

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

enter image description here enter image description here

And using int i to get the selected split printed out

enter image description here

  • Related