I am creating a program to detect mobs in a pixel rpg. I tried to detect the contours of mobs using OpenCV color filtering because mobs are yellow-red while the background is gray-black, but I can’t find the HSV range, and I’m also not sure about the contour filtering parameters by size and aspect ratio.
from PIL import ImageOps, Image, ImageGrab
from numpy import *
import numpy as np
import time
import cv2
import win32gui
import pyautogui
WINDOW_SUBSTRING = "Game"
def get_window_info():
window_info = {}
win32gui.EnumWindows(set_window_coordinates, window_info)
return window_info
def set_window_coordinates(hwnd, window_info):
if win32gui.IsWindowVisible(hwnd):
if WINDOW_SUBSTRING in win32gui.GetWindowText(hwnd):
rect = win32gui.GetWindowRect(hwnd)
x = rect[0]
y = rect[1]
w = rect[2] - x
h = rect[3] - y
window_info['x'] = x
window_info['y'] = y
window_info['width'] = w
window_info['height'] = h
window_info['name'] = win32gui.GetWindowText(hwnd)
win32gui.SetForegroundWindow(hwnd)
def get_screen(x1, y1, x2, y2):
box = (x1, y1+31, x2, y2-68)
screen = ImageGrab.grab(box)
img = array(screen.getdata(), dtype=uint8).reshape((screen.size[1], screen.size[0], 3))
return img
def find_contours():
window_info = get_window_info()
img = get_screen(
window_info["x"],
window_info["y"],
window_info["x"] + window_info["width"],
window_info["y"] + window_info["height"]
)
img[0:77, 0:182] = (0, 0, 0)
lower_range = np.array([10, 150, 150])
upper_range = np.array([25, 255, 255])
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = gray.astype(np.uint8)
gray = cv2.equalizeHist(gray)
rgb = cv2.cvtColor(gray, cv2.COLOR_GRAY2RGB)
hsv = cv2.cvtColor(rgb, cv2.COLOR_RGB2HSV)
mask = cv2.inRange(hsv, lower_range, upper_range)
kernel = np.ones((5,5),np.uint8)
mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)
contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
monsters = []
for contour in contours:
x, y, w, h = cv2.boundingRect(contour)
if w*h > 300 and w/h > 0.8 and w/h < 1.2:
monsters.append((x, y))
for monster in monsters:
print(f"Monster: {monster}")
cv2.imshow("Mask", mask)
cv2.imshow("Contours", cv2.drawContours(img, contours, -1, (0, 255, 0), 2))
cv2.waitKey(0)
cv2.destroyAllWindows()
def main():
find_contours()
if __name__== '__main__':
main()
Initially, I tried to just look for contours in the image, but this led to dozens of extra tons. All objects in the game consist of different pixel patterns. It got better after using color filtering, but the program still doesn’t find mobs. Best result Mask
BeastLike Good is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.