如何从HDF5文件提取单张JPEG图像以适配CRSNet网络输入要求
我来给你梳理一下具体的实现步骤,结合Python的常用库就能搞定这个需求,咱们一步一步来:
解决方案步骤
1. 准备依赖库
首先需要安装几个核心工具库,用来处理HDF5文件、图像尺寸调整和数值操作:
pip install h5py opencv-python numpy pillow
2. 读取大HDF5文件中的原始数据
先把你手里的大HDF5文件里的images和density_maps读出来,注意原数据的最后一个维度是冗余的单通道,可以先去掉方便后续处理:
import h5py import numpy as np import cv2 import os # 替换成你的大HDF5文件路径 large_hdf5_path = "your_large_dataset.h5" with h5py.File(large_hdf5_path, 'r') as hf: # 读取并去掉最后一个单通道维度 images = np.squeeze(hf['images'][:], axis=-1) # 形状变为 (300, 380, 676) density_maps = np.squeeze(hf['density_maps'][:], axis=-1) # 形状变为 (300, 380, 676)
3. 调整图像与密度图的尺寸
CRSNet要求输入图像是(572, 945),这里要注意两个关键点:
- 图像调整:直接用双线性插值拉伸即可,视觉效果较好
- 密度图调整:不能直接拉伸!因为密度图的总和代表场景中的总人数,直接拉伸会改变人数统计,必须做比例校正
示例处理代码:
target_shape = (572, 945) # (目标高度, 目标宽度) # 计算面积缩放比例,用于校正密度图 original_area = 380 * 676 target_area = target_shape[0] * target_shape[1] scale_factor = original_area / target_area # 创建保存文件的文件夹 os.makedirs("crsnet_input_images", exist_ok=True) os.makedirs("crsnet_density_maps", exist_ok=True)
4. 循环处理并保存单独文件
遍历每一组图像和密度图,处理后分别保存为JPEG和单独的HDF5文件:
from tqdm import tqdm # 可选,用来显示处理进度 for idx in tqdm(range(len(images))): # 处理图像:转成uint8格式(如果原数据是0-1的float)并调整尺寸 img = images[idx] if img.dtype in [np.float32, np.float64]: img = (img * 255).astype(np.uint8) # cv2.resize的参数是(宽度, 高度),所以要调换target_shape的顺序 resized_img = cv2.resize(img, (target_shape[1], target_shape[0]), interpolation=cv2.INTER_LINEAR) # 保存JPEG img_save_path = os.path.join("crsnet_input_images", f"image_{idx:03d}.jpg") cv2.imwrite(img_save_path, resized_img) # 处理密度图:调整尺寸后校正比例,保证总人数不变 dm = density_maps[idx] resized_dm = cv2.resize(dm, (target_shape[1], target_shape[0]), interpolation=cv2.INTER_LINEAR) # 校正密度值,保持总人数一致 resized_dm = resized_dm * scale_factor # 加回单通道维度,恢复原数据格式 resized_dm = np.expand_dims(resized_dm, axis=-1) # 保存为单独的HDF5文件 dm_save_path = os.path.join("crsnet_density_maps", f"density_{idx:03d}.h5") with h5py.File(dm_save_path, 'w') as hf: hf.create_dataset("density_map", data=resized_dm)
额外注意事项
- 如果原图像是RGB三通道(而非灰度图),去掉代码中的
np.squeeze操作即可,直接处理(300, 380, 676, 3)格式的数据 - 如果你更喜欢用Pillow处理图像,可以替换cv2的图像调整代码:
from PIL import Image resized_img = Image.fromarray(img).resize((target_shape[1], target_shape[0]), Image.Resampling.BILINEAR) resized_img.save(img_save_path) - 处理大数量样本时,建议用
tqdm显示进度,避免不知道处理到哪一步
内容的提问来源于stack exchange,提问作者CodingKingggg
相关产品推荐
相关产品推荐

