I created a minimum working example of an image preprocessing step which is to be ported over from Caffe v.1 to tensorflow. I am able to reproduce the steps using PIL + skimage however, I am unable to do the same in tensorflow. As observed, the L2 norm between the transformed image in Caffe and tensorflow is high which is not the case for the PIL + skimage. How do we reproduce the steps the image underwent in Caffe or PIL methods using tensorflow?
import tensorflow as tf import numpy as np from PIL import Image import caffe from skimage.transform import resize import requests
image_url = 'https://tinyjpg.com/images/social/website.jpg'
TEST_IMAGE = 'test_image.jpg'
DATA_LAYER = 'data_p'
MEAN = np.array([131.26315308, 140.62084961, 142.71440125], dtype=np.float32)
img_data = requests.get(image_url).content
with open(TEST_IMAGE, 'wb') as handler:
handler.write(img_data)
def create_transformer():
transformer = caffe.io.Transformer({DATA_LAYER: (1, 3, 224, 224)})
transformer.set_transpose(DATA_LAYER, (2,0,1))
transformer.set_channel_swap(DATA_LAYER,(2,1,0))
transformer.set_mean(DATA_LAYER, MEAN)
transformer.set_raw_scale(DATA_LAYER, 255)
return transformer
def transform_image_original(test_image):
'''
Creates a caffe.io.Transformer
'''
t = create_transformer()
image_data = Image.fromarray(np.uint8(caffe.io.load_image(TEST_IMAGE) * 255))
input_image = np.array(image_data) / 255.0
transformed_image = t.preprocess(DATA_LAYER, input_image)
return transformed_image
def _resize(im, new_dims,interp_order=1):
im_min, im_max = im.min(), im.max()
if im_max > im_min:
im_std = (im - im_min) / (im_max - im_min)
resized_std = resize(im_std, new_dims, order=interp_order, mode='constant')
resized_im = resized_std * (im_max - im_min) + im_min
return resized_im
def preprocess_image(TEST_IMAGE, height=224, width=224):
'''
replicates the caffe tranformation using PIL and skimage.transform
'''
with open(TEST_IMAGE, 'rb') as f:
image = Image.open(f)
image = image.convert('RGB')
image = np.array(image, np.float32) / 255.0
image = _resize(image, (224, 224))
image = np.array(image, np.float32) * 255.0
import scipy.misc
scipy.misc.imsave('pil_file.jpg', image)
image = np.transpose(image, (2, 0, 1))
image = image[::-1, ...] # convert RGB to BGR
image = image - MEAN.reshape((3, 1, 1))
return image
def tf_preprocess_image(TEST_IMAGE, height=224, width=224):
'''
preprocessing an image in tensorflow
'''
image_string = tf.read_file(TEST_IMAGE)
image = tf.image.decode_jpeg(image_string, channels=3, dct_method='INTEGER_ACCURATE',
fancy_upscaling=False, acceptable_fraction=1, try_recover_truncated=True)
image = tf.to_float(image) / 255
image = tf.div(
tf.subtract(
image,
tf.reduce_min(image)
),
tf.subtract(
tf.reduce_max(image),
tf.reduce_min(image)
)
)
if height and width:
# Resize the image to the specified height and width.
image = tf.expand_dims(image, 0)
image = tf.image.resize_bilinear(image, [height, width],
align_corners=False)
image = tf.squeeze(image, [0])
image = tf.add(
tf.multiply(
image,
tf.subtract(
tf.reduce_max(image),
tf.reduce_min(image)
)
),
tf.reduce_min(image)
)
image = tf.to_float(image) * 255
# RGB to BGR using strided slice
image = image[..., ::-1]
# Channel last to channel first
image = tf.transpose(image, [2, 0, 1])
# Mean subtraction
image = tf.subtract(image, MEAN.reshape(3,1,1))
return image
print('Preprocessing test image using Caffe...')
image = transform_image_original(TEST_IMAGE)
print('Preprocessing test image using PIL + skimage.transform ...')
image2 = preprocess_image(TEST_IMAGE)
print('Preprocessing test image using tensorflow')
with tf.Session() as sess:
tf_image3 = tf_preprocess_image(TEST_IMAGE)
image3 = tf_image3.eval()
print('L2 norm between caffe transformation and PIL + skimage', np.linalg.norm(image - image2)) # L2 norm
print('L2 norm between caffe transformation and tf', np.linalg.norm(image2 - image3))