如何处理并转换扩展名为.nii.gz的医学图像?
医学NIfTI(.nii.gz)格式图像转常规RGB/灰度图像方案
基础维度说明
你读取的BRATS脑肿瘤数据集的NIfTI图像是3D多序列MRI数据,各维度含义如下:
- 前两维(240,240):单张二维切片的像素尺寸
- 第三维155:3D MRI数据的轴向切片数量,你可以理解为将完整的3D大脑模型从头到脚方向切为155张连续的二维断层切片,索引从0到154对应不同的脑部位置
- 第四维4:对应4种不同的MRI扫描序列,通常为T1、T1增强(T1ce)、T2、FLAIR,不同序列对不同脑组织/病灶的显影特性不同
转换实现方法
可以实现转常规图像格式,操作步骤如下:
注意:nibabel的get_data()方法已被弃用,推荐替换为get_fdata()保证兼容性
1. 转(240,240)单通道灰度图像
核心逻辑是选取指定切片的单个MRI序列,归一化到0-255的像素范围后转uint8格式:
import nibabel as nib import glob import numpy as np from PIL import Image path = "./Task01_BrainTumour/imagesTr" path_list = glob.glob(path+'/*.gz') # 读取3D多序列图像 img = nib.load(path_list[0]).get_fdata() # 选取目标切片和序列:示例取第80层(索引79,通常是大脑中间层信息最丰富)、第0个序列(T1) slice_2d = img[:, :, 79, 0] # 归一化到0-255灰度范围 normalized_slice = (slice_2d - np.min(slice_2d)) / (np.max(slice_2d) - np.min(slice_2d)) * 255 gray_img = normalized_slice.astype(np.uint8) # 保存为png格式 Image.fromarray(gray_img).save("brain_gray_slice.png")
2. 转(240,240,3)三通道RGB图像
有两种常用转换逻辑:
方案A:多序列合成伪彩RGB
将3种不同的MRI序列分别映射到R、G、B通道,得到的伪彩图可同时展示多序列信息:
# 定义单通道归一化函数 def normalize_channel(channel_arr): return ((channel_arr - np.min(channel_arr)) / (np.max(channel_arr) - np.min(channel_arr)) * 255).astype(np.uint8) # 取第80层的三个不同序列分别对应R、G、B通道 r_channel = normalize_channel(img[:, :, 79, 0]) # T1序列对应R g_channel = normalize_channel(img[:, :, 79, 1]) # T1ce序列对应G b_channel = normalize_channel(img[:, :, 79, 2]) # T2序列对应B # 堆叠为三通道RGB数组 rgb_img = np.stack([r_channel, g_channel, b_channel], axis=-1) # 保存 Image.fromarray(rgb_img).save("brain_rgb_slice.png")
方案B:灰度图转三通道灰度RGB
如果需要和普通灰度照片格式对齐(三个通道数值完全相同),直接堆叠单通道灰度图三次即可:
rgb_gray = np.stack([gray_img, gray_img, gray_img], axis=-1) Image.fromarray(rgb_gray).save("brain_rgb_gray_slice.png")
优化提示
如果导出的图像对比度差,通常是因为信号存在极端离群值,可使用百分位截断优化归一化效果:
# 取1%和99%分位数截断离群值 p1, p99 = np.percentile(slice_2d, (1, 99)) clipped_slice = np.clip(slice_2d, p1, p99) # 再执行归一化操作 normalized_slice = (clipped_slice - p1) / (p99 - p1) * 255
内容的提问来源于stack exchange,提问作者Azzurra
相关产品推荐
相关产品推荐

