TensorFlow图像缩放后Matplotlib逆显示的两种有效方式原理疑惑
图像逆缩放原理解析:两种显示方式的等价性
核心前提:plt.imshow的输入要求
plt.imshow支持两种合法输入:
- 整数数组:取值范围
[0, 255](对应8位图像的标准像素值) - 浮点数数组:取值范围
[0, 1](会自动映射到[0, 255]的像素范围显示)
两种逆缩放方式本质都是把预处理后的数值区间,映射到plt.imshow能识别的合法范围,下面分两种预处理场景拆解:
场景1:预处理到[-1, 1]区间
预处理代码:
image = (tf.cast(image, tf.float32) / 127.5) - 1
这个操作是对原始[0, 255]的uint8像素值做线性变换:
- 原始像素为0时:
(0 / 127.5) - 1 = -1 - 原始像素为255时:
(255 / 127.5) - 1 = 2 - 1 = 1
最终得到[-1, 1]区间的浮点数。
两种逆变换的等价性
转
[0,255]整数的方式:((example[0] + 1) * 127.5).numpy().astype('uint8')推导:假设
x是[-1,1]区间的数值,x+1会把区间拉到[0,2],乘以127.5后得到[0,255],转成uint8后完全符合plt.imshow的整数输入要求。转
[0,1]浮点数的方式:example[0] * 0.5 + 0.5推导:
x是[-1,1]区间的数值,x*0.5把区间压缩到[-0.5,0.5],再加0.5后直接映射到[0,1],刚好符合plt.imshow的浮点数输入要求,无需转uint8就能正常显示。
场景2:预处理到[-0.5, 0.5]区间
预处理代码:
image = (tf.cast(image, tf.float32) / 255) - 0.5
原始[0,255]的像素值变换后:
- 原始像素为0时:
(0 / 255) - 0.5 = -0.5 - 原始像素为255时:
(255 / 255) - 0.5 = 1 - 0.5 = 0.5
最终得到[-0.5, 0.5]区间的浮点数。
逆变换example[0] + 0.5的原理:
把[-0.5,0.5]的每个值加0.5,直接将区间平移到[0,1],完全符合plt.imshow的浮点数输入要求,因此可以正确显示。
完整示例代码
import tensorflow as tf import matplotlib.pyplot as plt AUTOTUNE = tf.data.experimental.AUTOTUNE IMAGE_SIZE = [256, 256] files = ["<add_an_image_location>"] def decode_image(image): image = tf.io.read_file(image) image = tf.io.decode_png(image, channels=3) image = tf.image.resize(image, [*IMAGE_SIZE]) image = (tf.cast(image, tf.float32) / 127.5) - 1 # 转换到[-1, 1]区间 image = tf.reshape(image, [*IMAGE_SIZE, 3]) return image def load_dataset(filenames, labeled=True, ordered=False): dataset = tf.data.Dataset.from_tensor_slices(filenames) dataset = dataset.map(decode_image, num_parallel_calls=AUTOTUNE) return dataset ds = load_dataset(files, labeled=True).batch(1) example = next(iter(ds)) plt.imshow(example[0] * 0.5 + 0.5) # 直接映射到[0,1]浮点数区间 plt.show()
内容的提问来源于stack exchange,提问作者Pratheek Ponnuru
相关产品推荐
相关产品推荐

