You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用image_dataset_from_directory生成tfrecords后解码图像失真如何解决

问题原因
  1. 编码阶段类型转换逻辑错误:tf.image.convert_image_dtype默认会将浮点型输入视为[0, 1]范围,乘以255后映射为uint8的[0, 255]区间。但image_dataset_from_directory默认无rescale配置,返回的float32类型图像像素本身就是[0, 255]范围,经过convert_image_dtype转换后,所有大于1的像素值都会被截断为255,直接导致图像过曝、色彩失真。
  2. 解码阶段重复缩放:编码阶段已经通过image_dataset_from_directory的image_size参数将图像缩放到固定尺寸,解码后又执行了一次tf.image.resize操作,二次插值会额外引入精度损失,如果两次设置的尺寸不一致还会导致图像拉伸变形,进一步加重失真。
修复方案
  1. 修正编码阶段的类型转换逻辑,将process_image函数中的tf.image.convert_image_dtype替换为直接强转,可选设置JPEG最高质量减少压缩损耗:
def process_image(image, label):
    # 替换convert_image_dtype为tf.cast,适配[0,255]范围的float32输入
    image = tf.cast(image, dtype=tf.uint8)
    image = tf.io.encode_jpeg(image, quality=100)
    
    label = tf.one_hot(label, NUM_CLASSES)
    
    return image, label
  1. 移除解码阶段不必要的resize操作,除非业务确实需要修改图像尺寸:
def _parse_image_function(example):
    image_feature_description = {
        'image': tf.io.FixedLenFeature([], tf.string),
        'label': tf.io.FixedLenFeature([40], tf.float32),
    }

    features = tf.io.parse_single_example(example, image_feature_description)
    image = tf.image.decode_jpeg(features['image'], channels=3)
    # 移除多余的resize步骤
    label = features['label']

    return image, label
  1. 如果确实需要在解码阶段调整图像尺寸,展示时要先将resize后的float32类型数据正确转换为uint8:
plt.imshow(tf.cast(images[i], tf.uint8).numpy())

内容的提问来源于stack exchange,提问作者SinkingTitanic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 17:57:01