def example_parallel_2d(): # ------------------ Declare Parameters ------------------ # Volume Parameters: volume_size = 64 volume_shape = [volume_size, volume_size] volume_spacing = [1, 1] # Detector Parameters: detector_shape = 100 detector_spacing = 1 # Trajectory Parameters: number_of_projections = 90 angular_range = 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).astype(np.float32) # Add required batch dimension phantom = np.expand_dims(phantom, axis=0) sino = parallel_projection2d(phantom,geometry) @tf.function def test_func_proj(x): return parallel_projection2d(x,geometry) @tf.function def test_func_reco(x): return parallel_backprojection2d(x,geometry) proj_theoretical, proj_numerical = tf.test.compute_gradient(test_func_proj, [sino]) reco_theoretical, reco_numerical = tf.test.compute_gradient(test_func_reco, [sino])
def example_fan_2d_shortscan(): # Volume Parameters: volume_size = 256 volume_shape = [volume_size, volume_size] volume_spacing = [1, 1] # Detector Parameters: detector_shape = 500 detector_spacing = 1 # Trajectory Parameters: number_of_projections = 250 angular_range = None # will get set to pi + 2 * fan_angle source_detector_distance = 1200 source_isocenter_distance = 750 # Create Geometry class geometry = GeometryFan2D(volume_shape, volume_spacing, detector_shape, detector_spacing, number_of_projections, angular_range, source_detector_distance, source_isocenter_distance) geometry.angular_range = np.pi + 2 * geometry.fan_angle # fan_angle gets defined by sdd and detector_shape geometry.set_trajectory(circular_trajectory_2d(geometry)) # Create Phantom phantom = shepp_logan_enhanced(volume_shape) # Add required batch dimension phantom = np.expand_dims(phantom, axis=0) # Build up Reconstruction Pipeline # Create Sinogram of Phantom sinogram = fan_projection2d(phantom, geometry) # Redundancy Weighting: Create Weights Image and pointwise multiply redundancy_weights = weights.parker_weights_2d(geometry) sinogram_redun_weighted = sinogram * redundancy_weights # Filtering: Create 2D Filter and pointwise multiply reco_filter = filters.ram_lak_2D(geometry) sino_freq = tf.signal.fft( tf.cast(sinogram_redun_weighted, 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)) # Final Backprojection reco = fan_backprojection2d(sinogram_filtered, geometry) plt.figure() plt.imshow(np.squeeze(reco), cmap=plt.get_cmap('gist_gray')) plt.axis('off') plt.savefig('2d_fan_short_scan_reco.png', dpi=150, transparent=False, bbox_inches='tight')
def example_fan_2d_shortscan(): # Volume Parameters: volume_size = 256 volume_shape = [volume_size, volume_size] volume_spacing = [1,1] # Detector Parameters: detector_shape = 500 detector_spacing = 1 # Trajectory Parameters: number_of_projections = 250 angular_range = None # will get set to pi + 2 * fan_angle source_detector_distance = 1200 source_isocenter_distance = 750 # Create Geometry class geometry = GeometryFan2D(volume_shape, volume_spacing, detector_shape, detector_spacing, number_of_projections, angular_range, source_detector_distance, source_isocenter_distance) geometry.angular_range = np.pi + 2*geometry.fan_angle # fan_angle gets defined by sdd and detector_shape geometry.central_ray_vectors = circular_trajectory_2d(geometry) # Create Phantom phantom = shepp_logan_enhanced(volume_shape) phantom = np.expand_dims(phantom,axis=0) # Build up Reconstruction Pipeline with tf.Session() as sess: # Create Sinogram of Phantom result = fan_projection2d(phantom, geometry) sinogram = result.eval() # Redundancy Weighting: Create Weights Image and pointwise multiply redundancy_weights = weights.parker_weights_2d(geometry) sinogram_redun_weighted = sinogram * redundancy_weights # Filtering: Create 2D Filter and pointwise multiply the_filter = filters.ram_lak_2D(geometry) sino_fft = np.fft.fft(sinogram_redun_weighted, axis=-1) sino_filtered_fft = np.multiply(sino_fft, the_filter) sinogram_filtered = np.fft.ifft(sino_filtered_fft, axis=-1) # Final Backprojection result_back_proj = fan_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_fan_short_scan_reco.png', dpi=150, transparent=False, bbox_inches='tight')
def example_fan_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 source_detector_distance = 1200 source_isocenter_distance = 750 # create Geometry class geometry = GeometryFan2D(volume_shape, volume_spacing, detector_shape, detector_spacing, number_of_projections, angular_range, source_detector_distance, source_isocenter_distance) geometry.set_central_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 = fan_projection2d(phantom, geometry) sinogram = result.eval() #TODO: Add Cosine weighting #TODO: Add redundancy weighting for 360 degree reco_filter = filters.ramp_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 = fan_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_fan_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_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 iterative_reconstruction(): # ------------------ Declare Parameters ------------------ parser = argparse.ArgumentParser(description='') parser.add_argument('--lr', dest='learning_rate', type=float, default=1e-2, help='initial learning rate for adam') parser.add_argument('--epoch', dest='num_epochs', type=int, default=1000000, help='# of epoch') args = parser.parse_args() # Volume Parameters: volume_size = 512 volume_shape = [volume_size, volume_size] volume_spacing = [0.5, 0.5] # Detector Parameters: detector_shape = 625 detector_spacing = 0.5 # Trajectory Parameters: number_of_projections = 30 angular_range = np.radians(200) # 200 * np.pi / 180 # 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)) phantom = shepp_logan.shepp_logan_enhanced(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: acquired_sinogram = generate_sinogram(phantom,projection_2d.parallel_projection2d,geometry) acquired_sinogram = acquired_sinogram + np.random.normal( loc=np.mean(np.abs(acquired_sinogram)), scale=np.std(acquired_sinogram), size=acquired_sinogram.shape) * 0.02 zero_vector = np.zeros(np.shape(phantom), dtype=np.float32) iter_pipeline = pipeline(sess, args, geometry) iter_pipeline.train(zero_vector,np.asarray(acquired_sinogram)) plt.figure() plt.imshow(iter_pipeline.result[0], cmap=plt.get_cmap('gist_gray')) plt.axis('off') plt.savefig('iter_tv_reco.png', dpi=150, transparent=False, bbox_inches='tight')
def create_parallel_geometry(det_count, num_angles): # Detector Parameters: detector_shape = det_count detector_spacing = 1 # Trajectory Parameters: number_of_projections = num_angles angular_range = 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)) return geometry
def example_fan_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 source_detector_distance = 1200 source_isocenter_distance = 750 # create Geometry class geometry = GeometryFan2D(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_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 = fan_projection2d(phantom, geometry) #TODO: Add Cosine weighting #TODO: Add redundancy weighting for 360 degree reco_filter = filters.ramp_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 = fan_backprojection2d(sinogram_filtered, geometry) plt.figure() plt.imshow(np.squeeze(reco), cmap=plt.get_cmap('gist_gray')) plt.axis('off') plt.savefig('2d_fan_reco.png', dpi=150, transparent=False, bbox_inches='tight')
def create_fanbeam_geometry(det_count, num_angles, source_dist, det_dist): # Detector Parameters: detector_shape = det_count detector_spacing = 1 # Trajectory Parameters: number_of_projections = num_angles angular_range = np.pi source_detector_distance = source_dist + det_dist # create Geometry class geometry = GeometryFan2D(volume_shape, volume_spacing, detector_shape, detector_spacing, number_of_projections, angular_range, source_detector_distance, source_dist) geometry.set_trajectory( circular_trajectory.circular_trajectory_2d(geometry)) return geometry
def get_pyronn_geometry(radon_geometry: RadonGeometry): # Volume Parameters: volume_size = radon_geometry.volume_img_width volume_shape = [volume_size, volume_size] volume_spacing = [1, 1] # Detector Parameters: detector_shape = radon_geometry.projection_width detector_spacing = 1 # Trajectory Parameters: number_of_projections = radon_geometry.nr_projections angular_range = np.radians(180.) # create Geometry class pyronn_geometry = GeometryParallel2D(volume_shape, volume_spacing, detector_shape, detector_spacing, number_of_projections, angular_range) pyronn_geometry.set_trajectory( circular_trajectory.circular_trajectory_2d(pyronn_geometry)) return pyronn_geometry
current_time = datetime.datetime.now().strftime("%Y%m%d-%H%M%S") train_gen_log_dir = './logs/gradient_tape/' + current_time + '/generator_train' train_dis_log_dir = './logs/gradient_tape/' + current_time + '/discriminator_train' train_gen_summary_writer = tf.summary.create_file_writer(train_gen_log_dir) train_dis_summary_writer = tf.summary.create_file_writer(train_dis_log_dir) geometry_inpainted = GeometryParallel2D(volume_shape, volume_spacing, detector_shape, detector_spacing, number_of_projections_inpainted, angular_range_inpainted) geometry_inpainted.set_trajectory( circular_trajectory.circular_trajectory_2d(geometry_inpainted)) dataset_paths = [x[2] for x in os.walk('./train_dataset')] dataset_paths = [args.tfolder + s for s in dataset_paths[0]] current_it = 0 for epoch in range(number_epochs): for dataset_path in dataset_paths: #Get and prepare training array X = prepare_training_array(dataset_path, img_size) for idx in range(X.shape[0]): if idx == 0: inpainted_sinogram_0 = parallel_projection2d( np.expand_dims(X[0], 0), geometry_inpainted) else:
# # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import numpy as np from pyronn.ct_reconstruction.geometry.geometry_parallel_2d import GeometryParallel2D from pyronn.ct_reconstruction.helpers.trajectories import circular_trajectory """ This file defines the Geometry parameters used by the whole model. A GeometryParallel2D instance is provided to be used by everyone that needs it. """ # Declare Parameters volume_shape = [256, 256] volume_spacing = [1 , 1] detector_shape = 400 detector_spacing = 1 number_of_projections = 180 angular_range = np.pi # Create Geometry class instance GEOMETRY = GeometryParallel2D(volume_shape, volume_spacing, detector_shape, detector_spacing, number_of_projections, angular_range) GEOMETRY.set_trajectory(circular_trajectory.circular_trajectory_2d(GEOMETRY))
# # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import numpy as np from pyronn.ct_reconstruction.geometry.geometry_parallel_2d import GeometryParallel2D from pyronn.ct_reconstruction.helpers.trajectories import circular_trajectory """ This file defines the Geometry parameters used by the hole model. A GeometryParallel2D instance is provided to be used by everyone that needs it. """ # Declare Parameters volume_shape = [256, 256] volume_spacing = [0.5, 0.5] detector_shape = 365 detector_spacing = 0.5 number_of_projections = 720 angular_range = 2 * np.pi # Create Geometry class instance 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))
def iterative_reconstruction(): # ------------------ Declare Parameters ------------------ parser = argparse.ArgumentParser(description='') parser.add_argument('--lr', dest='learning_rate', type=float, default=1e-2, help='initial learning rate for adam') parser.add_argument('--epoch', dest='num_epochs', type=int, default=100000, help='# of epoch') args = parser.parse_args() # Volume Parameters: volume_size = 256 volume_shape = [volume_size - 1, volume_size] #, volume_size+1] volume_spacing = [1, 1] #, 1] # Detector Parameters: detector_shape = [375] #, 375] detector_spacing = [1] #,1] # Trajectory Parameters: number_of_projections = 30 angular_range = np.radians(200) # 200 * np.pi / 180 # create Geometry class geometry = GeometryParallel2D(volume_shape, volume_spacing, detector_shape, detector_spacing, number_of_projections, angular_range) #, 1200.0, 750.0 ) matrices = circular_trajectory.circular_trajectory_2d(geometry) geometry.set_trajectory(matrices) phantom = shepp_logan.shepp_logan_enhanced(volume_shape).astype( dtype=np.float32) # Add required batch dimension phantom = np.expand_dims(phantom, axis=0) # ------------------ Call Layers ------------------ acquired_sinogram = generate_sinogram(phantom, projection_2d.parallel_projection2d, geometry) # acquired_sinogram = acquired_sinogram + np.random.normal( # loc=np.mean(np.abs(acquired_sinogram)), scale=np.std(acquired_sinogram), size=acquired_sinogram.shape) * 0.02 zero_vector = np.zeros(np.shape(phantom), dtype=np.float32) iter_pipeline = pipeline(args, geometry) iter_pipeline.train(zero_vector, np.asarray(acquired_sinogram)) plt.figure() plt.imshow(np.squeeze(iter_pipeline.result), cmap=plt.get_cmap('gist_gray')) plt.axis('off') plt.savefig('iter_tv_reco.png', dpi=150, transparent=False, bbox_inches='tight')
train_gen_log_dir = './logs/gradient_tape/' + current_time + '/generator_train' train_dis_log_dir = './logs/gradient_tape/' + current_time + '/discriminator_train' if os.path.isdir('./logs/gradient_tape/'): shutil.rmtree('./logs/gradient_tape/') train_gen_summary_writer = tf.summary.create_file_writer(train_gen_log_dir) train_dis_summary_writer = tf.summary.create_file_writer(train_dis_log_dir) ##Workable 2D, input 1 slice geometry = GeometryParallel2D(volume_shape, volume_spacing, detector_shape, detector_spacing, number_of_projections, angular_range) geometry.set_trajectory(circular_trajectory.circular_trajectory_2d(geometry)) geometry_inpainted = GeometryParallel2D(volume_shape, volume_spacing, detector_shape, detector_spacing, number_of_projections_inpainted, angular_range_inpainted) geometry_inpainted.set_trajectory( circular_trajectory.circular_trajectory_2d(geometry_inpainted)) reco_filter = filters.ram_lak_2D(geometry) epoch = 0 for dataset_path in [ args.recon, ]: #['./test_dataset/series_5-area_0_SIRT30i_2n.h5', ]:# ['./test_dataset/20170710.h5', ] #['./test_dataset/clean4test.h5', ] ['./test_dataset/phantom_00016_recon.h5', ] ['./dataset/TIQ.h5', ]