今天要实现的任务是提取肿瘤的感兴趣区域。
有两个文件,一个是nii的原始图像文件,一个是nii的标签文件。
我们要实现的是:在标签文件上选出最大层面,然后把最大层面的ROI映射到原始图像区域,在原始图像上提裁剪出ROI区域,然后根据这个ROI,在其上面一层和下面一层,共裁剪出三张原始图像。
将原始图像和标签图像的像素值提取出来
# 读取原始NII文件
image_origin = sitk.ReadImage(r"C:\Users\Administrator\Desktop\Breast\AN_HAI_YING_DCE.nii")
# 读取标签NII文件
image_label = sitk.ReadImage(r"C:\Users\Administrator\Desktop\Breast\AN_HAI_YING_label.nii")
# 转换为NumPy数组
origin_array = sitk.GetArrayFromImage(image_origin)
label_array = sitk.GetArrayFromImage(image_label)
#提取像素值
origin_array = np.array([origin_array[i] for i in range(origin_array.shape[0])])
label_array = np.array([label_array[i] for i in range(label_array.shape[0])])
print(origin_array.shape)
print(label_array.shape)
(36, 480, 480) (36, 480, 480)
筛选出标签图像中不为0的像素值最多的那张图像,就是层面最大的图像。
import numpy as np
# 假设 tumor_array 是你的数据数组
# tumor_array 的形状为(36, 480, 480)
# 遍历每张图片
max_nonzero_pixels = 0
max_nonzero_index = None
for i in range(label_array.shape[0]):
# 计算当前图片中非零像素的数量
nonzero_pixels = np.count_nonzero(label_array[i])
# 如果当前图片的非零像素数量比之前的最大值大,则更新最大值和对应的索引
if nonzero_pixels > max_nonzero_pixels:
max_nonzero_pixels = nonzero_pixels
max_nonzero_index = i
# 打印结果
print("最多非零像素的图片索引为:", max_nonzero_index)
print("对应的非零像素数量为:", max_nonzero_pixels)
最多非零像素的图片索引为: 23 对应的非零像素数量为: 574
说明第23张图像是ROI层面最大的图像,(准确应该是第24张,因为从0开始)
根据最大层面的ROI,映射到对应的原始图像中,以及上一层和下一层。
roi_array =np.array([label_array[max_nonzero_index]*origin_array[max_nonzero_index - 1],
label_array[max_nonzero_index]*origin_array[max_nonzero_index],
label_array[max_nonzero_index]*origin_array[max_nonzero_index + 1]])
roi_array.shape
(3, 480, 480)
plt.imshow(roi_array[1],cmap='gray')
然后再剔除周围的0像素
参考去除图像周围的0像素,调整大小-CSDN博客
def trim_image(image):
# 转换为numpy数组
image_array = np.array(image)
# 找到非零像素的边界
non_zero_indices = np.nonzero(image_array)
min_row = np.min(non_zero_indices[0])
max_row = np.max(non_zero_indices[0])
min_col = np.min(non_zero_indices[1])
max_col = np.max(non_zero_indices[1])
min_depth = np.min(non_zero_indices[2])
max_depth = np.max(non_zero_indices[2])
# 裁剪图像
cropped_image_array = image_array[min_row:max_row + 1, min_col:max_col + 1, min_depth:max_depth + 1]
return cropped_image_array
查看裁剪后的代码
trim_image(roi_array).shape
(3, 31, 26)
对第三张图像进行可视化
plt.imshow(trim_image(roi_array)[2],cmap='gray')
这样就裁剪好了
然后使用双向线性插值调整图像的大小
参考 最邻近插值和线性插值-CSDN博客
from PIL import Image
import torch
import torch.nn.functional as F
import numpy as np
import matplotlib.pyplot as plt
image_tensor = torch.tensor(finish_array, dtype=torch.float32).unsqueeze(0)
# 目标图像大小
target_height, target_width =224,224
# 使用双线性插值角对齐对图像进行缩放
output_bilinear_corners_True = F.interpolate(image_tensor, size=(target_height, target_width), mode='bilinear', align_corners=True)
# 将张量转换回 numpy 数组
output_bilinear_corners_True_array = output_bilinear_corners_True.squeeze().numpy().astype(np.uint8)
对第二张进行可视化
plt.imshow(output_bilinear_corners_True_array[2],cmap='gray')
然后就可以将处理好的图像保存
import h5py
# 假设 output_bilinear_corners_True_array 是你处理好的数组
# 另外假设你的数组的形状为 (channel, height, width)
# 创建一个 HDF5 文件
with h5py.File(r"C:\Users\Administrator\Desktop\Breast\output_bilinear_corners_True.h5", "w") as hf:
# 将数组写入 HDF5 文件中
hf.create_dataset("output_array", data=output_bilinear_corners_True_array)
保存到一个h5文件中