2010-04-14 77 views
0

首先抱歉粘贴下面的长段代码。 这是我第一次真的不用担心应用程序的性能,所以我并不真的担心性能。 这段代码几乎在另一张图片中搜索一张图片,在我的计算机上运行需要30秒,将图片转换为灰度,并且其他修改的时间为15秒,我需要另外15张剃掉。我读了一堆页面,看了一些例子,但在代码中找不到相同的问题。所以任何帮助将不胜感激。使用PIL优化代码

从它的外观(cProfile)在Image模块中花了25秒,而在我的代码中只花了5秒。

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"))') 

回答

1

虽然没有直接的表现,你可以做一些事情,以改善你的代码相关:

if not Found: 
    return "Not Found" 

是用Python写的条件惯用的方式。但是,您不需要此子句,因为只有在未找到图像时才能够达到此返回语句。

in GetImage您应该创建文件名一次与os.path.join(os.getcwd(),"Images",name)以最大限度地减少错误,而不是重复自己。如果你没有图像文件,它也不会正常工作。既然你不是在Find处理错误,我建议如下:

def Find(name): 
    fname = os.path.join(os.getcwd(), "Images", name + '.bmp') 
    image = Image.open(fname) 
    imagebbox = image.getbbox() 
    screen = ImageGrab.grab() 
    YLimit = screen.getbbox()[3] - imagebbox[3] 
    XLimit = screen.getbbox()[2] - imagebbox[2] 
    image = image.convert("L") 
    Screen = screen.convert("L") 
    Screen.load() 
    image.load() 
    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: 
       return x, y 
    # returns None implicitly 

你的主要问题是,你正在做的像素搜索像素,这将是任何有意义的尺寸的影像上缓慢。

1

这个算法是相当计算密集的,我不相信你可以在不改变方法的情况下加快速度。

让我们做一些数学: 说屏幕为1024x768(我们仍然在2000年) 说你的测试图像是100x100的 那么你最终做的100×100 那是924米* 668米的blit约相当于7848全屏幕blits。

这种暴力方式势必缓慢。