2010-04-14 76 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。

這種暴力方式勢必緩慢。