如何从存储低剂量CT图像的.pkl格式NumPy数组中还原可视化图像
从.pkl存储的NumPy数组提取可查看低剂量CT图像的方案
你读取到的int16类型、大量元素值为-1000的数组完全符合CT原始数据特征:CT值以亨氏单位(HU)计量,空气的标准CT值即为-1000,大量-1000值对应扫描视野外的空气区域,属于正常表现。
按以下步骤操作即可得到可查看的图像:
1. 规整数组维度
你给出的读取结果外层是数组列表,每个子数组为多层CT的原始体数据,首先需要将其处理为形状为(切片数, 单切片高度, 单切片宽度)的标准3D CT体数据结构,去除多余的嵌套维度。
参考代码:
import pickle import numpy as np # 读取pkl文件 with open("lowDose_CT.pkl", "rb") as f: raw_load = pickle.load(f) # 去除嵌套、压缩长度为1的冗余维度 ct_volume = np.squeeze(raw_load[0]) # 打印维度和数值范围做校验 print(f"体数据维度: {ct_volume.shape}") print(f"CT值范围: {ct_volume.min()} HU ~ {ct_volume.max()} HU")
正常校验输出的维度第一个值为CT总切片数,后两个值为单张切片的像素长宽。
2. 窗宽窗位转换为可显示灰度图
CT原始int16格式的HU值范围覆盖-1000(空气)到数千(致密骨),普通显示设备仅支持0-255范围的8位灰度显示,必须通过窗宽窗位调整截断、归一化数值,不同窗设置对应观察不同组织:
- 肺窗:窗位-600HU,窗宽1500HU,用于观察肺部纹理、结节
- 纵隔窗:窗位40HU,窗宽400HU,用于观察纵隔软组织、血管、淋巴结
- 骨窗:窗位300HU,窗宽2000HU,用于观察骨骼结构
转换函数参考:
def hu_to_gray(hu_slice, win_center, win_width): hu_min = win_center - win_width // 2 hu_max = win_center + win_width // 2 # 截断超出窗范围的数值 clipped = np.clip(hu_slice, hu_min, hu_max) # 线性归一化到0-255灰度区间 gray = ((clipped - hu_min) / (hu_max - hu_min) * 255).astype(np.uint8) return gray
3. 预览与保存图像
可以逐切片转换后保存为通用图片格式,或直接预览指定切片,参考代码:
import matplotlib.pyplot as plt import os # 创建肺窗切片保存目录 os.makedirs("ct_lung_window", exist_ok=True) slice_num = ct_volume.shape[0] for idx in range(slice_num): current_slice = ct_volume[idx] # 跳过全为空气的无效空切片 if np.all(current_slice == -1000): continue # 转换为肺窗灰度图 lung_gray = hu_to_gray(current_slice, win_center=-600, win_width=1500) # 保存为png格式 plt.imsave(f"ct_lung_window/slice_{idx:04d}.png", lung_gray, cmap="gray") # 预览中间位置切片 mid_idx = slice_num // 2 mid_gray = hu_to_gray(ct_volume[mid_idx], win_center=-600, win_width=1500) plt.imshow(mid_gray, cmap="gray") plt.axis("off") plt.show()
注意事项:
- 如果预览图像存在方位偏差(旋转、翻转),直接对数组做对应的
np.rot90、np.flip操作调整即可,不同设备导出的数组轴顺序可能存在差异,调整到符合正常CT解剖方位即可。- 如果需要专业的3D查看、多平面重建效果,可以将规整后的3D数组保存为NIfTI格式,用3D Slicer、ITK-SNAP等医学影像软件打开,支持实时调整窗宽窗位。
内容的提问来源于stack exchange,提问作者Farah Jabeen
相关产品推荐
相关产品推荐

