Gantry tilt correction for list of DICOM images

Hello,

I am working on writing my own gantry tilt correction function in Python. The function takes in a list of correctly ordered DICOM images loaded by pydicom, corrects each slice, and returns a corrected 3D image.

def correct_gantry_tilt(images):
    
    corrected_images = np.zeros((len(images), images[0].Rows, images[0].Columns))
    
    for image_index, image in enumerate(images):
        
        gantry_tilt = image.GantryDetectorTilt
        slice_location = image.SliceLocation
        inter_slice_distance = image.SliceThickness * np.cos(np.radians(gantry_tilt))
        
        image = sitk.GetImageFromArray(image.pixel_array[:,:,np.newaxis])
        transform = sitk.AffineTransform(3)
        transform.SetCenter(image.TransformContinuousIndexToPhysicalPoint(np.array(image.GetSize())/2))
        transform.SetTranslation((0, 0, (slice_location-images[0].SliceLocation)/inter_slice_distance))
        transform.Shear(0, 2, np.radians(gantry_tilt))
        output_shape = (512, 512, 512)
        resampled_image = sitk.Resample(image, output_shape, transform, sitk.sitkLinear,  [-output_shape[0]//2,0,0], image.GetSpacing(), image.GetDirection())
        resampled_image = sitk.GetArrayFromImage(resampled_image)
        
        corrected_images[image_index,:,:] = np.amax(resampled_image, axis=2)
    
    return corrected_images

The current implementation does not seem to get the tilt angle correct and is slow (this is because of the large output_shape that is being reduced with np.amax()). Does anyone have any insight into how to efficiently correct gantry tilt of a single DICOM image?

One option is to read the image with non-orthogonal direction matrix by using ImageSeriesReader with SetForceOrthogonalDirection(True), and the resampling it onto orthogonal grid. I don’t know whether it would be noticeably faster than resampling slices one by one.

Thank you for the response, @dzenanz.

Is that a method in the python library? The following doesn’t seem to work for me.

      1 reader = sitk.ImageSeriesReader()
----> 2 reader.SetForceOrthogonalDirection(True)

AttributeError: 'ImageSeriesReader' object has no attribute 'SetForceOrthogonalDirection'

It might not be exposed in SimpleITK. Try itk.ImageSeriesReader, example here. And use ITK for the rest of the code, or convert the image from itk to sitk.