如何检查两个图像是否相同?

2024-04-24 01:21:24 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用ImageChops检查两个图像是否不同,方法是:

currentPic = Image.open('current.png').convert('RGB')
previousPic = Image.open('previous.png').convert('RGB')
diff = ImageChops.difference(currentPic, previousPic)
if diffUserHome.getbbox():
   print("Images are different herey !!")

我试图修改此代码以检查这两个图像是否相同。 你知道我用ImageChops库检查两张图片是否完全相同的方法吗


Tags: 方法图像imageconvertifpngdiffrgb
3条回答

我不会在这里使用ImageChops.difference,因为它不能处理不同的图像modes,cf

from PIL import Image, ImageChops

# Read images
img1 = Image.open('image.png').convert('L')
img2 = Image.open('image.png').convert('L').convert('F')

diff = ImageChops.difference(img1, img2)

尽管两幅图像完全相同(w.r.t.像素的强度),但我们得到以下结果ValueError

Traceback (most recent call last):
  File "...", line 7, in <module>
    diff = ImageChops.difference(img1, img2)
  File "...\lib\site-packages\PIL\ImageChops.py", line 102, in difference
    return image1._new(image1.im.chop_difference(image2.im))
ValueError: images do not match

总的来说,我同意使用NumPy的矢量化功能来加快计算速度,但也可能有一种非常简单的方法:

  1. 检查带数。如果它们不匹配,则图像必须不同
  2. 手动计算每个像素的绝对强度差(即ImageChops.difference实际的作用),但确保支持任何两种图像模式。这与单通道图像和多通道图像略有不同
  3. 如前所述,对所有像素的差异求和。如果该总和大于0,则图像必须不同

这就是我的代码:

from PIL import Image

# Read images
img1 = Image.open('path/to/your/image.png').convert('RGB')
img2 = Image.open('path/to/your/image.png').convert('RGB')

# Check for different number of channels
if img1.im.bands != img2.im.bands:
    print('Images are different; number of channels do not match.')
    exit(-1)

# Get image (pixel) data
imdata1 = list(img1.getdata())
imdata2 = list(img2.getdata())

# Calculate pixel-wise absolute differences, and sum those differences
diff = 0
if img1.im.bands == 1:
    diff = sum([abs(float(i1) - float(i2)) for i1, i2 in zip(imdata1, imdata2)])
else:
    diff = sum([abs(float(i1) - float(i2)) for i1, i2 in
                zip([i for p in imdata1 for i in p],
                    [i for p in imdata2 for i in p])])
if diff > 0:
    print('Images are different; pixel-wise difference > 0.')
    exit(-1)

print('Images are the same.')

对于某些图像,代码原样将返回:

Images are the same.

另外,对于开头提到的情况,我们将得到这个输出。然而,对于一些输入,例如

img1 = Image.open('image.png').convert('L')
img2 = Image.open('image.png').convert('F')

最有可能的结果是:

Images are different; pixel-wise difference > 0.

直接转换为模式F将导致单个强度值的某些分数部分,因此,与普通转换为模式L不同

如果您有代码失败的用例,请让我知道。我很好奇,我是否错过了一些边缘案例

                    
System information
                    
Platform:      Windows-10-10.0.16299-SP0
Python:        3.9.1
PyCharm:       2021.1.1
Pillow:        8.2.0
                    

函数的作用是:将两幅图像逐像素相减,从而为您创建一幅新图像。如果生成的图像完全为黑色,则提取的图像完全相同。这是因为黑色的rgb值为{0,0,0}。函数的作用是:计算图像中非零区域的边界框。如果该函数找不到非零点,则返回0。使用这些函数,可以生成如下简单函数

from PIL import Image, ImageChops

def isDiffirent(current,previous):
    diff = ImageChops.difference(current,previous)
    if diff.getbbox():
        return 1
    else:
        return 0

可以使用^{}获取差分图像的所有像素值。将这些值转换为一个NumPy数组可以很容易地对所有像素值求和。当且仅当原始两幅图像之间的所有像素值相同时,该和为零,因为像素值不能为负

from PIL import Image, ImageChops
import numpy as np

def are_same_image(image1, image2):
    if np.sum(np.array(ImageChops.difference(image1, image2).getdata())) == 0:
        return True
    return False

相关问题 更多 >