padding扩充
import nibabel as nib
import numpy as np
from scipy import ndimage
def pad_nii(img_path, padded_shape):
img = nib.load(img_path)
data = img.get_fdata()
current_shape = np.array(data.shape)
pad_widths = [(max(0, padded_shape[i] - current_shape[i]) // 2, (padded_shape[i] - current_shape[i] + 1) // 2) for i in range(3)]
pad_widths = tuple(pad_widths)
padded_data = np.pad(data, pad_width=pad_widths, mode='constant')
zoom_factors = tuple(padded_shape[i] / current_shape[i] for i in range(3))
# 使用高质量的三次插值进行插值
padded_data = ndimage.zoom(padded_data, zoom_factors, order=3)
padded_image = nib.Nifti1Image(padded_data, img.affine)
return padded_image
看完是不是有一些疑问:
1.我还是不太清楚pad_widths 这里做了什么,能详细解释吗,还有后面对它进行了tuple
2. padded_image = nib.Nifti1Image(padded_data, img.affine) 这里是干什么
回答1: pad_widths
是一个整数或由长度为轴数的元组(tuple)组成的序列,用于指定每个轴上填充的宽度。其中,正数表示在轴的两端填充相应的宽度,负数表示削减相应的宽度。
在这里,我们使用 numpy.pad() 函数将 3D 数据沿着三个轴进行填充,以将其填充到目标大小 (640, 640, 24)。因此,我们需要指定每个轴上填充的宽度,以及填充的方式。
具体来说,我们使用 pad_widths = ((left_pad, right_pad), (top_pad, bottom_pad), (front_pad, back_pad)) 指定每个轴上的填充宽度。
其中,left_pad 和 right_pad 分别表示在 x 轴左侧和右侧填充的宽度,top_pad 和 bottom_pad 分别表示在 y 轴上方和下方填充的宽度,front_pad 和 back_pad 分别表示在 z 轴前面和后面填充的宽度。
回答2: nib.Nifti1Image
是 nibabel 库中的一个函数,用于创建一个 Nifti 文件格式的图像对象,其中 padded_data 是填充后的 3D 数据,img.affine 是原始图像的仿射变换矩阵。
仿射变换矩阵是一个 4 x 4 的矩阵,它将 3D 数据中的坐标映射到物理空间中的坐标。Nifti 格式的图像数据不仅包含 3D 数据本身,还包括其仿射变换矩阵,用于描述数据在物理空间中的位置、方向和缩放等信息。
在创建 Nifti1Image 对象时,可以将仿射变换矩阵设置为原始图像的仿射变换矩阵 img.affine,以保留原始图像的空间信息。
那么简而言之: 我原始图像的信息存到img.affine
当中了,我最后需要提取出原图像中的一些信息保存到填充后的图像中,但需要注意,三次高质量插值会导致生成的文件结果较大,若不可接受,删除插值部分代码即可。
crop裁剪
bing = 'xueguan'
source = 'niidata'
modal = 't1c'
def crop_nifti_file(file_path, output_path, target_size=(512, 512, 24)):
img = nib.load(file_path)
data = img.get_fdata()
center = np.array(data.shape[:3]) // 2
start = center - np.array(target_size) // 2
end = start + np.array(target_size)
cropped_data = data[start[0]:end[0], start[1]:end[1], start[2]:end[2]]
cropped_img = nib.Nifti1Image(cropped_data, img.affine)
# 构造输出文件名
output_path = os.path.join(output_path, bing,source,file_path.split('\\')[-2])
if not os.path.exists(output_path): # 如果不存在路径,则创建这个路径,关键函数就在这两行,其他可以改变
os.makedirs(output_path)
output_path = os.path.join(output_path, file_path.split('\\')[-1])
# Save the cropped image to the output path
nib.save(cropped_img, output_path)
标题保存 标题为2D图像的pickle格式
import numpy as np
import os # 用于遍历文件夹
import nibabel as nib # 用nibabel包打开nii文件
import pickle
import glob
# t1c模态比t2模态更容易看到肿瘤
modalities = 't1c'
class_name = 'naomo'
#加载nii.gz文件
def nib_load(file_name):
if not os.path.exists(file_name):
print('Invalid file name, can not find the file!')
# 加载该图像
proxy = nib.load(file_name)
# 获取图像
data = proxy.get_fdata()
proxy.uncache()
# 返回图像
return data
# 改变视角
def change_view(img):
(x, y, z) = img.shape # 获取图像的3个方向的维度
for i in range(z): # z方向
silce = np.fliplr(np.rot90(img[:, :, :], -1))
return silce
def nii_to_image(img_path,labelpath,twoD_imgfile):
filenames = os.listdir(imgpath) # 指定nii所在的文件夹
for patient in filenames:
patient_path = os.listdir(os.path.join(imgpath,patient))
for f in patient_path:
if f.split("_")[1].startswith("t1c"):
x = f.split("_")[0]
label_path = os.path.join(labelpath,x,'*')
# 获取文件夹中的文件列表
label_file = glob.glob(label_path)
# 如果列表只包含一个文件,则读取该文件
if len(label_file) == 1:
label = np.array(nib_load(label_file[0]), dtype='uint8', order='C')
for depth in range(label.shape[-1]):
if np.any(label[..., depth]):
img = nib_load(os.path.join(img_path,patient,patient+'_'+modalities+'.nii.gz'))
# 对图像的z方向进行旋转翻转,得到与原图像相同的视角
img = change_view(img)
img = np.array(img, dtype='float32', order='c')[..., depth]
output = os.path.join(twoD_imgfile,class_name,modalities)
if not os.path.exists(output): # 如果不存在路径,则创建这个路径,关键函数就在这两行,其他可以改变
os.makedirs(output)
output = os.path.join(output,f'{x}_{modalities}_{depth}.pkl')
print(output)
with open(output, 'wb') as f:
assert img.shape == (512, 512), "img.shape: {}, not match (512, 512)!"
pickle.dump(img, f)
若保存为2Dpng图像,即把后面保存部分代码修改
# 将输出路径设置为输出目录下的类别名和模态名
output = os.path.join(twoD_imgfile,class_name,modalities)
if not os.path.exists(output): # 如果不存在路径,则创建这个路径,关键函数就在这两行,其他可以改变
os.makedirs(output)
output = os.path.join(output,f'{x}_{modalities}_{depth}.png')
print(output)
# 将图像保存为PNG格式
imageio.imwrite(output, img)