The most efficient / fastest way to analyze data using Python?

I created a simple Python script that is activated whenever a certain program is launched. This program sends information to the screen, which the script must capture and analyze.

Part of the script logic can be expressed as follows:

while a certain condition is met:
    function to continuously check pixel information on a fixed area of the screen()
    if pixel data (e.g. RGB) changes:
        do something
    else:
        continues to check

I have already found what does exactly this, but not as fast as I would like. Here is a solution using the Python Imaging Library (PIL) with arbitrary values:

import ImageGrab

box = (0,0,100,100) # 100x100 screen area to capture (0x0 is top left corner)
pixel = (60,20) #target pixel coordenates (must be within the box boundaries)
im = ImageGrab.grab(box) #grabs the image area (aka printscreen) -> source of bottleneck
hm = im.getpixel(pixel) # gets pixel information from the captured image in the form of an RGB value

RGB , . , - , , - , script . , script , , , , , .

script ~ 30 i7 4770k. , , , . - 200, 150 , script 5-10 .

, : ?

+4
2

, , , , Python pywin32 (, ). " " numpy whatnot. , 5 (6 ):

import win32ui
window_name = "Target Window Name" # use EnumerateWindow for a complete list
wd = win32ui.FindWindow(None, window_name)
dc = wd.GetWindowDC() # Get window handle
j = dc.GetPixel (60,20)  # as practical and intuitive as using PIL!
print j
dc.DeleteDC() # necessary to handle garbage collection, otherwise code starts to slow down over many iterations

. (COLORREF) , ( , RGB hex) , , , ! , ( Python build CPython i7 4770k):

( ):

    import ImageGrab, time
    box = (0,0,100,100) #100 x 100 square box to capture
    pixel = (60,20) #pixel coordinates (must be within the box boundaries)
    t1 = time.time()
    count = 0
    while count < 1000:
        s = ImageGrab.grab(box) #grabs the image area
        h = s.getpixel(pixel) #gets pixel RGB value
        count += 1
    t2 = time.time()
    tf = t2-t1
    it_per_sec = int(count/tf)
    print (str(it_per_sec) + " iterations per second")

29 . , .

, BenjaminGolder ctypes:

from ctypes import windll
import time
dc= windll.user32.GetDC(0)
count = 0
t1 = time.time()
while count < 1000:
    a= windll.gdi32.GetPixel(dc,x,y)
    count += 1
t2 = time.time()
tf = t2-t1
print int(count/tf)

54 . 86%, , .

, , :

name = "Python 2.7.6 Shell" #just an example of a window I had open at the time
w = win32ui.FindWindow( None, name )
t1 = time.time()
count = 0
while count < 1000:
    dc = w.GetWindowDC()
    dc.GetPixel (60,20)
    dc.DeleteDC()
    count +=1
t2 = time.time()
tf = t2-t1
it_per_sec = int(count/tf)
print (str(it_per_sec) + " iterations per second")

16000 script. , 16000. 2 , , 29600%. , count + = 1 . 100 ., 1000 , - , 14-16 . . 7-8 , , , ... , .

, ! , , . , Python .

+4

, Python, . Pypy - pypy 10 , Python .

, Python , . PIL Numpy - . , Python, , , , , Numpy . , Python , .

+2

Source: https://habr.com/ru/post/1537047/


All Articles