RAMAC Example on Custom Volumetric images

RAMAC repository is tailored for implementation of the algorithm on Monaleesa Computed Tomography (CT) data set as outlined in the below paper : Image registration based automated lesion correspondence pipeline for longitudinal CT data

Hence users can use this tool for their own volumetric image dataset. The following function provides a convenient format for users to establish correspondence within their own volumetric image datasets. By simply providing the directory path containing the images and the corresponding Region of Interest (ROI) coordinate information, users can effortlessly establish the necessary correspondence.

[1]:
import sys
sys.path.append("../ramac")
from registration import *
from correspondence_csv_input import *
from transform_coordinates import *
from merge_dataframe import *
from phantominator import shepp_logan
from plots import *
from input_transform import *
from preprocessing import mask_air
from utils import *
#import warnings
import scipy
import numpy as np
import SimpleITK as sitk
import pandas as pd
import os

The below function is to perform a test using custom data. This function shows the process to load DICOM series for longitudinal image data at two timepoints, performs rigid 3D registration,perform adaaptive hungarian and saves result files, and plots triplanar views of the images.

[ ]:
def test_custom_data():

    ## Directory 1 = '/projects01/didsr-novartis/reference/Novartis_Monaleesa/Images/ML3_deid/1003003/Screening/CT - Chest - Abdomen - Pelvis - Venous - Spiral'
    ## Directory 2 = '/projects01/didsr-novartis/reference/Novartis_Monaleesa/Images/ML3_deid/1003003/Week 8/CT - Chest - Abdomen - Pelvis - Venous - Spiral'

    Screening_image = load_dicom_series('Directory 1') ## User needs to give the directory path
    Week_8_image = load_dicom_series('Directory 2')

    ## Preprocess the images if needed
    fixed_image = mask_air(Screening_image)
    moving_image = mask_air(Week_8_image)
    # # Apply the 3D rigid registration
    moving_resampled, [init_transform, final_transform] = registration_3d_rigid_series(fixed_image, moving_image)

    result_folder = "monaleesa"
    os.makedirs(result_folder, exist_ok=True)  # Create the result folder if it doesn't exist

    # File paths for saving CSV files which contains the ROI coordinates as inputs in CSV format (to be placed by user)

    filename_fixed_R1 = os.path.join(result_folder, 'df_lesions_Screening_1.csv')
    filename_fixed_R2 = os.path.join(result_folder, 'df_lesions_Screening_2.csv')
    filename_moving_R1 = os.path.join(result_folder, 'df_lesions_Week_8_1.csv')
    filename_moving_R2 = os.path.join(result_folder, 'df_lesions_Week_8_2.csv')

    ## Apply Adaptive Hungarian
    threshold = 30
    correspondences_screening, unmatched_names_df1_screening, unmatched_names_df2_screening = process_lesion_timepoints(filename_fixed_R1, filename_fixed_R2, threshold)
    plot_lesion_correspondences_timepoints(filename_fixed_R1, filename_fixed_R2)
    final_df_screening = create_final_dataframe_timepoints(correspondences_screening, unmatched_names_df1_screening, unmatched_names_df2_screening, filename_fixed_R1, filename_fixed_R2)

    correspondences_week_8, unmatched_names_df1_week_8, unmatched_names_df2_week_8 = process_lesion_timepoints(filename_moving_R1, filename_moving_R2, threshold)
    plot_lesion_correspondences_timepoints(filename_moving_R1, filename_moving_R2)
    final_df_week_8 = create_final_dataframe_timepoints(correspondences_week_8, unmatched_names_df1_week_8, unmatched_names_df2_week_8, filename_moving_R1, filename_moving_R2)

    final_df_S = create_trim_dataframe(final_df_screening)
    final_df_8 = create_trim_dataframe(final_df_week_8)

    ## Save the dataframes of the ROI coordiantes in CSV format
    filename_fixed = os.path.join(result_folder, 'fixed_coordinates.csv')
    filename_moving = os.path.join(result_folder, 'moving_coordinates.csv')
    filename_registered = os.path.join(result_folder, 'registered_coordinates.csv')
    filename_correspondence = os.path.join(result_folder, 'correspondence_indices.csv')

    save_transformed_dataframe(final_df_S, filename_fixed)
    save_transformed_dataframe(final_df_8, filename_moving)
    ## Apply the transformation matrix on ROI cooridnates of moving image (Image B) to obtain registered ROI cooridnates
    final_transform_1 = final_transform.GetInverse()

    registered_coordinates = create_transformed_dataframe(filename_moving, final_transform_1)
    save_transformed_dataframe(registered_coordinates, filename_registered)

    ## Apply Adaptive Hungarian on the fixed ROI cooridnates and registered coordinates
    threshold = 30
    correspondences, unmatched_names_df1, unmatched_names_df2 = process_lesion_timepoints(filename_fixed, filename_registered, threshold)
    plot_lesion_correspondences_timepoints(filename_fixed, filename_registered)
    final_df = create_final_dataframe_timepoints(correspondences, unmatched_names_df1, unmatched_names_df2, filename_fixed, filename_registered)

    ## Saving the final correspondence thereby achieved in a CSV format
    df_transformed = merge_indices(final_df)
    df_transformed.to_csv(filename_correspondence, index=False)

    ## Transform the ROI coordinates from physical to voxel unit for plotting

    fixed_voxel = transform_physical_to_index(fixed_image, filename_fixed)
    fixed_voxel_tuples = voxel_tuples_from_dataframe(fixed_voxel)
    moving_voxel = transform_physical_to_index(moving_image, filename_moving)
    moving_voxel_tuples = voxel_tuples_from_dataframe(moving_voxel)
    registered_voxel = transform_physical_to_index(moving_resampled, filename_registered)
    registered_voxel_tuples = voxel_tuples_from_dataframe(registered_voxel)

    ## Triplanar visualization after registration

    window_level = 100
    window_width = 2000

    images = [fixed_image, moving_image, moving_resampled]
    voxel_tuples_list = [fixed_voxel_tuples, moving_voxel_tuples, registered_voxel_tuples]
    image_names = ['Fixed', 'Moving', 'Registered']

    for image, voxel_tuples, image_name in zip(images, voxel_tuples_list, image_names):
        plot_triplanar(image, voxel_tuples, window_level, window_width, image_name)


test_custom_data()