How can I process images faster with Python?

女生的网名这么多〃 提交于 2020-12-01 10:40:46

问题


I'd trying to write a script that will detect an RGB value on the screen then click the x,y values. I know how to perform the click but I need to process the image a lot faster than my code below currently does. Is this possible with Python?

So far I'm reading a row at a time, when x = 1920 I go onto the second row but it takes about 10 seconds to do one row. By that time the person on screen would have moved into a completely different spot and I have only done one row!

Can I speed this code up OR is there a better way to achieve what I want? If it is not possible in Python I am open to C++ options :)

import Image

x = 0
y = 0

im = Image.open("C:\Users\sean\Desktop\screen.jpg")
pix = im.load()
print im.size #get width and height of the image for iterating over
while x < 1920:
    print pix[x,y] #get RGBA value of the pixel of an image
    print "x is:" +str(x)
    x = x + 1
    print "y is: " +str(y)
    if x == 1920:
        x = 0
        y = y + 1

回答1:


Generally, you want to avoid per-pixel loops in Python. They will always be slow. To get somewhat fast image processing, you need to get used to working with matrices instead of individual pixels. You have basically two options, you can either use NumPy or OpenCV, or a combination of the two. NumPy is a generic mathemtical matrix/array library, but you can do many image-related things with it. If you need something more specific, OpenCV supports many common operations on images.




回答2:


Thanks for the responses, below is the code I used, I didn't change my original. Turns out it is fast enough but printing is a very costly operation :) It finds the x and y coords of the RGB value in less than a second

#check for certain RGB in image

##need to screen grab

import Image, sys

x = 0
y = 0

im = Image.open('C:\\Users\\sean\\Desktop\\test.jpg')
pix = im.load()
print im.size #get width and height of the image for iterating over
while x < 1914:
    value = pix[x,y] #get RGBA value of the pixel of an image
    if value == (33, 179, 80):
        #call left_click(x,y)
        print x,y
    x = x + 1
    if x == 1914:
        x = 0
        y = y + 1
print "Finished"
sys.exit()



回答3:


Image.getpixel is considered very slow. Instead, consider using Image.getdata. That will give you a sequence with data for all the pixels through which you can iterate.

Something like this:

import Image
import math

x = 0
y = 0

im = Image.open("IMG_2977.JPG")
(width, height) = im.size
print width
print height

pix = im.getdata()

i = 0

for pixel in pix:
    print pixel
    x = i % ( width )
    y = math.trunc( i / width)
    print "x is: {}".format(x)
    print "y is: {}".format(y)
    i += 1

Without printing (just storing pixel in a variable) that runs in 2 seconds of user time (0.02 seconds of processor time) on my MacBook Pro.




回答4:


You may want to do one of two things here.

1. Get a single pixel from the image

In this case, you don't need to iterate through the entire file. Just use im.getpixel. @Daniel makes a valid point that this is slow in a loop, but if you just want a single pixel, this is very efficient.

from PIL import Image
im = Image.open('screenshot.png')

im.getpixel((x, y))    # Returns the colour at (x, y)

2. Process multiple pixels from the image

This is best done using NumPy as @Lukáš suggests. If you want to do something like get the average colour of the 10 x 10 grid around the pixel, for example.

You can get the data as a NumPy array using scipy.misc.fromimage

from PIL import Image
from scipy.misc import fromimage

im = Image.open('screenshot.png')
data = fromimage(img)

Let's compare the time it takes to get this data against a for loop.

In [32]: pix = im.load()

In [33]: %timeit fromimage(im)
10 loops, best of 3: 8.24 ms per loops

In [34]: %timeit [pix[x, y] for x in xrange(im.size[0]) for y in xrange(im.size[1])]
1 loops, best of 3: 637 ms per loop

To summarise:

  • scipy.misc.fromimage is the fastest, at ~8ms for a 1920x1080 image
  • Looping through pix[x, y] takes ~640ms, about 80 times slower



回答5:


There is something called pyautogui and it will find the entire image on the screen within 1-5 seconds usually, which is not too fast but seems better than you current option



来源:https://stackoverflow.com/questions/29581014/how-can-i-process-images-faster-with-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!