TFRecords解析:如何从单个张量中解码多张mask图像?
错误原因
tf.image.decode_png 一次只能处理单个PNG字节串(标量字符串张量),你序列化时image/object/mask存储的是变长字符串列表,解析后得到的是形状为[?]的1阶张量,直接传入解码接口就会触发阶数不匹配报错。
解决方法
使用tf.map_fn对mask列表中的每个元素单独解码,同时注意你生成的mask本身是单通道二值图,解码时不需要指定3通道,避免冗余。修改后的解析函数代码如下:
def parse_example(serialized_example): feature_dict = { 'image/height': tf.io.FixedLenFeature([], tf.int64), 'image/width': tf.io.FixedLenFeature([], tf.int64), 'image/encoded': tf.io.FixedLenFeature([], tf.string), 'image/object/class/label': tf.io.FixedLenSequenceFeature([], tf.int64, allow_missing=True), 'image/object/mask': tf.io.FixedLenSequenceFeature([], tf.string, allow_missing=True), } example = tf.io.parse_single_example(serialized_example, features=feature_dict) raw_height = tf.cast(example['image/height'], tf.int32) raw_width = tf.cast(example['image/width'], tf.int32) image = tf.image.decode_png(example['image/encoded'], channels=3) image = tf.image.resize(image, (512, 512)) labels = example['image/object/class/label'] # 遍历mask列表逐个解码 masks = tf.map_fn( lambda x: tf.image.decode_png(x, channels=1), example['image/object/mask'], fn_output_signature=tf.TensorSpec(shape=(None, None, 1), dtype=tf.uint8) ) # 统一mask尺寸,按需调整 masks = tf.image.resize(masks, (512, 512)) # 不需要通道维度的话可以压缩:masks = tf.squeeze(masks, axis=-1),输出形状为[N, 512,512],N为当前图像的物体数量
额外注意事项
- 若后续训练要求固定张量形状,可在resize后补充静态形状声明:
masks.set_shape([None, 512, 512, 1]) - 若图像中没有标注物体,
image/object/mask会返回空张量,可按需补充判空逻辑避免后续训练报错
内容的提问来源于stack exchange,提问作者0x00
相关产品推荐
相关产品推荐

