ACDC_CDS_NICMS / datas /preprocess.py
TaipingQu's picture
Upload 305 files
772d47c verified
Raw History Blame Contribute Delete
5.53 kB
import os
import numpy as np
import SimpleITK as sitk
# Remove apical and basal slices with limited anatomical information
def crop_z_axis(data, group_size=30, keep_layers=9):
z_size = data.shape[0]
total_layers = z_size // group_size
if total_layers <= keep_layers:
return data
remove_layers = total_layers - keep_layers
remove_front = (remove_layers // 2) * group_size
remove_back = (remove_layers - remove_layers // 2) * group_size
cropped = data[remove_front:z_size-remove_back, :, :]
return cropped
def resample_spacing(Image,Label,NewSpacing):
Size=Image.GetSize()
Spacing=Image.GetSpacing()
Origin = Image.GetOrigin()
Direction = Image.GetDirection()
NewSize=[int(Size[0]*Spacing[0]/NewSpacing[0]),int(Size[1]*Spacing[1]/NewSpacing[1]),int(Size[2]*Spacing[2]/NewSpacing[2])]
Resample = sitk.ResampleImageFilter()
Resample.SetOutputDirection(Direction)
Resample.SetOutputOrigin(Origin)
Resample.SetSize(NewSize)
Resample.SetInterpolator(sitk.sitkBSpline)
Resample.SetOutputSpacing(NewSpacing)
NewImage = Resample.Execute(Image)
Resample = sitk.ResampleImageFilter()
Resample.SetOutputDirection(Direction)
Resample.SetOutputOrigin(Origin)
Resample.SetSize(NewSize)
Resample.SetOutputSpacing(NewSpacing)
Resample.SetInterpolator(sitk.sitkNearestNeighbor)
NewLabel = Resample.Execute(Label)
return NewImage,NewLabel
# Crop around cardiac region
def crop_xy_axis(image, mask, crop_size=(200, 200)):
if np.sum(mask) == 0:
return np.zeros((image.shape[0], crop_size[0], crop_size[1]), dtype=image.dtype), np.zeros((mask.shape[0], crop_size[0], crop_size[1]), dtype=mask.dtype)
non_zero_coords = np.argwhere(mask > 0)
z_min, y_min, x_min = non_zero_coords.min(axis=0)
z_max, y_max, x_max = non_zero_coords.max(axis=0)
center_y = (y_min + y_max) // 2
center_x = (x_min + x_max) // 2
crop_height, crop_width = crop_size
y_start = max(center_y - crop_height // 2, 0)
y_end = min(center_y + crop_height // 2, image.shape[1])
x_start = max(center_x - crop_width // 2, 0)
x_end = min(center_x + crop_width // 2, image.shape[2])
cropped_image = image[:, y_start:y_end, x_start:x_end]
cropped_mask = mask[:, y_start:y_end, x_start:x_end]
pad_y_before = max(0, crop_height // 2 - center_y)
pad_y_after = max(0, crop_height // 2 - (image.shape[1] - center_y))
pad_x_before = max(0, crop_width // 2 - center_x)
pad_x_after = max(0, crop_width // 2 - (image.shape[2] - center_x))
cropped_image = np.pad(
cropped_image,
((0, 0), (pad_y_before, pad_y_after), (pad_x_before, pad_x_after)),
mode='constant',
constant_values=0
)
cropped_mask = np.pad(
cropped_mask,
((0, 0), (pad_y_before, pad_y_after), (pad_x_before, pad_x_after)),
mode='constant',
constant_values=0
)
return cropped_image, cropped_mask
def preprocess_patient(img_path, seg_path, save_img_path, save_seg_path, target_spacing=(0.9375, 0.9375, 0.2451)):
img = sitk.ReadImage(img_path)
seg = sitk.ReadImage(seg_path)
img_arr = sitk.GetArrayFromImage(img)
seg_arr = sitk.GetArrayFromImage(seg)
# Step 1
cropped_img_arr = crop_z_axis(img_arr)
cropped_seg_arr = crop_z_axis(seg_arr)
cropped_img = sitk.GetImageFromArray(cropped_img_arr)
cropped_img.SetDirection(img.GetDirection())
cropped_img.SetOrigin(img.GetOrigin())
cropped_img.SetSpacing(img.GetSpacing())
cropped_seg = sitk.GetImageFromArray(cropped_seg_arr)
cropped_seg.SetDirection(img.GetDirection())
cropped_seg.SetOrigin(img.GetOrigin())
cropped_seg.SetSpacing(img.GetSpacing())
# Step 2
resample_img, resample_seg = resample_spacing(cropped_img, cropped_seg, target_spacing)
# Step 3
resample_img_arr = sitk.GetArrayFromImage(resample_img)
resample_seg_arr = sitk.GetArrayFromImage(resample_seg)
output_img_arr, output_seg_arr = crop_xy_axis(resample_img_arr, resample_seg_arr, crop_size=(200,200))
# save
output_img = sitk.GetImageFromArray(output_img_arr)
output_seg = sitk.GetImageFromArray(output_seg_arr)
output_img.SetDirection(resample_img.GetDirection())
output_img.SetOrigin(resample_img.GetOrigin())
output_img.SetSpacing(resample_img.GetSpacing())
output_seg.SetDirection(resample_img.GetDirection())
output_seg.SetOrigin(resample_img.GetOrigin())
output_seg.SetSpacing(resample_img.GetSpacing())
sitk.WriteImage(output_img, save_img_path)
sitk.WriteImage(output_seg, save_seg_path)
def run_preprocessing():
root="./ACDC4D"
img_dir=os.path.join(root,"img")
seg_dir=os.path.join(root,"seg")
output_dir=os.path.join("./processed")
os.makedirs(output_dir,exist_ok=True)
files=[f for f in os.listdir(img_dir) if f.endswith("_3d.nii.gz")]
for fname in files:
pid=fname.split("_")[0]
print(f"Processing {pid}")
patient_dir=os.path.join(output_dir, pid)
os.makedirs(patient_dir, exist_ok=True)
img_path=os.path.join(img_dir, fname)
seg_path=os.path.join(seg_dir, fname)
save_img=os.path.join(patient_dir, f"{pid}_sa_image.nii.gz")
save_seg=os.path.join(patient_dir, f"{pid}_sa_image-seg.nii.gz")
preprocess_patient(img_path, seg_path, save_img, save_seg)
print("All preprocessing finished.")
if __name__=="__main__":
run_preprocessing()