Firstly sorry for the long piece of code pasted below.
This is my first time actually having to worry about performance of an application so I haven’t really ever worried about performance.
This piece of code pretty much searches for an image inside another image, it takes 30 seconds to run on my computer, converting the images to greyscale and other changes shaved of 15 seconds, I need another 15 shaved off. I did read a bunch of pages and looked at examples but I couldn’t find the same problems in my code. So any help would be greatly appreciated.
From the looks of it (cProfile) 25 seconds is spent within the Image module, and only 5 seconds in my code.
from PIL import Image
import os, ImageGrab, pdb, time, win32api, win32con
import cProfile
def GetImage(name):
name = name + '.bmp'
try:
print(os.path.join(os.getcwd(),"Images",name))
image = Image.open(os.path.join(os.getcwd(),"Images",name))
except:
print('error opening image;', name)
return image
def Find(name):
image = GetImage(name)
imagebbox = image.getbbox()
screen = ImageGrab.grab()
#screen = Image.open(os.path.join(os.getcwd(),"Images","Untitled.bmp"))
YLimit = screen.getbbox()[3] - imagebbox[3]
XLimit = screen.getbbox()[2] - imagebbox[2]
image = image.convert("L")
Screen = screen.convert("L")
Screen.load()
image.load()
#print(XLimit, YLimit)
Found = False
image = image.getdata()
for y in range(0,YLimit):
for x in range(0,XLimit):
BoxCoordinates = x, y, x+imagebbox[2], y+imagebbox[3]
ScreenGrab = screen.crop(BoxCoordinates)
ScreenGrab = ScreenGrab.getdata()
if image == ScreenGrab:
Found = True
#print("woop")
return x,y
if Found == False:
return "Not Found"
cProfile.run('print(Find("Login"))')
while not directly performance related you could do some things to improve your code:
is idiomatic way to write condition in Python. You don’t need this clause, however, since this return statement could be reached only if image wasn’t found.
in
GetImageyou should create filename once withos.path.join(os.getcwd(),"Images",name)to minimize errors and not to repeat yourself. Also it wouldn’t normally work if you don’t have the image file. Since you’re not handling error in theFind, I’d suggest the following:Your major problem is that you’re doing pixel by pixel search, it’s going to be slow on any meaningful size image.