# Get minimap part from the entire frame
minimap = frame[map_y_min:map_y_max, map_x_min:map_x_max]
minimap_clone = minimap.copy()
# For each icon which exist in the current game
for name, icon in icon_dict.items():
matched = False
crop_px = 0
while not matched:
# Center-cropping
if crop_px > MAX_CENTER_CROP:
break
if crop_px > 0:
icon_query = icon[crop_px:-crop_px, crop_px:-crop_px].copy()
else:
icon_query = icon.copy()
# Resize query icon to specific size
icon_mini = cv2.resize(icon_query, query_size)
# Find the optimal position for the entire icon, and the top, bottom, left and right part
for icon in [icon_mini, icon_mini[:CROP_PX], icon_mini[-CROP_PX:], icon_mini[:, :CROP_PX], icon_mini[:, -CROP_PX:]]:
# Extract the dominant HSV color from the icon
icon_HSV = cv2.cvtColor(cv2.resize(icon, (1,1)), cv2.COLOR_BGR2HSV).astype(np.float32)
(tH, tW) = icon.shape[:2]
# Find the matched region using the query icon as a template
result = cv2.matchTemplate(minimap, icon, cv2.TM_CCOEFF_NORMED)
scores = np.sort(result.reshape(-1))[::-1]
# for top-k matched regions
for score in scores[:top_k]:
(yCoords, xCoords) = np.where(result == score)
for x, y in zip(xCoords, yCoords):
# matched region comparison (HSV difference score and SSIM)
matched_part = minimap[y:y+tH, x:x+tW].copy()
matched_HSV = cv2.cvtColor(cv2.resize(matched_part, (1,1)), cv2.COLOR_BGR2HSV).astype(np.float32)
HSV_diff = np.mean(np.abs(icon_HSV - matched_HSV))
ssim = structural_similarity(icon, matched_part, multichannel=True)
# check the matched region is valid
if (HSV_diff < 10 and ssim > 0.35) or (HSV_diff < 25 and ssim > 0.7) or (HSV_diff < 15 and ssim > 0.55):
matched = True
cv2.rectangle(minimap_clone, (x, y), (x + tW, y + tH), (0, 0, 255), 1)
cv2.putText(minimap_clone, name, (x, y), cv2.FONT_HERSHEY_SIMPLEX, 0.3, (0,0,255))
break
if matched:
break
if matched:
break
# Center-cropping for one more pixel
crop_px += 1