如何使用Python更快地处理图像?

时间:2015-04-11 17:43:21

标签: python image image-processing rgb

我试图编写一个脚本来检测屏幕上的RGB值,然后单击x,y值。我知道如何执行点击,但我需要比我目前的代码更快地处理图像。这可能与Python有关吗?

到目前为止,我一次读取一行,当x = 1920时,我进入第二行,但是需要大约10秒才能完成一行。到那个时候,屏幕上的人会搬进一个完全不同的地方,我只做了一行!

我可以加快这段代码的速度吗?或者有更好的方法来实现我想要的吗?如果在Python中不可能,我可以使用C ++选项:)

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

5 个答案:

答案 0 :(得分:3)

通常,您希望避免Python中的每像素循环。他们总是很慢。要获得更快的图像处理,您需要习惯使用矩阵而不是单个像素。您基本上有两个选项,您可以使用NumPy或OpenCV,也可以使用两者的组合。 NumPy是一个通用的数学矩阵/数组库,但您可以使用它做许多与图像相关的事情。如果您需要更具体的内容,OpenCV支持对图像进行许多常见操作。

答案 1 :(得分:0)

Image.getpixel被视为very slow。相反,请考虑使用Image.getdata。这将为您提供一个序列,其中包含您可以迭代的所有像素的数据。

这样的事情:

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

在我的MacBook Pro上没有打印(只是在变量中存储像素),用户时间为2秒(处理器时间为0.02秒)。

答案 2 :(得分:0)

感谢您的回复,下面是我使用的代码,我没有改变我原来的代码。事实证明它足够快但打印是一个非常昂贵的操作:)它在不到一秒的时间内找到RGB值的x和y坐标

#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 :(得分:0)

你可能想在这里做两件事之一。

1。从图像中获取单个像素

在这种情况下,您无需遍历整个文件。只需使用im.getpixel即可。 @Daniel提出了一个有效的观点,即循环速度很慢,但如果只想要一个像素,这非常有效。

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

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

2。处理图像中的多个像素

最好使用NumPy,因为@Lukáš建议。例如,如果你想做像像素那样的10 x 10网格的平均颜色。

您可以使用scipy.misc.fromimage

将数据作为NumPy数组获取
from PIL import Image
from scipy.misc import fromimage

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

让我们比较获取此数据与for循环所需的时间。

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

总结:

  • scipy.misc.fromimage是最快的,对于1920x1080图像来说是~8ms
  • 循环pix[x, y]需要约640毫秒,约 80倍

答案 4 :(得分:0)

有一种叫做pyautogui的东西,通常会在1-5秒内在屏幕上找到整个图像,虽然速度不太快,但似乎比您当前的选择要好