存储为HDF5后如何还原原始预处理图像?
问题原因分析
嘿,这个问题的核心其实是数据类型不匹配导致的数值溢出:
- cv2读取的图像默认是
uint8类型(数值范围0-255),但你在创建HDF5数据集时用了np.int8(数值范围-128到127)。 - 当把0-255的
uint8值存入int8数据集时,大于127的数值会被强制转换为负数(比如255会变成-1),这直接导致了图像色彩失真,也就是你看到的读取后图像和预处理前的差异。 - 而预测时,你用HDF5读取的是已经被“错误转换”后的数据,训练过程也是基于这些失真数据进行的,所以直接传正常预处理的图像(未经过溢出转换)就会和训练数据分布不一致,导致预测结果错误。
解决方案
1. 修复HDF5保存时的数据类型
把保存图像的数据集类型从np.int8改成np.uint8,和cv2读取的图像类型保持一致,避免数值溢出:
修改保存代码中的这一行:
hdf5_file.create_dataset("train_img", train_shape, np.uint8)
这样保存后的图像数据和预处理后的原始数据完全一致,读取后也不会有色彩失真的问题。
2. 统一预测时的预处理流程
直接用cv2读取图像做预测时,必须和你保存HDF5前的预处理步骤完全对齐,包括:
- 旋转90度
- 缩放到128x128
- 通道顺序转换(从cv2的HWC转为CNN需要的CHW)
- (如果训练时做了归一化或均值减法,也要同步执行)
给你写个示例预测预处理函数:
def preprocess_for_prediction(img_path, mean=None): # 1. 读取图像 img = cv2.imread(img_path) # 2. 和保存HDF5前一致的预处理 img = imutils.rotate(img, 90) img = cv2.resize(img, (128, 128)) # 3. 转换通道顺序为CHW(和训练时一致) img = np.rollaxis(img, 2) # 4. 转换数据类型(如果训练时用了float32) img = img.astype('float32') # 5. 如果训练时做了均值减法,这里也要执行 if mean is not None: img -= mean # 6. 增加batch维度(Keras预测需要batch维度) return img[None, ...]
使用的时候,先加载之前保存的mean值,再传入图像路径即可:
# 加载mean hdf5_file = h5py.File(r'D:\test_images\test.hdf5', "r") mean = hdf5_file["train_mean"][...] hdf5_file.close() # 预处理图像并预测 pred_img = preprocess_for_prediction(r"D:\test_images/your_test_img.jpg", mean) result = model.predict(pred_img)
3. 验证修复效果
修改保存代码后重新生成HDF5文件,再读取保存的图像,你会发现test_after.jpg和test_before.jpg完全一致了;同时用上面的预处理函数得到的图像,预测结果也会和直接从HDF5读取的图像结果一致。
内容的提问来源于stack exchange,提问作者Anupam Mohanty
相关产品推荐
相关产品推荐

