-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
- Loading branch information
There are no files selected for viewing
This file was deleted.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Large diffs are not rendered by default.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
|
||
## [Pre- to Post-Contrast Breast MRI Synthesis for Enhanced Tumour Segmentation]() | ||
|
||
In SPIE Medical Imaging 2024. | ||
|
||
![examples](docs/examples.png) | ||
|
||
## Getting Started | ||
The [Duke Dataset](https://sites.duke.edu/mazurowski/resources/breast-cancer-mri-dataset/) used in this study is available on [The Cancer Imaging Archive (TCIA)](https://wiki.cancerimagingarchive.net/pages/viewpage.action?pageId=70226903). | ||
|
||
You may find some examples of synthetic nifti files in [synthesis/examples](synthesis/examples). | ||
|
||
### Synthesis Code | ||
- [Config](synthesis/pix2pixHD/scripts/train_512p_duke_2D_w_GPU_1to195.sh) to run a training of the image synthesis model. | ||
- [Config](synthesis/pix2pixHD/scripts/test_512p_duke_2D_w_GPU_1to195.sh) to run a test of the image synthesis model. | ||
- [Code](synthesis/utils/convert_to_nifti_whole_dataset.py) to transform Duke DICOM files to NiFti files. | ||
- [Code](synthesis/utils/nifti_png_conversion.py) to extract 2D pngs from 3D NiFti files. | ||
- [Code](synthesis/utils/png_nifti_conversion.py) to create 3D NiFti files from axial 2D pngs. | ||
- [Code](synthesis/utils/get_training_patient_ids.py) to separate synthesis training and test cases. | ||
- [Code](synthesis/utils/metrics.py) to compute the image quality metrics such as SSIM, MSE, LPIPS, and more. | ||
- [Code](synthesis/utils/fid.py) to compute the Frèchet Inception Distance (FID) based on ImageNet and [RadImageNet](https://github.com/BMEII-AI/RadImageNet). | ||
|
||
### Segmentation Code | ||
- [Code](nnUNet/custom_scripts/convert_data_to_nnunet_204.py) to prepare 3D single breast cases for nnunet segmentation. | ||
- [Train-test-splits](nnUNet/nnunetv2/nnUNet_preprocessed/Dataset208_DukePreSynthetic/splits_final_pre_post_syn.json) of the segmentation dataset. | ||
- [Script](nnUNet/custom_scripts/full_pipeline.sh) to run the full nnunet pipeline on the Duke dataset. | ||
|
||
## Acknowledgements | ||
This repository borrows code from the [pix2pixHD](https://github.com/NVIDIA/pix2pixHD) and the [nnUNet](https://github.com/MIC-DKFZ/nnUNet) repositories. The 254 tumour segmentation masks used in this study were provided by [Caballo et al](https://doi.org/10.1002/jmri.28273). |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import os | ||
import SimpleITK as sitk | ||
import numpy as np | ||
from scipy import ndimage | ||
import csv | ||
import random | ||
|
||
import shutil | ||
|
||
def save_image(save_array, reference_img, save_path): | ||
image = sitk.GetImageFromArray(save_array) | ||
image.SetDirection(reference_img.GetDirection()) | ||
image.SetSpacing(reference_img.GetSpacing()) | ||
image.SetOrigin(reference_img.GetOrigin()) | ||
|
||
sitk.WriteImage(image, os.path.join(save_path)) | ||
|
||
|
||
def save_the_half(paths): #patient, pre_path, post_path | ||
|
||
patient = paths[0] | ||
post_path = paths[1] | ||
|
||
if os.path.exists(post_path): | ||
post = sitk.ReadImage(post_path) | ||
save_name = post_path.split('/')[-1] | ||
print(save_name) | ||
|
||
if not os.path.exists(os.path.join('/workspace/AutomaticSegmentation/nnUNet/nnunetv2/nnUNet_raw/Dataset204_DukePhaseOneHalf/imagesTr', save_name)): | ||
|
||
# create the half image based on where the mask is: | ||
post_array = sitk.GetArrayFromImage(post) | ||
|
||
# find which side the segmentation is - right or left | ||
if os.path.exists(os.path.join('/data/Duke-Breast-Cancer-MRI-Nifti-Whole-Preprocessed/masks_preprocessed', patient + '.nii.gz')): | ||
segmentation = sitk.GetArrayFromImage(sitk.ReadImage(os.path.join('/data/Duke-Breast-Cancer-MRI-Nifti-Whole-Preprocessed/masks_preprocessed', patient + '.nii.gz'))) | ||
segmentation_coordinates = ndimage.center_of_mass(segmentation) | ||
|
||
middle_coordinate = segmentation.shape[-1]/2 | ||
if segmentation_coordinates[-1] < middle_coordinate: | ||
new_post = post_array[:, :, :np.int64(middle_coordinate)] | ||
new_segmentation = segmentation[:, :, :np.int64(middle_coordinate)] | ||
else: | ||
new_post = post_array[:, :, np.int64(middle_coordinate + 1):] | ||
new_segmentation= segmentation[:, :, np.int64(middle_coordinate + 1):] | ||
save_image(new_post, post, os.path.join('/workspace/AutomaticSegmentation/nnUNet/nnunetv2/nnUNet_raw/Dataset204_DukePhaseOneHalf/imagesTr', patient+'_0000.nii.gz')) | ||
save_image(new_segmentation, post, os.path.join('/workspace/AutomaticSegmentation/nnUNet/nnunetv2/nnUNet_raw/Dataset204_DukePhaseOneHalf/labelsTr', patient+'.nii.gz')) | ||
|
||
def main(): | ||
processed_nifti_path = '/data/Duke-Breast-Cancer-MRI-Nifti-Whole-Preprocessed' | ||
pre_post_list = [] | ||
|
||
# step 1 | ||
for patient in os.listdir(processed_nifti_path): | ||
|
||
post = os.path.join(processed_nifti_path, patient, patient + '_0001.nii.gz') | ||
save_the_half([patient, post]) | ||
# # pre_post_list.append([patient, pre, post]) | ||
|
||
# # step 2 | ||
# # remove multifocal images | ||
|
||
# step 3 | ||
# select test data and remove it from the training set | ||
|
||
main() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import os | ||
import SimpleITK as sitk | ||
import numpy as np | ||
from scipy import ndimage | ||
import csv | ||
import random | ||
|
||
import shutil | ||
|
||
def save_image(save_array, reference_img, save_path): | ||
image = sitk.GetImageFromArray(save_array) | ||
image.SetDirection(reference_img.GetDirection()) | ||
image.SetSpacing(reference_img.GetSpacing()) | ||
image.SetOrigin(reference_img.GetOrigin()) | ||
|
||
sitk.WriteImage(image, os.path.join(save_path)) | ||
|
||
|
||
def save_the_half(paths): #patient, pre_path, post_path | ||
|
||
patient = paths[0] | ||
post_path = paths[1] | ||
|
||
if os.path.exists(post_path): | ||
post = sitk.ReadImage(post_path) | ||
save_name = post_path.split('/')[-1] | ||
print(save_name) | ||
|
||
if not os.path.exists(os.path.join('/workspace/AutomaticSegmentation/nnUNet/nnunetv2/nnUNet_raw/Dataset205_DukePreHalf/imagesTr', save_name)): | ||
|
||
# create the half image based on where the mask is: | ||
post_array = sitk.GetArrayFromImage(post) | ||
|
||
# find which side the segmentation is - right or left | ||
if os.path.exists(os.path.join('/data/Duke-Breast-Cancer-MRI-Nifti-Whole-Preprocessed/masks_preprocessed', patient + '.nii.gz')): | ||
segmentation = sitk.GetArrayFromImage(sitk.ReadImage(os.path.join('/data/Duke-Breast-Cancer-MRI-Nifti-Whole-Preprocessed/masks_preprocessed', patient + '.nii.gz'))) | ||
segmentation_coordinates = ndimage.center_of_mass(segmentation) | ||
|
||
middle_coordinate = segmentation.shape[-1]/2 | ||
if segmentation_coordinates[-1] < middle_coordinate: | ||
new_post = post_array[:, :, :np.int64(middle_coordinate)] | ||
new_segmentation = segmentation[:, :, :np.int64(middle_coordinate)] | ||
else: | ||
new_post = post_array[:, :, np.int64(middle_coordinate + 1):] | ||
new_segmentation= segmentation[:, :, np.int64(middle_coordinate + 1):] | ||
save_image(new_post, post, os.path.join('/workspace/AutomaticSegmentation/nnUNet/nnunetv2/nnUNet_raw/Dataset205_DukePreHalf/imagesTr', patient+'_0000.nii.gz')) | ||
save_image(new_segmentation, post, os.path.join('/workspace/AutomaticSegmentation/nnUNet/nnunetv2/nnUNet_raw/Dataset205_DukePreHalf/labelsTr', patient+'.nii.gz')) | ||
|
||
|
||
def main(): | ||
processed_nifti_path = '/data/Duke-Breast-Cancer-MRI-Nifti-Whole-Preprocessed' | ||
pre_post_list = [] | ||
|
||
|
||
# step 1 | ||
for patient in os.listdir(processed_nifti_path): | ||
post = os.path.join(processed_nifti_path, patient, patient + '_0000.nii.gz') | ||
save_the_half([patient, post]) | ||
|
||
# step 2 | ||
# remove multifocal images | ||
|
||
# step 3 | ||
# select test data and remove it from the training set | ||
|
||
|
||
main() |