Tensorflow / Keras均值图像减法

时间:2019-02-01 09:08:03

标签: python tensorflow keras deep-learning

在生成训练数据期间,将计算平均图像(不是每个通道的平均像素值)

为了改善学习过程,我想将一种简化的方法应用于零中心并标准化我的网络输入数据,该数据主要由RGB图像组成:

image = (image - meanImage + 1.0) / 2.0

作为DL Framework,我正在使用Keras-加载训练数据tfrecords文件,如描述的here

在加载管道的某个时刻,我具有输入(X)和输出(Y)张量:

def datasetLoader(dataSetPath, batchSize):
   dataset = tf.data.TFRecordDataset(dataSetPath)

   dataset = dataset.map(_ds_parser, num_parallel_calls=8)

   # This dataset will go on forever
   dataset = dataset.repeat()

   # Set the batchsize
   dataset = dataset.batch(batchSize)

   # Create an iterator
   iterator = dataset.make_one_shot_iterator()

   # Create your tf representation of the iterator
   X, Y = iterator.get_next()  

   # Bring the date back in shape
   X = tf.reshape(I, [-1, 66, 198, 3])
   Y = tf.reshape(Y,[-1,1])

   return X, Y

变量X和Y只是张量,稍后在张量流会话期间填充。

问题是:我如何使用本地png均值图像执行零中心和归一化任务?

2 个答案:

答案 0 :(得分:3)

张量减法

要从一批图像数据中减去平均图像,只需使用减号运算符(这只是tf.subtract的语法糖):

In [28]: x = tf.zeros((2, 3, 3))

In [29]: x
Out[29]: 
<tf.Tensor: id=38, shape=(2, 3, 3), dtype=float32, numpy=
array([[[0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.]],

       [[0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.]]], dtype=float32)>

In [30]: mean = tf.eye(3)

In [31]: mean
Out[31]: 
<tf.Tensor: id=42, shape=(3, 3), dtype=float32, numpy=
array([[1., 0., 0.],
       [0., 1., 0.],
       [0., 0., 1.]], dtype=float32)>

In [32]: x - mean
Out[32]: 
<tf.Tensor: id=44, shape=(2, 3, 3), dtype=float32, numpy=
array([[[-1.,  0.,  0.],
        [ 0., -1.,  0.],
        [ 0.,  0., -1.]],

       [[-1.,  0.,  0.],
        [ 0., -1.,  0.],
        [ 0.,  0., -1.]]], dtype=float32)>

将图像读取到张量

要将您的PNG图像用作TensorFlow张量,只需用tf.constant包装一个numpy数组:

import cv2

mean_img = cv2.imread('/path/to/the/image')
mean_img_tensor = tf.constant(mean_img)

请注意,OpenCV默认会将图像读取到BGR颜色空间中。您可能需要将其转换为RGB,然后:

mean_img = cv2.cvtColor(mean_img, cv2.COLOR_BGR2RGB))

或使用Python图片库:

from PIL import Image
import numpy as np
mean_img = Image.open('/path/to/image')
mean_img_tensor = tf.constant(np.array(mean_img))

将它们放在一起

由于您使用的是TF Dataset API,因此我相信map_and_batch必须是更好的性能解决方案:

def datasetLoader(dataSetPath, batchSize, mean_image_path):
   dataset = tf.data.TFRecordDataset(dataSetPath)
   mean_img = cv2.cvtColor(cv2.imread(mean_image_path), cv2.COLOR_BGR2RGB)
   mean = tf.constant(mean_img)

   dataset = dataset.map(_ds_parser, num_parallel_calls=8)

   # This dataset will go on forever
   dataset = dataset.repeat()

   def preprocess(X, Y):
        # Bring the date back in shape
        X = tf.reshape(X, [-1, 66, 198, 3])
        Y = tf.reshape(Y,[-1,1])
        X = X - mean
        return X, Y

   # Set the batchsize
   dataset = dataset.apply(tf.contrib.data.map_and_batch(map_func=preprocess, batch_size=batchSize, num_parallel_calls=8))

   return dataset.make_one_shot_iterator().get_next()

答案 1 :(得分:0)

import cv2
import numpy as np

img = img.astype(np.float32)
img -= img.mean()
img /= img.std()