如何减少软件 GUI 上 openCV 模板匹配的误报
How to reduce false positive on openCV template match on a software GUI
我正在尝试创建一个用于游戏的任务器,就像一个机器人来执行重复的简单任务。
我正在寻找的一些元素(如文本和按钮)非常相似(见下图)。
我什至使用蒙版来获得最佳效果,模板的大小与原始图片完全相同。
所以,在游戏的主屏幕上,只有一个元素必须匹配,所以我可以决定机器人必须执行什么动作,但这些是每个匹配的等级:
img/btnCara.png 0.960
img/btnCoroa.png 0.960
img/btnFinalizar.png 0.988
img/btnRender.png 0.875
img/btnSim.png 0.997
img/btnJogar.png 0.922 << 图片上唯一的一个
img/txtEnemyChosen.png 0.953
img/txtJogarPrimeiro.png 0.945
img/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
这是游戏的GUI:
这是我在 GUI 上寻找的元素列表
如您所见,其中一些非常相似,例如这两个:
看起来 GUI 中有一些非常相似的元素,导致 openCV 与其中一些元素不匹配。
使用Canny Edge Detector技术(OpenCV Documentation about it)我可以从图片中去除不需要的信息并取得最佳效果。
我正在尝试创建一个用于游戏的任务器,就像一个机器人来执行重复的简单任务。
我正在寻找的一些元素(如文本和按钮)非常相似(见下图)。
我什至使用蒙版来获得最佳效果,模板的大小与原始图片完全相同。
所以,在游戏的主屏幕上,只有一个元素必须匹配,所以我可以决定机器人必须执行什么动作,但这些是每个匹配的等级:
img/btnCara.png 0.960
img/btnCoroa.png 0.960
img/btnFinalizar.png 0.988
img/btnRender.png 0.875
img/btnSim.png 0.997
img/btnJogar.png 0.922 << 图片上唯一的一个
img/txtEnemyChosen.png 0.953
img/txtJogarPrimeiro.png 0.945
img/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
这是游戏的GUI:
这是我在 GUI 上寻找的元素列表
如您所见,其中一些非常相似,例如这两个:
看起来 GUI 中有一些非常相似的元素,导致 openCV 与其中一些元素不匹配。
使用Canny Edge Detector技术(OpenCV Documentation about it)我可以从图片中去除不需要的信息并取得最佳效果。