我正在尝试查找并识别项目图像中的代理/角色图标(特别是带有绿色边框的代理图标)。我一个月前才开始学习 OpenCV,最成功的就是使用模板匹配来查找代理图标。
但是我面临的最大问题是除了使用阈值之外如何区分坏匹配和好匹配。有时,当我尝试模板匹配代理图标时,我的程序会指向图像的错误部分。例如,当我将 Omen_Icon 图像模板匹配到 MiniMap1 中时,程序将指向 MiniMap1FindingOmen 上的错误位置,如红点所示。同样,当我尝试模板匹配重叠图像时,由于代理图标隐藏在另一个图标后面,毫不奇怪,我的程序将指向图像的错误部分。例如,在MiniMap2中,我们可以看到Raze_Icon图像位于另一个代理图标后面,并且我的程序将在MiniMap2FindingRaze中指向错误的位置。我希望可以使用阈值来区分不良匹配和良好匹配,但是我的不良匹配和良好匹配经常在与平方差之和的模板匹配中具有相似的值,因此很难找到一条明确的线来区分不良匹配和良好匹配。很好的搭配。
我的模板匹配代码:
import numpy as np
import cv2
from pathlib import Path
from isolatingGreenAgentIcons import refinedColorThresholds
# Compares an image to a template to see if a match is found
mapName = "Haven3"
listOfRoundNumbers = [1]
listOfAgentsToFind = ["sova"]
# Get the path to the parent directory
parentParentDirectory = Path.cwd().parent.parent
miniMapPath = parentParentDirectory.joinpath("miniMaps")
# print("MiniMap Path: ", miniMapPath)
def agentFindingInMiniMap(agent, imgRGB):
baseTemplate = cv2.imread(str(parentParentDirectory / f"agentIconImgs/{agent}.png"), 0)
# Loaded in the template
h, w = baseTemplate.shape
imgGray = cv2.cvtColor(imgRGB, cv2.COLOR_BGR2GRAY)
# Created a copy of the Colored Image but in Gray scale
result = cv2.matchTemplate(imgGray, baseTemplate, cv2.TM_SQDIFF_NORMED)
# SQDIFF_NORMED is the Sum of Squared Differences, which means similar images have a smaller difference
# aka the values are btw 0 and 1, and the closer the min value of result is to 0, the more closely the
# base template and image patch match
maxDiff = 0.5
# Right now, I have a high threshold because I can't find a value that will consistently separate bad matches and good matches
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
if min_val < maxDiff:
print(f"We found a(n) {agent} with our Base Template! Min value: ", min_val)
top_left_loc = min_loc # min_location is in (column, row) format, which is why you add w first before h
bottom_right_loc = (top_left_loc[0] + w, top_left_loc[1] + h)
xCoord = int((top_left_loc[0] + bottom_right_loc[0])/2)
yCoord = int((top_left_loc[1] + bottom_right_loc[1])/2)
imgRGB = cv2.circle(imgRGB, (xCoord,yCoord), radius=3, color=(0, 0, 255), thickness=-1)
# Dotted where the agent is found on the minimap
cv2.imshow("Match", imgRGB)
cv2.waitKey(0)
cv2.destroyAllWindows()
else:
print(f"No match was found => Agent {agent} was not found ", min_val)
if __name__ == "__main__":
for roundNumber in listOfRoundNumbers:
try:
print("Round Number: ", roundNumber)
imgMiniMap = refinedColorThresholds(mapName, roundNumber)
for agent in listOfAgentsToFind:
agentFindingInMiniMap(agent, imgMiniMap)
except Exception as e:
print(f"An error occurred while processing round {roundNumber}: {str(e)}")
我还尝试使用 SIFT 或 ORB 以及基于 FLANN 的 Matcher 或 Brute-Force Matcher 进行特征检测和匹配,但结果不准确(我猜测是因为我的模板中没有足够的像素来查找特征)。
感谢您阅读我的帖子!
编辑:
澄清一下,MiniMap1 和 MiniMap1FindingOmen 除了红点之外看起来不同的原因是因为我使用了一些遮罩来隔离代理图标。这样,我认为匹配不良的可能性就会降低,因为没有代理图标的区域被涂黑了。 MiniMap2 和 MiniMap2FindingRaze 也是如此。