从截图中处理图像 - Python

1 投票
1 回答
1167 浏览
提问于 2025-04-17 10:19

我想给一个游戏《宝石迷阵》截个图,这个游戏是一个8x8的棋盘,然后从截图中提取出棋盘的位置。我试过用Image/Imagestat、autopy,还有从每个格子的中间抓取单个像素,但都没成功。所以我在想,能不能通过计算每个8x8格子的平均值来识别每个棋子,但我用Image/Imagestat和autopy都没办法做到。

有没有人知道怎么获取图像某个区域的像素或颜色值?或者有没有更好的方法来识别图像中主色调的部分?

1 个回答

1

我找到了一种方法,可以用PIL库里的Imagegrab和ImageStat来实现这个功能。下面是如何抓取屏幕并裁剪到游戏窗口的代码:

def getScreen():
    # Grab image and crop it to the desired window. Find pixel borders manually.
    box = (left, top, right, bottom)        
    im = ImageGrab.grab().crop(box)
    #im.save('testcrop.jpg')  # optionally save your crop

    for y in reversed(range(8)):
        for x in reversed(range(8)):
            #sqh,sqw are the height and width of each piece.
            #each pieceim is one of the game piece squares
            piecebox = ( sqw*(x), sqh*(y), sqw*(x+1), sqh*(y+1))
            pieceim = im.crop(piecebox)
            #pieceim.save('piececrop_xy_'+ str(x) + str(y) + '.jpg')

            stats = ImageStat.Stat(pieceim)
            statsmean = stats.mean
            Rows[x][y] = whichpiece(statsmean)

这段代码会为所有64个棋子创建一张图片,识别每种棋子的类型,并把这些信息存储在一个叫'Rows'的数组里。接着,我用stats.mean计算每种棋子的平均RGB值,并把这些值存到一个字典(rgbdict)里。然后把所有的输出复制到Excel中,根据颜色类型进行筛选,以得到这些平均值。之后,我使用了一种RSS方法和这个字典,把图片与已知的棋子类型进行统计匹配。(RSS的参考链接:http://www.charlesrcook.com/archive/2010/09/05/creating-a-bejeweled-blitz-bot-in-c.aspx

rgbdict = {
           'blue':[65.48478993, 149.0030965, 179.4636593],  #1
           'red':[105.3613444,55.95710092, 36.07481793],   #2
           ......
            }
 def whichpiece(statsmean):
        bestScore = 100
        curScore= 0
        pieceColor = 'empty'
        for key in rgbdict.keys():
            curScore = (math.pow( (statsmean[0]/255) - (rgbdict[key][0]/255), 2)
                +  math.pow( (statsmean[1]/255) - (rgbdict[key][1]/255), 2)
                +  math.pow( (statsmean[2]/255) - (rgbdict[key][2]/255), 2) )
            if curScore < bestScore:
                pieceColor = key
                bestScore = curScore  
        return piececolor

通过这两个函数,可以抓取屏幕,并把棋盘的状态转移到一个数组中,这样就可以根据这个数组来决定下一步的动作。如果这对任何人有帮助,祝你好运!如果你优化了选择动作的功能,记得告诉我哦。

撰写回答