在Pillow和OpenCV中打开的图像不匹配 [英] Images opened in Pillow and OpenCV are not equivelant

查看:152
本文介绍了在Pillow和OpenCV中打开的图像不匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从Wikipedia(如下所示的树)下载了测试图像,以比较python中的PillowOpenCV(使用cv2).从视觉上看,两个图像看起来相同,但是它们各自的md5哈希值不匹配;如果我减去这两个图像,结果甚至不会接近纯黑(图像显示在原始图像下方).原始图像是JPEG.如果我先将其转换为PNG,则哈希匹配.

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.

最后一张图片显示了像素值差异的频率分布.

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

正如Catree指出的那样,我的减法导致整数溢出.我更新为在减法之前也要转换dtype=int(以显示负值),然后在绘制差值之前先取绝对值.现在,差异图像在感知上是纯黑色.

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.

这是我使用的代码:

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])



频率分布已更新为显示负值.

Frequency distribution updated to show negative values.

这是我实施Catree建议的更改之前所看到的.

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

推荐答案

原始图像是JPEG.

The original image is a JPEG.

JPEG解码可能会产生不同的结果,具体取决于libjpeg版本,编译器优化和平台等.

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

检查正在使用哪个版本的libjpeg PillowOpenCV.

Check which version of libjpeg Pillow and OpenCV are using.

有关更多信息,请参见以下答案: JPEG图像在多个设备上具有不同的像素值

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

顺便说一句,(im-imP)会产生uint8溢出(如果没有在频率图).进行频率计算之前,请尝试转换为int类型.

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.

这篇关于在Pillow和OpenCV中打开的图像不匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆