如何比较pscreenshot中截取的屏幕截图和保存的屏幕截图?

问题描述:

我已经使用pyscreenshot在python中创建了一个程序,它周期性地截取了一个屏幕的特定区域,它将包含几个预定义的图像之一。我正在寻找从文件加载每个这些图像到列表中,并将它们与屏幕截图进行比较,以查看当前显示哪些图像。最初文件由screenshotting影像创建,因为他们在屏幕上:如何比较pscreenshot中截取的屏幕截图和保存的屏幕截图?

while True: 

filenm = str(i) + ".png" 
im=ImageGrab.grab(bbox=(680,640,735,690)) #accross, down 
im.save(filenm) 
time.sleep(1) 
i = i + 1 

然后,当我试图对它们进行比较总是报告错误:

image2 = Image.open("04.png") 

im=ImageGrab.grab(bbox=(680,640,735,690)) #accross, down 

if im == image2: 
    print "TRUE" 
else: 
    print "FALSE" 

但是比较两个保存到文件中的图像工作原理:

image = Image.open("03.png") 
image2 = Image.open("04.png") 

if image == image2: 
    print "TRUE" 
else: 
    print "FALSE" 

所以我的问题是如何做的影像会有所不同,一旦从文件加载,我怎么能比较“活”的截图从文件加载图像?

它看起来像当我使用ImageGrab.grab(),一个PIL.Image.Image对象被创建,其中Image.open()创建一个PIL.pngImagePlugin.PngImageFile对象。您不希望在实际对象上调用==,因为在比较这两种对象类型时,没有为PIL图像实现特殊语义,因此它只是检查它们是否是内存中的相同对象。代码我会用正确的(使用numpy的)的比较两个图像看起来像

import numpy as np 
from PIL import Image 

def image_compare(image_1, image_2): 
    arr1 = np.array(image_1) 
    arr2 = np.array(image_2) 
    if arr1.shape != arr2.shape: 
     return False 
    maxdiff = np.max(np.abs(arr1 - arr2)) 
    return maxdiff == 0 

def image_compare_file(filename_1, filename_2): 
    im1 = Image.load(filename_1) 
    im2 = Image.load(filename_2) 
    return image_compare(im1, im2) 

下面我就PIL图像的优势,自动铸造用np.array()到NumPy的ndarrays。然后检查尺寸是否匹配,并计算绝对误差的最大值。如果此最大值为零,则图像是相同的。现在,你可以只调用

if image_compare_file('file1.png','file2.png'): 
    pass # images in file are identical 
else: 
    pass # images differ 

if image_compare(image1,image2): 
    pass # images are identical 
else: 
    pass # images differ 
+0

这看起来接近我所需要的,但请记住,我不想加载两个文件进行比较,因为这需要每秒保存一个屏幕截图并一遍又一遍地加载相同的比较文件。我需要使用PIL.Image.Image和PIL.pngImagePlugin.PngImageFile。 –

您可能会感兴趣的使用感知差异工具可以让你快速识别截图差异。 imgdiff是一个为Python封装工具的库。一个简单的版本,大概可以用PIL的ImageChop实现,如在this answer

import Image 
import ImageChops 

im1 = Image.open("splash.png") 
im2 = Image.open("splash2.png") 

diff = ImageChops.difference(im2, im1) 

更多关于感性的版本比较,看看Bret Slatkin's talk about using it for safe continuous deployment

+0

听起来不错,但我怎么知道这个答案呢?差异似乎包含另一个图像。 –

+1

@GarethFrance它是一个图像,但更有用的是将其视为包含像素差异的二维数组。如果需要对Image对象进行一些计算,可以将Image对象转换为numpy ndarray。例如,如果'diff'中所有元素的总和为0,那么您知道这两个图像是完美匹配的像素。 – ahota