Beispiel #1
0
def process_image(filename, output_folder, sigma):
    """
    Reorient image at filename, smooth with sigma, clamp and save to output_folder.
    :param filename: The image filename.
    :param output_folder: The output folder.
    :param sigma: Sigma for smoothing.
    """
    basename = os.path.basename(filename)
    basename_wo_ext = basename[:basename.find('.nii.gz')]
    print(basename_wo_ext)
    ImageType = itk.Image[itk.SS, 3]
    reader = itk.ImageFileReader[ImageType].New()
    reader.SetFileName(filename)
    image = reader.GetOutput()
    reoriented = reorient_to_rai(image)
    if not basename_wo_ext.endswith('_seg'):
        reoriented = smooth(reoriented, sigma)
        reoriented = clamp(reoriented)
    reoriented.SetOrigin([0, 0, 0])
    m = itk.GetMatrixFromArray(
        np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]], np.float64))
    reoriented.SetDirection(m)
    reoriented.Update()
    itk.imwrite(reoriented,
                os.path.join(output_folder, basename_wo_ext + '.nii.gz'))
def reorient_to_rai(image):
    # Reorient image to RAI orientation.
    filter = itk.OrientImageFilter.New(image)
    filter.UseImageDirectionOn()
    filter.SetInput(image)
    m = itk.GetMatrixFromArray(np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]], np.float64))
    filter.SetDesiredCoordinateDirection(m)
    filter.Update()
    reoriented = filter.GetOutput()
    return reoriented
Beispiel #3
0
def sitk_to_itk(sitk_image):
    """
    Helper function to convert SimpleITK images to ITK images
    """
    sitk_arr = sitk.GetArrayFromImage(sitk_image)

    itk_image = itk.GetImageFromArray(sitk_arr, is_vector=False)
    itk_image.SetOrigin(sitk_image.GetOrigin())
    itk_image.SetSpacing(sitk_image.GetSpacing())
    itk_image.SetDirection(
        itk.GetMatrixFromArray(
            np.reshape(np.array(sitk_image.GetDirection()), [3] * 2)))

    return itk_image
Beispiel #4
0
    def create_backend_obj(
        cls,
        data_array: NdarrayOrTensor,
        channel_dim: Optional[int] = 0,
        affine: Optional[NdarrayOrTensor] = None,
        dtype: DtypeLike = np.float32,
        affine_lps_to_ras: bool = True,
        **kwargs,
    ):
        """
        Create an ITK object from ``data_array``. This method assumes a 'channel-last' ``data_array``.

        Args:
            data_array: input data array.
            channel_dim: channel dimension of the data array. This is used to create a Vector Image if it is not ``None``.
            affine: affine matrix of the data array. This is used to compute `spacing`, `direction` and `origin`.
            dtype: output data type.
            affine_lps_to_ras: whether to convert the affine matrix from "LPS" to "RAS". Defaults to ``True``.
                Set to ``True`` to be consistent with ``NibabelWriter``,
                otherwise the affine matrix is assumed already in the ITK convention.
            kwargs: keyword arguments. Current `itk.GetImageFromArray` will read ``ttype`` from this dictionary.

        see also:

            - https://github.com/InsightSoftwareConsortium/ITK/blob/v5.2.1/Wrapping/Generators/Python/itk/support/extras.py#L389
        """
        data_array = super().create_backend_obj(data_array)
        _is_vec = channel_dim is not None
        if _is_vec:
            data_array = np.moveaxis(data_array, -1,
                                     0)  # from channel last to channel first
        data_array = data_array.T.astype(dtype, copy=True, order="C")
        itk_obj = itk.GetImageFromArray(data_array,
                                        is_vector=_is_vec,
                                        ttype=kwargs.pop("ttype", None))

        d = len(itk.size(itk_obj))
        if affine is None:
            affine = np.eye(d + 1, dtype=np.float64)
        _affine = convert_data_type(affine, np.ndarray)[0]
        if affine_lps_to_ras:
            _affine = orientation_ras_lps(to_affine_nd(d, _affine))
        spacing = affine_to_spacing(_affine, r=d)
        _direction: np.ndarray = np.diag(1 / spacing)
        _direction = _affine[:d, :d] @ _direction
        itk_obj.SetSpacing(spacing.tolist())
        itk_obj.SetOrigin(_affine[:d, -1].tolist())
        itk_obj.SetDirection(itk.GetMatrixFromArray(_direction))
        return itk_obj
def process_image(filename, output_folder, sigma):
    basename = os.path.basename(filename)
    basename_wo_ext = basename[:basename.find('.nii.gz')]
    print(basename_wo_ext)
    ImageType = itk.Image[itk.SS, 3]
    reader = itk.ImageFileReader[ImageType].New()
    reader.SetFileName(filename)
    image = reader.GetOutput()
    reoriented = reorient_to_rai(image)
    smoothed = smooth(reoriented, sigma)
    clamped = clamp(smoothed)
    clamped.SetOrigin([0, 0, 0])
    m = itk.GetMatrixFromArray(
        np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]], np.float64))
    clamped.SetDirection(m)
    clamped.Update()
    itk.imwrite(clamped,
                os.path.join(output_folder, basename_wo_ext + '.nii.gz'))
Beispiel #6
0
assert m1.get(0, 0) == m_np[0, 0]
m_np[0, 0] = 0
assert m1.get(0, 0) != m_np[0, 0]
view = itk.GetArrayViewFromVnlMatrix(m1)
assert m1.get(0, 0) == view[0, 0]
view[0, 0] = 0
assert m1.get(0, 0) == view[0, 0]
arr = np.zeros([3, 3])
m_vnl = itk.GetVnlMatrixFromArray(arr)
assert m_vnl(0, 0) == 0
m_vnl.put(0, 0, 3)
assert m_vnl(0, 0) == 3
assert arr[0, 0] == 0
# ITK Matrix
arr = np.zeros([3, 3], float)
m_itk = itk.GetMatrixFromArray(arr)
# Test snake case function
m_itk = itk.matrix_from_array(arr)
m_itk.SetIdentity()
# Test that the numpy array has not changed,...
assert arr[0, 0] == 0
# but that the ITK matrix has the correct value.
assert m_itk(0, 0) == 1
arr2 = itk.GetArrayFromMatrix(m_itk)
# Check that snake case function also works
arr2 = itk.array_from_matrix(m_itk)
# Check that the new array has the new value.
assert arr2[0, 0] == 1
arr2[0, 0] = 2
# Change the array value,...
assert arr2[0, 0] == 2
    image_folder = '/home/gdp/data/spine_large/VerSeg_complete/VerSeg/image'
    output_folder = '/home/gdp/data/spine_large/VerSeg_complete/VerSeg/image_reorient'

    if not os.path.exists(output_folder):
        os.makedirs(output_folder)
    filenames = glob(os.path.join(image_folder, '*.nii.gz'))
    for filename in sorted(filenames):
        # filename = '/home/D/glo/Data/spine_seg_data/VerSe2020/training_data/segmentation/verse503_seg.nii.gz'
        basename = os.path.basename(filename)
        basename_wo_ext = basename[:basename.find('.nii.gz')]
        out_file_name = os.path.join(output_folder, basename_wo_ext + '.nii.gz')
        print(basename_wo_ext)
        # # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~reorient
        image = itk.imread(os.path.join(image_folder,  basename_wo_ext + '.nii.gz'))
        reoriented = reorient_to_rai(image)
        m = itk.GetMatrixFromArray(np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]], np.float64))
        reoriented.SetDirection(m)
        reoriented.Update()
        itk.imwrite(reoriented, out_file_name)
        print('done')

        # # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ resample
        # image = sitk.ReadImage(out_file_name)
        # resampled = resample(image, out_spacing=(1, 1, 1), is_label=True)
        # resampled = sitk.GetArrayFromImage(resampled)
        # resampled[resampled<0] = 0
        # resampled = sitk.GetImageFromArray(resampled)
        # resampled.SetOrigin([0, 0, 0])
        # resampled.SetSpacing((1, 1, 1))
        # sitk.WriteImage(resampled, out_file_name)
        print()
    def compute(self, transform_parameters):


        """Generates a DRR given the transform parameters.

           Args:
               transform_parameters (list of floats): rotX, rotY,rotZ, transX, transY, transZ
 
        """

        # Get transform parameters
        rotx = transform_parameters[0]
        roty = transform_parameters[1]
        rotz = transform_parameters[2]
        tx = transform_parameters[3]
        ty = transform_parameters[4]
        tz = transform_parameters[5]

        # position movement
        
        # compute the transformation matrix and its inverse (itk always needs the inverse)
        Tr = rm.get_rigid_motion_mat_from_euler(rotz, 'z', rotx, 'x', roty, 'y', 0, 0, 0)
        
        self.movDirectionMatrix = itk.GetArrayFromMatrix(self.movDirection)
        self.movDirectionMatrix = Tr[:3,:3]
        self.movDirection = itk.GetMatrixFromArray(self.movDirectionMatrix)
        self.movDirectionMatrix01 = itk.GetArrayFromMatrix(self.movDirection)

        #tDRR1 = time.time()
        DRR = self.DRR
        movImageInfo = self.movImageInfo
        projector_info = self.projector_info
        PhyImageType = self.PhyImageType

        self.DRRorigin = itk.Point[itk.F, self.Dimension]()
        self.DRRorigin[0] = movImageInfo['Volume_center'][0] - projector_info['DRR_ppx'] - self.DRRspacing[0]*(self.DRRsize[0] - 1.) / 2. + tx
        self.DRRorigin[1] = movImageInfo['Volume_center'][1] + projector_info['focal_lenght'] + ty  #/ 2.
        self.DRRorigin[2] = movImageInfo['Volume_center'][2] - projector_info['DRR_ppy'] - self.DRRspacing[2]*(self.DRRsize[2] - 1.) / 2. + tz

        DRR.SetRegions(self.DRRregion)
        DRR.Allocate()
        DRR.SetSpacing(self.DRRspacing)
        DRR.SetOrigin(self.DRRorigin)
        #print(self.movDirection)
        DRR.SetDirection(self.movDirection)

        # Get array of physical coordinates for the DRR at the initial position 
        PhysicalPointImagefilter=itk.PhysicalPointImageSource[PhyImageType].New()
        PhysicalPointImagefilter.SetReferenceImage(DRR)
        PhysicalPointImagefilter.SetUseReferenceImage(True)
        PhysicalPointImagefilter.Update()
        sourceDRR = PhysicalPointImagefilter.GetOutput()

        #self.sourceDRR_array_to_reshape = itk.PyBuffer[PhyImageType].GetArrayFromImage(sourceDRR)[0].copy(order = 'C') # array has to be reshaped for matrix multiplication
        self.sourceDRR_array_to_reshape = itk.GetArrayFromImage(sourceDRR)#[:,0] # array has to be reshaped for matrix multiplication



        # compute the transformation matrix and its inverse (itk always needs the inverse)
        Tr = rm.get_rigid_motion_mat_from_euler(0, 'z', 0, 'x', 0, 'y', 0, projector_info['focal_lenght'], 0)
        invT = np.linalg.inv(Tr) # very important conversion to float32, otherwise the code crashes


        # Move source point with transformation matrix
        source_transformed = np.dot(invT, np.array([self.source[0],self.source[1],self.source[2], 1.]).T)[0:3]
        source_forGpu = np.array([ source_transformed[0], source_transformed[1], source_transformed[2] ], dtype=np.float32)
        
        # Instantiate new 3D DRR image at its initial position (at +focal length along the z direction)
        newDRR = self.ImageType.New()
        newMask = self.MaskType.New()
        newLung = self.MaskType.New()
        newValue = self.MaskType.New()

        newDRR.SetRegions(self.DRRregion)
        newMask.SetRegions(self.DRRregion)
        newLung.SetRegions(self.DRRregion)
        newValue.SetRegions(self.DRRregion)

        newDRR.Allocate()
        newMask.Allocate()
        newLung.Allocate()
        newValue.Allocate()

        newDRR.SetSpacing(self.DRRspacing)
        newMask.SetSpacing(self.DRRspacing)
        newLung.SetSpacing(self.DRRspacing)
        newValue.SetSpacing(self.DRRspacing)

        newDRR.SetOrigin(self.DRRorigin)
        newMask.SetOrigin(self.DRRorigin)
        newLung.SetOrigin(self.DRRorigin)
        newValue.SetOrigin(self.DRRorigin)

        self.movDirection.SetIdentity()
        newDRR.SetDirection(self.movDirection)
        newMask.SetDirection(self.movDirection)
        newLung.SetDirection(self.movDirection)
        newValue.SetDirection(self.movDirection)

        # Get 3d array for DRR (where to store the final output, in the image plane that in fact does not move)
        #newDRRArray = itk.PyBuffer[self.ImageType].GetArrayFromImage(newDRR)
        newDRRArray = itk.GetArrayViewFromImage(newDRR)
        newMaskArray = itk.GetArrayViewFromImage(newMask)
        newLungArray = itk.GetArrayViewFromImage(newLung)
        newValueArray = itk.GetArrayViewFromImage(newValue)

        #tDRR3 = time.time()

        # Get array of physical coordinates of the transformed DRR
        sourceDRR_array_reshaped = self.sourceDRR_array_to_reshape.reshape((self.DRRsize[0]*self.DRRsize[2], self.Dimension), order = 'C')

        sourceDRR_array_transformed = np.dot(invT, rm.augment_matrix_coord(sourceDRR_array_reshaped))[0:3].T # apply inverse transform to detector plane, augmentation is needed for multiplication with rigid motion matrix

        sourceDRR_array_transf_to_ravel = sourceDRR_array_transformed.reshape((self.DRRsize[0],self.DRRsize[2], self.Dimension), order = 'C')


        DRRPhy_array = np.ravel(sourceDRR_array_transf_to_ravel, order = 'C').astype(np.float32)

        # Generate DRR
        #tGpu3 = time.time()

        output, output_mask, output_mask_lung, output_mask_value = self.projector.generateDRR(source_forGpu,DRRPhy_array)
        #tGpu4 = time.time()

        # Reshape copy
        output_reshaped = np.reshape(output, (self.DRRsize[2], self.DRRsize[1], self.DRRsize[0]), order='C') # no guarantee about memory contiguity
        output_mask_reshaped = np.reshape(output_mask, (self.DRRsize[2], self.DRRsize[1], self.DRRsize[0]), order='C')
        
        output_mask_lung_reshaped = np.reshape(output_mask_lung, (self.DRRsize[2], self.DRRsize[1], self.DRRsize[0]), order='C') # no guarantee about memory contiguity
        output_mask_value_reshaped = np.reshape(output_mask_value, (self.DRRsize[2], self.DRRsize[1], self.DRRsize[0]), order='C')
                
        #output_reshaped = np.reshape(output, (self.DRRsize[2], self.DRRsize[0]), order='C') # no guarantee about memory contiguity

        # Re-copy into original image array, hence into original image (since the former is just a view of the latter)
        newDRRArray.setfield(output_reshaped, newDRRArray.dtype)
        newMaskArray.setfield(output_mask_reshaped, newMaskArray.dtype)
        newLungArray.setfield(output_mask_lung_reshaped, newLungArray.dtype)
        newValueArray.setfield(output_mask_value_reshaped, newValueArray.dtype)

        # Redim filter to convert the DRR from 3D slice to 2D image (necessary for further metric comparison)
        filterRedim = itk.ExtractImageFilter[self.ImageType, self.ImageType2D].New()
        filterRedim.InPlaceOn()
        filterRedim.SetDirectionCollapseToSubmatrix()

        filterRedim_mask = itk.ExtractImageFilter[self.MaskType, self.MaskType2D].New()
        filterRedim_mask.InPlaceOn()
        filterRedim_mask.SetDirectionCollapseToSubmatrix()

        filterRedim_lung = itk.ExtractImageFilter[self.MaskType, self.MaskType2D].New()
        filterRedim_lung.InPlaceOn()
        filterRedim_lung.SetDirectionCollapseToSubmatrix()

        filterRedim_value = itk.ExtractImageFilter[self.MaskType, self.MaskType2D].New()
        filterRedim_value.InPlaceOn()
        filterRedim_value.SetDirectionCollapseToSubmatrix()

        newDRR.UpdateOutputInformation() # important, otherwise the following filterRayCast.GetOutput().GetLargestPossibleRegion() returns an empty image
        newMask.UpdateOutputInformation()
        newLung.UpdateOutputInformation()
        newValue.UpdateOutputInformation()

        size_input = newDRR.GetLargestPossibleRegion().GetSize()
        start_input = newDRR.GetLargestPossibleRegion().GetIndex()

        size_output = [0]*self.Dimension
        size_output[0] = size_input[0]
        size_output[1] = 0
        size_output[2] = size_input[2]

        sliceNumber = 0
        start_output = [0]*self.Dimension
        start_output[0] = start_input[0]
        start_output[1] = sliceNumber
        start_output[2] = start_input[2]

        desiredRegion = self.RegionType()
        desiredRegion.SetSize( size_output )
        desiredRegion.SetIndex( start_output )

        filterRedim.SetExtractionRegion( desiredRegion )
        filterRedim_mask.SetExtractionRegion( desiredRegion )
        filterRedim_lung.SetExtractionRegion( desiredRegion )
        filterRedim_value.SetExtractionRegion( desiredRegion )

        filterRedim.SetInput(newDRR)
        filterRedim_mask.SetInput(newMask)
        filterRedim_lung.SetInput(newLung)
        filterRedim_value.SetInput(newValue)


        #tDRR2 = time.time()

        filterRedim.Update()
        filterRedim_mask.Update()
        filterRedim_lung.Update()
        filterRedim_value.Update()

        #print( '\nTime elapsed for generation of DRR: ', tDRR2 - tDRR1)

        return filterRedim.GetOutput(), filterRedim_mask.GetOutput(), filterRedim_lung.GetOutput(), filterRedim_value.GetOutput()