Bupathi Sangeeth
Bupathi Sangeeth

Reputation: 425

How to replicate tensorflow image processing using opencv python

Hi i need to use python cv2 to do exactly the same preprocessing done by tensorflow in the below code snippet. Please help!

file_name = 'image path'
input_name = 'file_reader'
input_height=299
input_width=299
input_mean=0
input_std=255

file_reader = tf.read_file(file_name, input_name)
image_reader = tf.image.decode_jpeg(file_reader, channels = 3,
                                    name='jpeg_reader')
float_caster = tf.cast(image_reader, tf.float32)
dims_expander = tf.expand_dims(float_caster, 0);
resized = tf.image.resize_bilinear(dims_expander, [input_height, input_width])
normalized = tf.divide(tf.subtract(resized, [input_mean]), [input_std])
sess = tf.Session()
result = sess.run(normalized)

Upvotes: 0

Views: 1864

Answers (2)

Yura Vasiliuk
Yura Vasiliuk

Reputation: 101

tf.image.resize_bilinear is a buggy function. so, you won't get exactly same values after resizing same image in TF and CV2.

Quick example:

img_original = np.random.randint(0, 255, (4,4,3)).astype(np.uint8)
img_rescaled = cv2.resize(img_original, (3,3), cv2.INTER_LINEAR)
print(img_original)

array([[[144,   9, 253],
    [  5,  87,   5],
    [ 21, 125, 117],
    [109, 159, 142]],

   [[ 64, 124, 196],
    [ 43, 230,  80],
    [ 42, 166,  36],
    [158, 121,  11]],

   [[238, 234,  57],
    [ 86, 254, 239],
    [149, 133, 161],
    [ 96, 245,  99]],

   [[128,   7, 134],
    [169,  69,  70],
    [246,  31,  95],
    [143,   1,  58]]], dtype=uint8)

Check how array has been transformed via CV2:

print(img_rescaled)

array([[[111,  42, 206],
    [ 18, 121,  60],
    [102, 149, 117]],

   [[137, 189, 132],
    [ 80, 196, 129],
    [122, 177,  62]],

   [[148,  54, 117],
    [192,  74, 102],
    [151,  42,  71]]], dtype=uint8)

Now, lets define TF session and see what's happens under the hood:

x = tf.placeholder(tf.uint8, shape=(None,4,4,3), name='x')
resize_op_TF = tf.image.resize_bilinear(x, (3,3), name='resize_op')
session = tf.InteractiveSession()
img_resized_TF = session.run(resize_op_TF, {x: [img_original]})[0]
print(img_resized_TF)

array([[[144.      ,   9.      , 253.      ],
    [ 10.333334,  99.66667 ,  42.333336],
    [ 79.66667 , 147.66667 , 133.66667 ]],

   [[122.00001 , 160.66667 , 149.66666 ],
    [ 64.111115, 210.33333 , 114.55556 ],
    [117.44445 , 159.88889 ,  52.77778 ]],

   [[164.66666 ,  82.66664 , 108.33334 ],
    [165.44446 , 108.777756, 123.22222 ],
    [156.11111 ,  76.55554 ,  86.77777 ]]], dtype=float32)

As you can see the values in array re-scaled with TF and values in array re-scaled with CV2 differ drastically. It is common issue in Tensorflow, and developers still didn't fix it because of bunch of reasons.

Upvotes: 0

zindarod
zindarod

Reputation: 6468

I am going to write OpenCV code for your tensorflow code line by line:

file_name = 'image path'
input_name = 'file_reader'
input_height=299
input_width=299
input_mean=0
input_std=255

#file_reader = tf.read_file(file_name, input_name)
#image_reader = tf.image.decode_jpeg(file_reader, channels = 3,name='jpeg_reader')                              
image = cv2.imread(file_name, -1)


#float_caster = tf.cast(image_reader, tf.float32)
float_caster = image.astype(numpy.float32, copy=False)


#dims_expander = tf.expand_dims(float_caster, 0);
#This line just adds another dimension to the image, which is not needed for OpenCV but if you want:
#dims_expander = numpy.expand_dims(float_caster, axis=0)


#resized = tf.image.resize_bilinear(dims_expander, [input_height, input_width])
resized = cv2.resize(float_caster, (input_height,input_width),interpolation=cv2.INTER_LINEAR)

#normalized = tf.divide(tf.subtract(resized, [input_mean]), [input_std])
normalized = resized - input_mean
normalized /= input_std

Remember that OpenCV reads images as BGR and tensorflow reads images as RGB. So if you want to visually compare results, you need to convert one to the order of the other.

Upvotes: 1

Related Questions