Pixel values difference between Tensorflow and skimage

Viewed 138

Why is there a difference between the pixel values if I open an image with skimage.io.imread(image) and tf.image.decode_image(image)?

For example:

import skimage.io
original_img = skimage.io.imread("test.jpg")
print(original_img.shape)
print(np.amax(original_img))
print(original_img)

The output is:

(110, 150, 3)
255
array([[[ 29,  65, 117],
        [ 45,  43,  90],
        [ 78,  39,  68],
        ...,
        [ 30,  46,  95],
        [ 30,  43,  96],
        [ 31,  44,  97]],

       [[ 41,  54,  89],
        [ 95,  89, 123],
        [ 57,  39,  65],
        ...,
        [ 32,  46,  91],
        [ 32,  46,  95],
        [ 32,  45,  97]],

       [[ 62,  49,  69],
        [ 84,  76,  97],
        [ 68,  70,  95],
        ...,
        [ 18,  30,  70],
        [ 35,  47,  95],
        [ 34,  47,  99]],

       ...,

       [[136, 124,  22],
        [144, 136,  53],
        [134, 123,  44],
        ...,
        [ 16,  74,  16],
        [ 39,  89,  52],
        [ 53, 108,  69]],

       [[161, 125,   5],
        [149, 129,  42],
        [129, 116,  48],
        ...,
        [ 67, 119,  73],
        [ 39,  80,  48],
        [ 33,  69,  41]],

       [[196, 127,   6],
        [160, 111,  32],
        [141, 108,  55],
        ...,
        [ 26,  56,  32],
        [  8,  29,  10],
        [ 12,  24,  12]]], dtype=uint8)

And if I open the same image with Tensorflow:

import tensorflow as tf

original_img = tf.image.decode_image(tf.io.read_file("test.jpg"))
print(np.amax(original_img))
print(original_img)

The output is:

255
<tf.Tensor: shape=(110, 150, 3), dtype=uint8, numpy=
array([[[ 44,  57, 101],
        [ 40,  42,  80],
        [ 65,  41,  65],
        ...,
        [ 25,  42,  88],
        [ 33,  49, 100],
        [ 25,  41,  92]],

       [[ 47,  53,  89],
        [ 96,  95, 127],
        [ 60,  44,  70],
        ...,
        [ 29,  43,  88],
        [ 40,  54, 103],
        [ 19,  35,  84]],

       [[ 59,  54,  74],
        [ 72,  69,  90],
        [ 70,  70,  96],
        ...,
        [ 23,  35,  77],
        [ 16,  29,  74],
        [ 50,  64, 111]],

       ...,

       [[145, 116,  24],
        [161, 131,  43],
        [141, 113,  30],
        ...,
        [ 19,  67,  19],
        [ 49,  95,  58],
        [ 53,  97,  64]],

       [[164, 119,  16],
        [166, 123,  28],
        [143, 108,  27],
        ...,
        [ 73, 119,  80],
        [ 29,  68,  37],
        [ 39,  75,  47]],

       [[182, 128,  20],
        [160, 112,  14],
        [149, 112,  32],
        ...,
        [ 11,  57,  21],
        [  7,  44,  13],
        [  0,  14,   0]]], dtype=uint8)>

I have also noticed that if I open an image with tensorflow, make some changes in this image, save the image on the disk and open it again with tf.image.decode_image(image) the pixel values are again different, but this time, not so much.

1 Answers

This is due to the algorithm used for decompression. By default, the system-specific method is used. tf.image.decode_image() does not provide any possibility to change the method.

In tf.image.decode_jpeg() there is the dct_method argument which can be used to change the method for decompression. Currently there are two valid values that can be set: INTEGER_FAST and INTEGER_ACCURATE.

If you open the image in the following way you should have the same output as with skimage.io.imread(image):

original_img = tf.image.decode_jpeg(tf.io.read_file("test.jpg"),dct_method="INTEGER_ACCURATE")
Related