Python 3.x 为什么tensorflow解码jpeg图像与scipy imread不同?

Python 3.x 为什么tensorflow解码jpeg图像与scipy imread不同?,python-3.x,tensorflow,scipy,Python 3.x,Tensorflow,Scipy,对于jpg图像,Tensorflow的tf.image.decode\u jpeg()函数给出的数值结果与scipy.misc.imread()不同。虽然图像看起来相似,但像素值不同 import numpy as np import scipy import tensorflow as tf import matplotlib.pyplot as plt def minimal_example(): def _bytes_feature(value): return t

对于
jpg
图像,Tensorflow的
tf.image.decode\u jpeg()
函数给出的数值结果与
scipy.misc.imread()不同。虽然图像看起来相似,但像素值不同

import numpy as np
import scipy
import tensorflow as tf
import matplotlib.pyplot as plt
def minimal_example():
    def _bytes_feature(value):
        return tf.train.Feature(bytes_list=tf.train.BytesList(value=[value]))

    tffilename = 'astronaut.tfrecords'
    writer = tf.python_io.TFRecordWriter(tffilename)
    #image_source = 'https://upload.wikimedia.org/wikipedia/commons/8/88/Astronaut-EVA.jpg'
    image_path = 'astronaut.jpg'
    image_file = open(image_path,'rb')
    image = image_file.read()
    image_scipy = scipy.misc.imread(image_path)
    example = tf.train.Example(features=tf.train.Features(feature={'image':_bytes_feature(image)}))
    writer.write(example.SerializeToString())
    writer.close()

    record_iterator = tf.python_io.tf_record_iterator(path=tffilename)
    example = tf.train.Example()
    example.ParseFromString(next(record_iterator))
    image = example.features.feature['image'].bytes_list.value[0]
    image_tf = tf.image.decode_jpeg(image).eval(session=tf.Session())
    fig = plt.figure()
    ax1 = fig.add_subplot(121)
    ax2 = fig.add_subplot(122)
    ax1.imshow(image_scipy)
    ax2.imshow(image_tf)
    print('Reconstruction Error', np.sum(np.abs(image_tf - image_scipy)))
    plt.show()
结果:

Reconstruction Error 3420883624
这是一个bug还是我做错了什么?

。因此,不同的实现之间会有一些变化

但是,它仍然需要

每个像素组件的最大差值为1位

因此,两个输出之间的距离不应超过一个。对吧?

print('max diff: ', np.max(np.abs(image_tf.astype(float) - image_scipy.astype(float))))
# max diff:  17.0
哎哟,至少有一个实现不符合标准…

。因此,不同的实现之间会有一些变化

但是,它仍然需要

每个像素组件的最大差值为1位

因此,两个输出之间的距离不应超过一个。对吧?

print('max diff: ', np.max(np.abs(image_tf.astype(float) - image_scipy.astype(float))))
# max diff:  17.0

哎哟,至少有一个实现没有遵循标准…

这种差异是由于Tensorflow使用的不准确但快速的默认离散余弦变换而产生的

根据

//jpeg解码默认选择的TensorFlow是IFAST,牺牲了

//图像质量的速度

flags_u.dct_method=JDCT_IFAST

为了获得准确的解码,可以设置属性
dct\u method='INTEGER\u-accurate'
,如下例所示

def minimal_example():
    #image_source = 'https://upload.wikimedia.org/wikipedia/commons/8/88/Astronaut-EVA.jpg'
    image_path = 'astronaut.jpg'
    image_file = open(image_path,'rb')
    image_raw = image_file.read()
    image_scipy = scipy.misc.imread(image_path)
    image_tf = tf.image.decode_jpeg(image_raw).eval(session=tf.Session())
    image_tf_accurate = tf.image.decode_jpeg(image_raw,dct_method="INTEGER_ACCURATE").eval(session=tf.Session())
    print('Error For Default: ', np.sum(np.abs(image_tf - image_scipy)))
    print('Error For Accurate: ', np.sum(np.abs(image_tf_accurate - image_scipy)))
    #Error For Default:  3420883624
    #Error For Accurate:  0

这种差异是由于Tensorflow使用的不准确但快速的默认离散余弦变换而产生的

根据

//jpeg解码默认选择的TensorFlow是IFAST,牺牲了

//图像质量的速度

flags_u.dct_method=JDCT_IFAST

为了获得准确的解码,可以设置属性
dct\u method='INTEGER\u-accurate'
,如下例所示

def minimal_example():
    #image_source = 'https://upload.wikimedia.org/wikipedia/commons/8/88/Astronaut-EVA.jpg'
    image_path = 'astronaut.jpg'
    image_file = open(image_path,'rb')
    image_raw = image_file.read()
    image_scipy = scipy.misc.imread(image_path)
    image_tf = tf.image.decode_jpeg(image_raw).eval(session=tf.Session())
    image_tf_accurate = tf.image.decode_jpeg(image_raw,dct_method="INTEGER_ACCURATE").eval(session=tf.Session())
    print('Error For Default: ', np.sum(np.abs(image_tf - image_scipy)))
    print('Error For Accurate: ', np.sum(np.abs(image_tf_accurate - image_scipy)))
    #Error For Default:  3420883624
    #Error For Accurate:  0

我第一次听到这个。非常有趣!scipy似乎使用libjpeg-dev(通过PIL/Pillow),而tensorflow可能使用。非常有趣!scipy似乎使用libjpeg-dev(通过PIL/Pillow),而tensorflow可能使用。