Как уменьшить количество ложных срабатываний при совпадении шаблона OpenCV в графическом интерфейсе программного обеспечения

#python #opencv #computer-vision #template-matching

#python #opencv #компьютерное зрение #сопоставление шаблонов

Вопрос:

Я пытаюсь создать tasker для использования в игре, например, бота для выполнения повторяющихся простых задач.

Некоторые элементы, которые я ищу (например, тексты и кнопки), очень похожи (см. Изображения ниже).

Я даже использую маски для получения наилучших результатов, а размер шаблонов точно такой же, как у исходного изображения.

Итак, на главном экране игры должен совпадать только один из элементов, чтобы я мог решить, какое действие должен выполнить бот, но это оценки каждого сопоставления:

изображение /btnCara.png 0.960

изображение /btnCoroa.png 0.960

изображение /btnFinalizar.png 0.988

изображение /btnRender.png 0.875

изображение /btnSim.png 0.997

img/btnJogar.png 0.922 << единственный на изображении

img/txtEnemyChosen.png 0.953

изображение /txtJogarPrimeiro.png 0.945

изображение /txtVocePerdeu.png 0.951

Итак, как я могу уменьшить количество ложных срабатываний и находить на экране только то, что я ищу?

Код, который я использую, находится здесь:

 def SearchImage(img):
    partial_image = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    partial_image= cv2.threshold(partial_image, 0, 255, cv2.THRESH_BINARY)[1]

    # get largest contour from binary image
    contours = cv2.findContours(partial_image.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    contours = contours[0] if len(contours) == 2 else contours[1]
    big_contour = max(contours, key=cv2.contourArea)

    # draw the contour of the piece outline as the mask
    mask = np.zeros((img.shape[0], img.shape[1], 3), dtype=np.uint8)
    cv2.drawContours(mask, [big_contour], 0, (255,255,255), 1)
    hh, ww = mask.shape[:2]

    # extract the template from the BGR (no alpha) piece 
    template = img[:,:,0:3]
    correlation = cv2.matchTemplate(img_np, template, cv2.TM_CCORR_NORMED, mask=mask)
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(correlation)
    max_val_ncc = '{:.3f}'.format(max_val)
    #print("normalize_cross_correlation: "   max_val_ncc)
    xx = max_loc[0]
    yy = max_loc[1]
    #print(xx, yy)
        
    # draw template bounds and corner intersection in red onto img
    cv2.rectangle(screenshot, (xx, yy), (xx ww, yy hh), (0, 0, 255), 1)
    
    #return xx, yy
    return max_val_ncc
  

Это графический интерфейс игры:

Графический интерфейс игры

и это список элементов, которые я ищу в графическом интерфейсе

введите описание изображения здесь

Как вы можете видеть, некоторые из них очень похожи, например, эти два:

введите описание изображения здесьвведите описание изображения здесь

Комментарии:

1. Итак, вы не удовлетворены matchTemplate результатом?

2. странно, что вы получаете такие похожие результаты — возможно, вам нужно изменить значения в matchTemplate , чтобы получить лучшие результаты. Вы также можете отображать изображения после преобразований, чтобы увидеть, какой код используется для сопоставления кнопок. Кстати: бот, который использует pyautogui для сопоставления кнопок — но, вероятно, pyautogui использует cv2 где-то в своем коде: Программирование бота для игры во флеш-игру «Sushi Go Round»

Ответ №1:

Похоже, что в графическом интерфейсе есть некоторые элементы, которые очень похожи, и это привело к несоответствию OpenCV некоторым из них.

Использование метода обнаружения краев с помощью Canny (Документация OpenCV об этом)Я смог удалить ненужную информацию с картинки и добился наилучших результатов.