如何在屏幕上找到忽略透明像素的图像

How do I find an image on screen ignoring transparent pixels

我有一个资产的 png,比如:

我试图在我的屏幕上找到它,它看起来像:

通常,我会这样使用 pyautoGUI:

pyautogui.locateCenterOnScreen('banana.png', grayscale=True, confidence=0.9)

但目前无法使用。看来问题可能出在我的香蕉资产的透明像素上,这显然不匹配。有没有办法通过忽略香蕉资产的透明像素并将它们视为通配符来做到这一点?或者另一种实现方式?

到目前为止,在我的搜索中,我找到了这个 Git issue with the same issue unresolved since 2014

谢谢!

在OpenCV中,matchTemplate()有一个masked模式。所以你基本上是按原样读取透明模板图像,然后提取它的基本图像和 alpha 通道。 Alpha 通道用作 matchTemplate() 中的掩码。参见 https://docs.opencv.org/4.1.1/df/dfb/group__imgproc__object.html#ga586ebfb0a7fb604b35a23d85391329be

输入:

模板:

import cv2
import numpy as np

# read game image
img = cv2.imread('game.png')

# read bananas image template
template = cv2.imread('bananas.png', cv2.IMREAD_UNCHANGED)
hh, ww = template.shape[:2]

# extract bananas base image and alpha channel and make alpha 3 channels
base = template[:,:,0:3]
alpha = template[:,:,3]
alpha = cv2.merge([alpha,alpha,alpha])

# do masked template matching and save correlation image
correlation = cv2.matchTemplate(img, base, cv2.TM_CCORR_NORMED, mask=alpha)

# set threshold and get all matches
threshhold = 0.95
loc = np.where(correlation >= threshhold)

# draw matches 
result = img.copy()
for pt in zip(*loc[::-1]):
    cv2.rectangle(result, pt, (pt[0]+ww, pt[1]+hh), (0,0,255), 1)
    print(pt)

# save results
cv2.imwrite('bananas_base.png', base)
cv2.imwrite('bananas_alpha.png', alpha)
cv2.imwrite('game_bananas_matches.jpg', result)  

cv2.imshow('base',base)
cv2.imshow('alpha',alpha)
cv2.imshow('result',result)
cv2.waitKey(0)
cv2.destroyAllWindows()

结果: