在枕头和OpenCV中打开的图像并不相同

时间:2021-02-23 00:21:59

I downloaded a test image from Wikipedia (the tree seen below) to compare Pillow and OpenCV (using cv2) in python. Perceptually the two images appear the same, but their respective md5 hashes don't match; and if I subtract the two images the result is not even close to solid black (the image shown below the original). The original image is a JPEG. If I convert it to a PNG first, the hashes match.

我从Wikipedia(见下的树)下载了一个测试图像,以比较Pillow和OpenCV(使用cv2)在python中的使用。这两幅图像在感知上是相同的,但它们各自的md5散列不匹配;如果我减去这两幅图像,结果甚至都不接近纯黑色(原始图像如下)。原始图像是JPEG。如果我先把它转换成PNG,哈希匹配。

The last image shows the frequency distribution of how the pixel value differences.

最后一幅图像显示了像素值差异的频率分布。

As Catree pointed out my subtraction was causing integer overflow. I updated to converting too dtype=int before the subtraction (to show the negative values) and then taking the absolute value before plotting the difference. Now the difference image is perceptually solid black.

正如Catree指出的,我的减法导致了整数溢出。我更新为在减法之前将too dtype=int(显示负值)转换为在绘制差之前取绝对值。不同的图像感知上是固体黑色。

This is the code I used:

这是我使用的代码:

from PIL import Image
import cv2
import sys
import md5
import numpy as np

def hashIm(im):
    imP = np.array(Image.open(im))

    # Convert to BGR and drop alpha channel if it exists
    imP = imP[..., 2::-1]
    # Make the array contiguous again
    imP = np.array(imP)
    im = cv2.imread(im)

    diff = im.astype(int)-imP.astype(int)

    cv2.imshow('cv2', im)
    cv2.imshow('PIL', imP)
    cv2.imshow('diff', np.abs(diff).astype(np.uint8))
    cv2.imshow('diff_overflow', diff.astype(np.uint8))

    with open('dist.csv', 'w') as outfile:
        diff = im-imP
        for i in range(-256, 256):
            outfile.write('{},{}\n'.format(i, np.count_nonzero(diff==i)))

    cv2.waitKey(0)
    cv2.destroyAllWindows()

    return md5.md5(im).hexdigest() + '   ' + md5.md5(imP).hexdigest()

if __name__ == '__main__':
    print sys.argv[1] + '\t' + hashIm(sys.argv[1])

在枕头和OpenCV中打开的图像并不相同

Frequency distribution updated to show negative values.

频率分布更新显示负值。

在枕头和OpenCV中打开的图像并不相同


This is what I was seeing before I implemented the changes recommended by Catree.

这是我在实现Catree建议的更改之前看到的。

在枕头和OpenCV中打开的图像并不相同

在枕头和OpenCV中打开的图像并不相同

1 个解决方案

#1


2  

The original image is a JPEG.

原始图像是JPEG。

JPEG decoding can produce different results depending on the libjpeg version, compiler optimization, platform, etc.

根据libjpeg版本、编译器优化、平台等,JPEG解码可以产生不同的结果。

Check which version of libjpeg Pillow and OpenCV are using.

检查libjpeg枕头和OpenCV使用的是哪个版本。

See this answer for more information: JPEG images have different pixel values across multiple devices or here.

更多信息请参见此答案:JPEG图像在多个设备或此处具有不同的像素值。

BTW, (im-imP) produces uint8 overflow (there is no way to have such a high amount of large pixel differences without seeing it in your frequency chart). Try to cast to int type before doing your frequency computation.

顺便说一句,(im-imP)会产生uint8溢出(如果在你的频率图中看不到,那么就不可能有如此大的像素差异)。在进行频率计算之前,尝试转换为int类型。

#1


2  

The original image is a JPEG.

原始图像是JPEG。

JPEG decoding can produce different results depending on the libjpeg version, compiler optimization, platform, etc.

根据libjpeg版本、编译器优化、平台等,JPEG解码可以产生不同的结果。

Check which version of libjpeg Pillow and OpenCV are using.

检查libjpeg枕头和OpenCV使用的是哪个版本。

See this answer for more information: JPEG images have different pixel values across multiple devices or here.

更多信息请参见此答案:JPEG图像在多个设备或此处具有不同的像素值。

BTW, (im-imP) produces uint8 overflow (there is no way to have such a high amount of large pixel differences without seeing it in your frequency chart). Try to cast to int type before doing your frequency computation.

顺便说一句,(im-imP)会产生uint8溢出(如果在你的频率图中看不到,那么就不可能有如此大的像素差异)。在进行频率计算之前,尝试转换为int类型。