从ImageGrab

时间:2019-02-17 12:29:24

标签: python python-3.x python-imaging-library

我当前正在创建PianoTiles AI,该AI必须定位ImageGrab中的所有黑色像素。我已经掌握了Image Grab的所有位置,但是我需要找出那里是否有黑色像素,如果有,则在哪里,以便我的AI可以单击它们。在下面,我已经摘录了我的代码。

我已经在网上浏览了一下,但是找不到任何东西。我认为代码是这样的。

from PIL import ImageGrab, ImageOps    

class Coordinates:    
    lines = [    
    (520, 300, 525, 760),    
    (630, 300, 635, 760),    
    (740, 300, 745, 760),    
    (850, 300, 855, 760)]    
    restartcheck = (660, 590, 725, 645)    
    restartbtn = (695, 615)    


blackpixelpositions = []    

def findtiles():    
    for line in Coordinates.lines:  
        i = ImageGrab.grab(line)  
        for pixel in i.getdata():  
            #if pixel is black  
            # x, y = pixel position  
             blackpixelpositions.append((x,y))  

我需要的是上面的代码才能工作,并给我黑色的像素位置。

2 个答案:

答案 0 :(得分:1)

i.getdata()存在一个问题,它使数据变平,即,您松开了像素坐标(除非您手动跟踪)。 因此您只会知道存在黑色像素,而在不存在黑色像素的地方。 您可以改用getpixel:

def get_black_pixels(image):
    found = []
    width, height = image.size
    for y in range(height):
        for x in range(width):
            if all(map(lambda x: x < 20, image.getpixel((x,y)))):
                found.append((x,y))
    return found

该行:

all(map(lambda x: x < 20, image.getpixel((x,y))))

只检查所有值(r,g,b)都小于20,您可以将其更改为其他一些阈值。

答案 1 :(得分:1)

您应该避免循环播放图像,并使用诸如getpixel()之类的功能来访问每个像素,因为它非常慢-特别是对于大型图像,如果您正在使用现代4-5k屏幕。

通常最好将PIL图像转换为Numpy数组,然后使用矢量化的Numpy例程来处理图像。因此,具体来说,假设您通过抓屏或打开文件来获取PIL图像:

im = Image.open('someFile.png')

然后您可以像这样从图像制作一个Numpy数组:

n = np.array(im)

并搜索像这样的黑色像素:

blacks = np.where((n[:, :, 0:3] == [0,0,0]).all(2)))

这将为您提供黑色像素的x坐标数组和y坐标的数组,例如您可以这样做:

xcoords, ycoords = np.where((n[:, :, 0:3] == [0,0,0]).all(2))