def model(self, sinogram):
        """
        main model for the FDK algorithm

        Parameters
        ----------
        sinogram : ndarray
            The projection data used for reconstruction

        Returns
        -------
        ndarray
            the reconstructed CT data
        """

        sinogram_cos = tf.multiply(sinogram, self.cosine_weight)

        weighted_sino_fft = tf.fft(tf.cast(sinogram_cos, dtype=tf.complex64))
        filtered_sinogram_fft = tf.multiply(
            weighted_sino_fft, tf.cast(self.filter, dtype=tf.complex64))
        filtered_sinogram = tf.real(tf.ifft(filtered_sinogram_fft))

        reconstruction = cone_backprojection3d(filtered_sinogram,
                                               self.geometry,
                                               hardware_interp=True)

        return reconstruction
Esempio n. 2
0
def example_cone_3d():
    # ------------------ Declare Parameters ------------------

    # Volume Parameters:
    volume_size = 256
    volume_shape = [volume_size, volume_size, volume_size]
    volume_spacing = [0.5, 0.5, 0.5]

    # Detector Parameters:
    detector_shape = [2*volume_size, 2*volume_size]
    detector_spacing = [1, 1]

    # Trajectory Parameters:
    number_of_projections = 360
    angular_range = 2 * np.pi

    source_detector_distance = 1200
    source_isocenter_distance = 750

    # create Geometry class
    geometry = GeometryCone3D(volume_shape, volume_spacing, detector_shape, detector_spacing, number_of_projections, angular_range, source_detector_distance, source_isocenter_distance)
    geometry.set_trajectory(circular_trajectory.circular_trajectory_3d(geometry))

    # Get Phantom 3d
    phantom = shepp_logan.shepp_logan_3d(volume_shape)
    # Add required batch dimension
    phantom = np.expand_dims(phantom, axis=0)

    # ------------------ Call Layers ------------------
    # The following code is the new TF2.0 experimental way to tell
    # Tensorflow only to allocate GPU memory needed rather then allocate every GPU memory available.
    # This is important for the use of the hardware interpolation projector, otherwise there might be not enough memory left
    # to allocate the texture memory on the GPU

    gpus = tf.config.experimental.list_physical_devices('GPU')
    if gpus:
        try:
            for gpu in gpus:
                tf.config.experimental.set_memory_growth(gpu, True)
        except RunetimeError as e:
            print(e)

    sinogram = cone_projection3d(phantom, geometry)

    reco_filter = ram_lak_3D(geometry)
    sino_freq = tf.signal.fft(tf.cast(sinogram,dtype=tf.complex64))
    sino_filtered_freq = tf.multiply(sino_freq,tf.cast(reco_filter,dtype=tf.complex64))
    sinogram_filtered = tf.math.real(tf.signal.ifft(sino_filtered_freq))

    reco = cone_backprojection3d(sinogram_filtered, geometry)

    plt.figure()
    plt.imshow(np.squeeze(reco)[volume_shape[0]//2], cmap=plt.get_cmap('gist_gray'))
    plt.axis('off')
    plt.savefig('3d_cone_reco.png', dpi=150, transparent=False, bbox_inches='tight')
Esempio n. 3
0
def example_cone_3d():
    # ------------------ Declare Parameters ------------------

    # Volume Parameters:
    volume_size = 256
    volume_shape = [volume_size, volume_size, volume_size]
    volume_spacing = [0.5, 0.5, 0.5]

    # Detector Parameters:
    detector_shape = [2 * volume_size, 2 * volume_size]
    detector_spacing = [1, 1]

    # Trajectory Parameters:
    number_of_projections = 360
    angular_range = 2 * np.pi

    source_detector_distance = 1200
    source_isocenter_distance = 750

    # create Geometry class
    geometry = GeometryCone3D(volume_shape, volume_spacing, detector_shape,
                              detector_spacing, number_of_projections,
                              angular_range, source_detector_distance,
                              source_isocenter_distance)
    geometry.set_projection_matrices(
        circular_trajectory.circular_trajectory_3d(geometry))

    # Get Phantom 3d
    phantom = shepp_logan.shepp_logan_3d(volume_shape)
    phantom = np.expand_dims(phantom, axis=0)

    config = tf.ConfigProto()
    config.gpu_options.per_process_gpu_memory_fraction = 0.5
    config.gpu_options.allow_growth = True
    # ------------------ Call Layers ------------------
    with tf.Session(config=config) as sess:
        result = cone_projection3d(phantom, geometry)
        sinogram = result.eval()

        filter = ram_lak_3D(geometry)
        sino_freq = np.fft.fft(sinogram, axis=-1)
        filtered_sino_freq = sino_freq * filter
        filtered_sino = np.fft.ifft(filtered_sino_freq, axis=-1)

        result_back_proj = cone_backprojection3d(filtered_sino, geometry)
        reco = result_back_proj.eval()
        plt.figure()
        plt.imshow(np.squeeze(reco)[volume_shape[0] // 2],
                   cmap=plt.get_cmap('gist_gray'))
        plt.axis('off')
        plt.savefig('3d_cone_reco.png',
                    dpi=150,
                    transparent=False,
                    bbox_inches='tight')
Esempio n. 4
0
    def model(self, sinogram):
        self.sinogram_cos = tf.multiply(sinogram, self.cosine_weight)
        self.redundancy_weighted_sino = tf.multiply(self.sinogram_cos,
                                                    self.redundancy_weight)

        self.weighted_sino_fft = tf.fft(
            tf.cast(self.redundancy_weighted_sino, dtype=tf.complex64))
        self.filtered_sinogram_fft = tf.multiply(
            self.weighted_sino_fft, tf.cast(self.filter, dtype=tf.complex64))
        self.filtered_sinogram = tf.real(tf.ifft(self.filtered_sinogram_fft))

        self.reconstruction = cone_backprojection3d(self.filtered_sinogram,
                                                    self.geometry,
                                                    hardware_interp=True)

        return self.reconstruction, self.redundancy_weighted_sino
    def forward_recon_domain(self, input, index):
        """
        the reconstruction domain of the model for reconstruction

        Parameters
        ----------
        input : ndarray
            The projection data used for reconstruction

        index : int
            The projection data are from which CT by the identification of the index

        Returns
        -------
        ndarray
            the reconstruted CT images after this model
        """

        self.reconstruction = tf.case({tf.equal(index, 1): lambda: cone_backprojection3d(input, GEO_LIST[0], hardware_interp=False),
                                       tf.equal(index, 2): lambda: cone_backprojection3d(input, GEO_LIST[1], hardware_interp=False),
                                       tf.equal(index, 3): lambda: cone_backprojection3d(input, GEO_LIST[2], hardware_interp=False),
                                       tf.equal(index, 4): lambda: cone_backprojection3d(input, GEO_LIST[3], hardware_interp=False),
                                       tf.equal(index, 5): lambda: cone_backprojection3d(input, GEO_LIST[4], hardware_interp=False),
                                       tf.equal(index, 6): lambda: cone_backprojection3d(input, GEO_LIST[5], hardware_interp=False),
                                       tf.equal(index, 7): lambda: cone_backprojection3d(input, GEO_LIST[6], hardware_interp=False),
                                       tf.equal(index, 8): lambda: cone_backprojection3d(input, GEO_LIST[7], hardware_interp=False),
                                       tf.equal(index, 9): lambda: cone_backprojection3d(input, GEO_LIST[8], hardware_interp=False),
                                       tf.equal(index, 10): lambda: cone_backprojection3d(input, GEO_LIST[9], hardware_interp=False),
                                       tf.equal(index, 11): lambda: cone_backprojection3d(input, GEO_LIST[10], hardware_interp=False),
                                       tf.equal(index, 12): lambda: cone_backprojection3d(input, GEO_LIST[11], hardware_interp=False),
                                       tf.equal(index, 13): lambda: cone_backprojection3d(input, GEO_LIST[12], hardware_interp=False),
                                       tf.equal(index, 14): lambda: cone_backprojection3d(input, GEO_LIST[13], hardware_interp=False),
                                       tf.equal(index, 15): lambda: cone_backprojection3d(input, GEO_LIST[14], hardware_interp=False),
                                       tf.equal(index, 16): lambda: cone_backprojection3d(input, GEO_LIST[15], hardware_interp=False),
                                       tf.equal(index, 17): lambda: cone_backprojection3d(input, GEO_LIST[16], hardware_interp=False),
                                       tf.equal(index, 18): lambda: cone_backprojection3d(input, GEO_LIST[17], hardware_interp=False),
                                       tf.equal(index, 19): lambda: cone_backprojection3d(input, GEO_LIST[18], hardware_interp=False),
                                       tf.equal(index, 20): lambda: cone_backprojection3d(input, GEO_LIST[19], hardware_interp=False)},
                                        default=(lambda:cone_backprojection3d(input, self.geometry, hardware_interp=False)), exclusive=True)

        self.recon_relu = self.para_relu(self.reconstruction)

        # CNN added in the reconstruction domain
        ###########################################################################
        self.recon_relu = tf.expand_dims(self.recon_relu, 3)
        self.recon_relu = self.cnn_model(self.recon_relu)
        self.recon_relu = tf.squeeze(self.recon_relu, axis=3)
        ###########################################################################

        return self.recon_relu
Esempio n. 6
0
 def test_func_reco(x):
     return cone_backprojection3d(x,geometry)
Esempio n. 7
0
def example_cone_3d():
    # ------------------ Declare Parameters ------------------

    # Volume Parameters:
    volume_size = 256
    volume_shape = [volume_size, volume_size, volume_size]
    volume_spacing = [0.5, 0.5, 0.5]

    # Detector Parameters:
    detector_shape = [2 * volume_size, 2 * volume_size]
    detector_spacing = [1, 1]

    # Trajectory Parameters:
    number_of_projections = 360
    angular_range = 2 * np.pi

    source_detector_distance = 1200
    source_isocenter_distance = 750

    # create Geometry class
    geometry = GeometryCone3D(volume_shape, volume_spacing, detector_shape,
                              detector_spacing, number_of_projections,
                              angular_range, source_detector_distance,
                              source_isocenter_distance)
    geometry.set_projection_matrices(
        circular_trajectory.circular_trajectory_3d(geometry))

    # Get Phantom 3d
    phantom = shepp_logan.shepp_logan_3d(volume_shape)

    config = tf.ConfigProto()
    config.gpu_options.per_process_gpu_memory_fraction = 0.5
    config.gpu_options.allow_growth = True
    # ------------------ Call Layers ------------------
    with tf.Session(config=config) as sess:
        result = cone_projection3d(phantom, geometry)
        sinogram = result.eval()

        #TODO: Use 3D ramp / ram_lak not 1D
        # filtering
        filter = ramp(int(geometry.detector_shape[1]))
        sino_freq = np.fft.fft(sinogram, axis=2)
        filtered_sino_freq = np.zeros_like(sino_freq)
        for row in range(int(geometry.detector_shape[0])):
            for projection in range(geometry.number_of_projections):
                filtered_sino_freq[projection,
                                   row, :] = sino_freq[projection,
                                                       row, :] * filter[:]

        filtered_sino = np.fft.ifft(filtered_sino_freq, axis=2)

        result_back_proj = cone_backprojection3d(filtered_sino, geometry)
        reco = result_back_proj.eval()
        plt.figure()
        plt.imshow(reco[(int)(volume_shape[0] / 2), :, :],
                   cmap=plt.get_cmap('gist_gray'))
        plt.axis('off')
        plt.savefig('3d_cone_reco.png',
                    dpi=150,
                    transparent=False,
                    bbox_inches='tight')