def forward(self, sinogram_batch): """ Sets up the network architecture. Args: images_batch: batch input of training data Returns: backprojection_layer: The last layer before the loss layer. """ # FFT layer fft_layer = tf.spectral.fft(tf.cast(sinogram_batch, dtype=tf.complex64)) # Filtering as multiplication layer self.filter_weights = tf.Variable( initial_value=filters.ramp(GEOMETRY.detector_shape[0]), expected_shape=GEOMETRY.detector_shape[0]) # init as ramp filter #filter_weights = tf.Variable(initial_value=tf.random.uniform(GEOMETRY.detector_shape[0]), expected_shape=GEOMETRY.detector_shape[0]) # init as random filter_layer = tf.multiply( fft_layer, tf.cast(self.filter_weights, dtype=tf.complex64)) # IFFT layer ifft_layer = tf.real(tf.spectral.ifft(filter_layer)) # Reconstruction Backprojection layer self.backprojection_layer = tf.nn.relu( parallel_backprojection2d(ifft_layer, GEOMETRY)) return self.backprojection_layer
def bench_parallel_backward(phantom, det_count, num_angles, warmup, repeats): geometry = create_parallel_geometry(det_count, num_angles) sino = parallel_projection2d(phantom, geometry) f = lambda x: parallel_backprojection2d(x, geometry) return benchmark(f, sino, warmup, repeats)
def backproject(self, sinos: TensorLike): sinos_tf = tf.convert_to_tensor(sinos, dtype=tf.float32) # This row is needed if rank of output is not changed in parallel_backprojection2d gradient. sinos_tf = tf.reshape(sinos_tf, shape=tf.shape(sinos_tf)[:3]) recos_3D = parallel_backprojection2d( sinos_tf, self._geometry) # removes channeldimension recos_4D = tf.expand_dims(recos_3D, axis=-1) return recos_4D
def example_parallel_2d(): # ------------------ Declare Parameters ------------------ # Volume Parameters: volume_size = 256 volume_shape = [volume_size, volume_size] volume_spacing = [1, 1] # Detector Parameters: detector_shape = 800 detector_spacing = 1 # Trajectory Parameters: number_of_projections = 360 angular_range = 2 * np.pi # create Geometry class geometry = GeometryParallel2D(volume_shape, volume_spacing, detector_shape, detector_spacing, number_of_projections, angular_range) geometry.set_ray_vectors( circular_trajectory.circular_trajectory_2d(geometry)) # Get Phantom phantom = shepp_logan.shepp_logan_enhanced(volume_shape) phantom = np.expand_dims(phantom, axis=0) # ------------------ Call Layers ------------------ with tf.Session() as sess: result = parallel_projection2d(phantom, geometry) sinogram = result.eval() #sinogram = sinogram + np.random.normal( # loc=np.mean(np.abs(sinogram)), scale=np.std(sinogram), size=sinogram.shape) * 0.02 reco_filter = filters.ram_lak_2D(geometry) sino_freq = np.fft.fft(sinogram, axis=1) sino_filtered_freq = np.multiply(sino_freq, reco_filter) sinogram_filtered = np.fft.ifft(sino_filtered_freq, axis=1) result_back_proj = parallel_backprojection2d(sinogram_filtered, geometry) reco = result_back_proj.eval() plt.figure() plt.imshow(np.squeeze(reco), cmap=plt.get_cmap('gist_gray')) plt.axis('off') plt.savefig('2d_par_reco.png', dpi=150, transparent=False, bbox_inches='tight')
def example_parallel_2d(): # ------------------ Declare Parameters ------------------ # Volume Parameters: volume_size = 256 volume_shape = [volume_size, volume_size] volume_spacing = [1, 1] # Detector Parameters: detector_shape = 800 detector_spacing = 1 # Trajectory Parameters: number_of_projections = 360 angular_range = 2 * np.pi # create Geometry class geometry = GeometryParallel2D(volume_shape, volume_spacing, detector_shape, detector_spacing, number_of_projections, angular_range) geometry.set_trajectory( circular_trajectory.circular_trajectory_2d(geometry)) # Get Phantom phantom = shepp_logan.shepp_logan_enhanced(volume_shape) # Add required batch dimension phantom = np.expand_dims(phantom, axis=0) # ------------------ Call Layers ------------------ sinogram = parallel_projection2d(phantom, geometry) #sinogram = sinogram + np.random.normal( # loc=np.mean(np.abs(sinogram)), scale=np.std(sinogram), size=sinogram.shape) * 0.02 reco_filter = filters.ram_lak_2D(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 = parallel_backprojection2d(sinogram_filtered, geometry) plt.figure() plt.imshow(np.squeeze(reco), cmap=plt.get_cmap('gist_gray')) plt.axis('off') plt.savefig('2d_par_reco.png', dpi=150, transparent=False, bbox_inches='tight')
def call(self, x): """ Sets up the network architecture. Args: images_batch: batch input of training data Returns: backprojection_layer: The last layer before the loss layer. """ sinogram_frequency = tf.signal.fft(tf.cast(x,dtype=tf.complex64)) filtered_sinogram_frequency = tf.multiply(sinogram_frequency, tf.cast(self.filter_weights,dtype=tf.complex64)) filtered_sinogram = tf.math.real(tf.signal.ifft(filtered_sinogram_frequency)) reco = parallel_backprojection2d(filtered_sinogram, GEOMETRY) #tf.nn.relu(reco) return reco
def test_func_reco(x): return parallel_backprojection2d(x,geometry)
def f(x): return parallel_backprojection2d(x, geometry)