如何在TensorFlow中还原tf.image.per_image_standardization()归一化操作?
还原TensorFlow中Z-score归一化的图像
嘿,这个问题太实用了!毕竟用tf.image.per_image_standardization()做归一化后,直接显示图像肯定会是灰蒙蒙的一片,甚至颜色失真,得先把它还原回原始数值范围才能正常查看。
首先得搞懂这个函数的归一化逻辑:它对单张图像单独计算均值(mean)和调整后的标准差(adjusted_stddev),然后执行(图像 - mean) / adjusted_stddev得到零均值、单位方差的结果。其中adjusted_stddev是为了避免标准差为0时出现除以0的错误,计算方式是max(stddev, 1.0/sqrt(图像总像素数))。
要还原的话,我们只需要把这个过程逆过来就行——但关键是必须在归一化时保存每张图像对应的mean和adjusted_stddev,因为每张图的这两个值都是不一样的。
单张图像的还原步骤
下面是具体的TensorFlow实现代码:
import tensorflow as tf # 模拟一张原始图像(比如0-255的float32格式) original_image = tf.random.uniform(shape=(256, 256, 3), minval=0, maxval=255, dtype=tf.float32) # 先同步计算归一化所需的mean和adjusted_stddev image_mean = tf.reduce_mean(original_image) image_std = tf.math.reduce_std(original_image) adjusted_stddev = tf.maximum(image_std, 1.0 / tf.sqrt(tf.cast(tf.size(original_image), tf.float32))) # 执行归一化(和tf.image.per_image_standardization输出完全一致) standardized_image = (original_image - image_mean) / adjusted_stddev # 核心:还原图像 restored_image = standardized_image * adjusted_stddev + image_mean # 验证还原效果(误差应该极小,接近0) print("还原误差最大值:", tf.reduce_max(tf.abs(restored_image - original_image)).numpy())
批量图像的还原步骤
如果是处理批量图像,要注意tf.image.per_image_standardization()是逐图处理的,所以我们需要对批量里的每张图单独计算并保存mean和adjusted_stddev,再逐图还原:
# 模拟批量图像,shape=(batch_size, height, width, channels) batch_images = tf.random.uniform(shape=(4, 256, 256, 3), minval=0, maxval=255, dtype=tf.float32) # 定义单图处理函数,返回归一化图、mean、adjusted_stddev def process_single_image(img): img_mean = tf.reduce_mean(img) img_std = tf.math.reduce_std(img) adj_std = tf.maximum(img_std, 1.0 / tf.sqrt(tf.cast(tf.size(img), tf.float32))) standardized = (img - img_mean) / adj_std return standardized, img_mean, adj_std # 批量处理,得到归一化后的批量图,以及对应的mean和std数组 standardized_batch, batch_means, batch_adj_stds = tf.map_fn( process_single_image, batch_images, dtype=(tf.float32, tf.float32, tf.float32) ) # 定义单图还原函数 def restore_single_image(std_img, mean, adj_std): return std_img * adj_std + mean # 批量还原图像 restored_batch = tf.map_fn( lambda x: restore_single_image(x[0], x[1], x[2]), (standardized_batch, batch_means, batch_adj_stds), dtype=tf.float32 ) # 验证批量还原效果 print("批量还原误差最大值:", tf.reduce_max(tf.abs(restored_batch - batch_images)).numpy())
重要提醒
- 如果你在归一化时没有保存对应的mean和adjusted_stddev,那是无法还原的,因为每张图像的这两个参数都是唯一的。
- 还原后的图像数值范围会和原始图像一致,比如原始是0-255的float32,还原后也会回到这个范围,此时就可以正常用
matplotlib或其他工具显示了。
内容的提问来源于stack exchange,提问作者Ramraj Chandradevan
相关产品推荐
相关产品推荐

