2010-04-14 5 views
0

Сначала извините за длинный кусок кода, вставленный ниже. Это мой первый раз, когда мне действительно нужно беспокоиться о производительности приложения, поэтому я никогда не беспокоился о производительности. Этот фрагмент кода в значительной степени ищет изображение внутри другого изображения, он занимает 30 секунд, чтобы работать на моем компьютере, конвертируя изображения в оттенки серого и другие изменения, выбритые 15 секунд, мне нужно еще 15 сбрить. Я прочитал кучу страниц и посмотрел примеры, но я не мог найти те же проблемы в своем коде. Поэтому любая помощь будет очень признательна.Оптимизация кода с использованием PIL

Из внешнего вида (cProfile) 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. Однако вам не нужен этот раздел, так как этот оператор возврата может быть достигнут, только если изображение не было найдено.

в 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

Этот алгоритм довольно интенсивно вычисляется, я не думаю, что вы можете ускорить его, не меняя подход.

позволяет сделать некоторые математике: Say экран 1024x768 (мы еще в 2000 году) Произнесите тест изображения 100x100 Тогда вы в конечном итоге делает 924 * 668 БЛИЦ 100х100 Thats эквивалентно примерно 7848 полноэкранные блики.

Он должен быть медленным с этим подходом грубой силы.

Смежные вопросы