Optimization for screen grab, thresholding, and houghcircles
So I've been working on a project to make a bot visually play One Finger Death Punch. I'm looking for ways to improve and optimize it and need advice. Here is the code for my screen grab, image processing, and enemy detection using houghcircles.
Screen Grab
import win32gui
import win32ui
import win32con
import win32api
import numpy as np
import pywintypes
winlist = []
def enum_cb(hwnd,results):
winlist.append((hwnd, win32gui.GetWindowText(hwnd)))
def get_screen(windowName):
toplist = []
win32gui.EnumWindows(enum_cb, toplist)
game = [(hwnd, title) for hwnd, title in winlist if windowName in title.lower()]
game = game[0]
if game[1] == 'One Finger Death Punch':
hwnd = game[0]
else:
return
try:
if win32gui.GetForegroundWindow() is not hwnd:
win32gui.SetForegroundWindow(hwnd)
left, top, right, bot = win32gui.GetWindowRect(hwnd)
w = right - left
h = bot - top
if w is not 800 and h is not 470:
win32gui.MoveWindow(hwnd, 0, 0, 800, 470, True)
wDC = win32gui.GetWindowDC(hwnd)
dcObj = win32ui.CreateDCFromHandle(wDC)
cDC = dcObj.CreateCompatibleDC()
dataBitMap = win32ui.CreateBitmap()
dataBitMap.CreateCompatibleBitmap(dcObj, w - 18, h - 48)
cDC.SelectObject(dataBitMap)
cDC.BitBlt((0, 0), (w - 18, h - 48), dcObj, (left + 9, top + 37), win32con.SRCCOPY)
signedIntsArray = dataBitMap.GetBitmapBits(True)
img = np.fromstring(signedIntsArray, dtype='uint8')
img.shape = (h - 48, w - 18, 4)
dcObj.DeleteDC()
cDC.DeleteDC()
win32gui.ReleaseDC(hwnd, wDC)
win32gui.DeleteObject(dataBitMap.GetHandle())
return img, win32gui.GetWindowRect(hwnd)
except pywintypes.error:
return
Image Processing
import cv2
import numpy as np
def roi(img, vertices):
#blank mask:
mask = np.zeros_like(img)
for vert in vertices:
# fill the mask
cv2.fillPoly(mask, vert, (255,255,255))
# now only show the area that is the mask
masked = cv2.bitwise_and(img, mask)
return masked
def process_img(original_image, low_threshold, high_threshold,vertices):
img_hsv = cv2.cvtColor(original_image, cv2.COLOR_BGR2HSV)
img_thresholded = cv2.inRange(img_hsv,low_threshold,high_threshold)
erode_x = 2#cv2.getTrackbarPos('erode', 'Control')
erode_y = erode_x
dilate_x = 2#cv2.getTrackbarPos('dilate', 'Control')
dilate_y = dilate_x
ekernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(erode_x,erode_y))
dkernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (dilate_x,dilate_y))
cv2.erode(img_thresholded,ekernel,img_thresholded,iterations = 1)
cv2.dilate(img_thresholded,dkernel,img_thresholded,iterations = 1)
processed_img = roi(img_thresholded, [vertices])
return processed_img
Enemy Detection
import cv2
import numpy as np
from imageprocessing import roi, process_img
def findEnemies(screen,bbox,player_x):
low_threshold = np.array([0, 0, 120])
high_threshold = np.array([0, 0, 160])
vert1 = np.array([[0, 155], [0, 120], [bbox[2] - 430, 120], [bbox[2] - 430, 155]], np.int32)
vert2 = np.array([[411, 155], [411, 120], [bbox[2], 120], [bbox[2], 155]], np.int32)
vertices = np.array([[vert1], [vert2]]) # Enemy vision
enemyview = process_img(screen,low_threshold,high_threshold,vertices)
circles = cv2.HoughCircles(enemyview,cv2.HOUGH_GRADIENT,2,23, param1=100, param2=20, minRadius=6, maxRadius=11)
if circles is not None:
circles = np.uint16(np.around(circles))
for i in circles[0, :]:
cv2.circle(screen, (i[0], i[1]), i[2], (0, 0, 255), 1) # draw the outer circle
cv2.putText(screen,str(abs(int(i[0])-player_x)),(i[0],i[1]),cv2.FONT_HERSHEY_SIMPLEX,0.5,(255,255,255),2)
return enemyview, circles
Measuring the time between screen grabs it starts out ...