在分割任务中,一个患者有很多层图像,但是勾画的ROI仅有那么几层。我想去除ROI以外层数的那些没用的图像。这里以一个36张图像的nii格式数据为例
查看一下mask文件中有多少个非0图像
import nibabel as nib
import numpy as np
# 加载 .nii 文件
file_path = r"C:\Users\梦里梦见梦不见的\Desktop\练习\ROI\zhangsan-label.nii"#
image = nib.load(file_path)
# 获取数据数组
data = image.get_fdata()
# 打印数据的形状
print("数据的形状:", data.shape)
# 初始化一个列表来存储非全零图像的序号
non_zero_indices = []
# 遍历每张图像
for i in range(data.shape[2]): # 遍历第三维,即36张图像
image_slice = data[:, :, i] # 提取第i张图像
if np.any(image_slice): # 检查图像是否包含非零像素
non_zero_indices.append(i) # 将序号加入列表
# 打印筛选结果
print(f"包含非零像素的图像序号: {non_zero_indices}")
print(f"筛选出的非全零图像数量: {len(non_zero_indices)}")
数据的形状: (480, 480, 36) 包含非零像素的图像序号: [13, 14, 15, 16] 筛选出的非全零图像数量: 4
对mask中勾画的ROI进行查看
import nibabel as nib
import matplotlib.pyplot as plt
# 加载处理后的NIfTI文件
processed_path = r"C:\Users\梦里梦见梦不见的\Desktop\练习\ROI\CAO_ZHAN_GUO-label.nii"
processed_img = nib.load(processed_path)
processed_data = processed_img.get_fdata() # 获取处理后的数据,形状为(480, 480, 36)
# 可视化36张图像
def visualize_slices(data, num_slices):
"""
可视化3D数据中的多张切片
:param data: 3D数据,形状为(height, width, depth)
:param num_slices: 需要可视化的切片数量
"""
depth = data.shape[2] # 获取切片的数量
slice_indices = np.linspace(0, depth - 1, num_slices, dtype=int) # 均匀选择切片索引
# 创建子图
fig, axes = plt.subplots(6, 6, figsize=(15, 15)) # 6x6的子图布局
fig.suptitle("Processed Image Slices", fontsize=16)
for i, idx in enumerate(slice_indices):
ax = axes[i // 6, i % 6] # 获取当前子图
ax.imshow(data[:, :, idx], cmap="gray") # 显示切片
ax.set_title(f"Slice {idx}")
ax.axis("off") # 关闭坐标轴
plt.tight_layout()
plt.show()
# 可视化36张切片
visualize_slices(processed_data, 36)
对image图像进行查看
我们要删除mask中没有勾画ROI的图像,最后是这样的mask文件
并保存对应的image图像
最后就是保存了两个删除后的文件。
完整的代码,批量操作image和mask文件夹下的文件,并保存到两个新的文件夹中
import nibabel as nib
import numpy as np
import os
# 设置image和mask文件夹路径
image_folder = r"C:\Users\梦里梦见梦不见的\Desktop\练习\image"
mask_folder = r"C:\Users\梦里梦见梦不见的\Desktop\练习\ROI"
new_image_folder = r"C:\Users\梦里梦见梦不见的\Desktop\练习\image_filtered"
new_mask_folder = r"C:\Users\梦里梦见梦不见的\Desktop\练习\ROI_filtered"
# 创建新文件夹(如果不存在)
os.makedirs(new_image_folder, exist_ok=True)
os.makedirs(new_mask_folder, exist_ok=True)
# 遍历image文件夹中的所有nii文件
for image_filename in os.listdir(image_folder):
if image_filename.endswith('.nii'):
# 构建对应的mask文件名
mask_filename = image_filename.replace('.nii', '-label.nii')
# 构建完整路径
image_path = os.path.join(image_folder, image_filename)
mask_path = os.path.join(mask_folder, mask_filename)
# 检查mask文件是否存在
if not os.path.exists(mask_path):
print(f"警告: 未找到对应的mask文件 {mask_filename},跳过此文件。")
continue
# 读取image和mask文件
image_nii = nib.load(image_path)
mask_nii = nib.load(mask_path)
# 获取图像数据
image_data = image_nii.get_fdata()
mask_data = mask_nii.get_fdata()
# 创建一个空列表,用于保存所有非零图像
filtered_image_data = []
filtered_mask_data = []
# 遍历每张图像(这里假设每张图像的大小是480x480)
for i in range(image_data.shape[2]): # 假设第三个维度是图像的数量,这里是36
# 选择当前图像的mask(二维数据)
mask_slice = mask_data[:, :, i]
# 如果mask图像有任何非零像素,则保存对应的image和mask
if np.any(mask_slice != 0):
# 获取该图像的数据
image_slice = image_data[:, :, i]
# 将符合条件的图像和mask存入列表
filtered_image_data.append(image_slice)
filtered_mask_data.append(mask_slice)
# 将筛选出的图像合并成一个新的数组
if filtered_image_data and filtered_mask_data: # 确保有有效的图像
filtered_image_data = np.stack(filtered_image_data, axis=2)
filtered_mask_data = np.stack(filtered_mask_data, axis=2)
# 打印处理的文件名
print(f"处理文件: {image_filename} 和 {mask_filename}")
# 保存新的合并后的nii文件
new_image_filename = os.path.join(new_image_folder, image_filename)
new_mask_filename = os.path.join(new_mask_folder, mask_filename)
# 保存为新的nii文件
new_image_nii = nib.Nifti1Image(filtered_image_data, image_nii.affine)
new_mask_nii = nib.Nifti1Image(filtered_mask_data, mask_nii.affine)
# 保存为新的nii文件
nib.save(new_image_nii, new_image_filename)
nib.save(new_mask_nii, new_mask_filename)
print("批量处理完成!")