def example_cone_3d(): # ------------------ Declare Parameters ------------------ # Volume Parameters: volume_size = 256 volume_shape = [volume_size, volume_size, volume_size] v_spacing = 0.25 volume_spacing = [v_spacing, v_spacing, v_spacing] # Detector Parameters: detector_shape = [450, 450] d_spacing = 0.33 detector_spacing = [d_spacing, d_spacing] # Trajectory Parameters: number_of_projections = 248 angular_range = np.pi + 2 * np.arctan(detector_shape[0] / 2 / 1200) 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.angular_range = np.radians(200) projection_geometry = circular_trajectory.circular_trajectory_3d(geometry) geometry.set_projection_matrices(projection_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: sinogram = generate_sinogram.generate_sinogram(phantom, cone_projection3d, geometry) model = nn_model(geometry) sess.run(tf.global_variables_initializer()) sess.run(tf.local_variables_initializer()) reco_tf, redundancy_weighted_sino_tf = model.model(sinogram) reco, redundancy_weighted_sino = sess.run( [reco_tf, redundancy_weighted_sino_tf]) plt.figure() plt.imshow(reco[(int)(volume_shape[0] / 2), :, :], cmap=plt.get_cmap('gist_gray'), vmin=0, vmax=0.4) plt.axis('off') plt.savefig('fdk_reco.png', dpi=150, transparent=False, bbox_inches='tight')
def example_cone_3d(): # ------------------ Declare Parameters ------------------ # Volume Parameters: volume_size = 256 volume_shape = [volume_size, volume_size, volume_size] v_spacing = 0.25 volume_spacing = [v_spacing, v_spacing, v_spacing] # Detector Parameters: detector_shape = [450, 450] d_spacing = 0.33 detector_spacing = [d_spacing, d_spacing] # Trajectory Parameters: number_of_projections = 248 angular_range = np.pi + 2 * np.arctan(detector_shape[0] / 2 / 1200) 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.angular_range = np.radians(200) projection_geometry = circular_trajectory.circular_trajectory_3d(geometry) geometry.set_trajectory(projection_geometry) # Get Phantom 3d phantom = shepp_logan.shepp_logan_3d(volume_shape) phantom = np.expand_dims(phantom, axis=0) # 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) # ------------------ Call Layers ------------------ sinogram = generate_sinogram.generate_sinogram(phantom, cone_projection3d, geometry) model = nn_model(geometry) reco, redundancy_weighted_sino = model.model(sinogram) plt.figure() plt.imshow(np.squeeze(reco)[volume_shape[0] // 2], cmap=plt.get_cmap('gist_gray'), vmin=0, vmax=0.4) plt.axis('off') plt.savefig('fdk_reco.png', dpi=150, transparent=False, bbox_inches='tight')
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')
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')
def forward_projections(): """ main procedures for cone-beam forward projection """ phantoms_dir = 'normalized_ct_phantoms/' num_phantoms = len(os.listdir(phantoms_dir)) config = tf.ConfigProto() config.gpu_options.per_process_gpu_memory_fraction = 0.8 config.gpu_options.allow_growth = True # ------------------ Call Layers ------------------ with tf.Session(config=config): for n in range(num_phantoms): phantom_file = phantoms_dir + 'phantom_' + str(n + 1) + '.npy' phantom = np.load(phantom_file) # Volume Parameters: volume_shape = [ phantom.shape[0], phantom.shape[1], phantom.shape[2] ] volume_spacing = NORMALIZATION_VOLUME_SPACING # Detector Parameters: detector_shape = PROJECTION_PARA['detector_shape'] detector_spacing = PROJECTION_PARA['detector_spacing'] # Trajectory Parameters: number_of_projections = PROJECTION_PARA['number_of_projections'] angular_range = PROJECTION_PARA['angular_range'] source_detector_distance = PROJECTION_PARA[ 'source_detector_distance'] source_isocenter_distance = PROJECTION_PARA[ 'source_isocenter_distance'] # create Geometry class geometry = GeometryCone3D(volume_shape, volume_spacing, detector_shape, detector_spacing, number_of_projections, angular_range, source_detector_distance, source_isocenter_distance) projection_geometry = circular_trajectory.circular_trajectory_3d( geometry) geometry.set_projection_matrices(projection_geometry) # generate projection sinogram sinogram = generate_sinogram.generate_sinogram( phantom, cone_projection3d, geometry) np.save('sinograms/sinogram_' + str(n + 1), sinogram) print('Sinogram ' + str(n + 1) + ' generated!')
def example_cone_3d(): # ------------------ Declare Parameters ------------------ # Volume Parameters: volume_size = 8 volume_shape = [volume_size, volume_size, volume_size] volume_spacing = [1, 1, 1] # Detector Parameters: detector_shape = [12, 12] detector_spacing = [1,1] # Trajectory Parameters: number_of_projections = 12 angular_range = 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 phantom = shepp_logan.shepp_logan_3d(volume_shape).astype(np.float32) # Add required batch dimension phantom = np.expand_dims(phantom, axis=0) sino = cone_projection3d(phantom,geometry) @tf.function def test_func_proj(x): return cone_projection3d(x,geometry) @tf.function def test_func_reco(x): return cone_backprojection3d(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])
####################################### Reconstruction parameters # Declare Parameters RECONSTRUCT_PARA = {} # Volume Parameters: RECONSTRUCT_PARA['volume_shape'] = [150, 256, 256] RECONSTRUCT_PARA['volume_spacing'] = [1.6, 0.73, 0.73] ####################################### Normalization spacing parameters NORMALIZATION_VOLUME_SPACING = [1.0, 0.56, 0.56] ####################################### Training, validation and test data phantom index TRAIN_INDEX = [1,2,3,5,6,7,8,9,11,12,13,14,15,16,19] VALID_INDEX = [10,17,18] TEST_INDEX = [4,20] NUM_TRAINING_SAMPLES = len(TRAIN_INDEX) NUM_VALIDATION_SAMPLES = len(VALID_INDEX) NUM_TEST_SAMPLES = len(TEST_INDEX) ####################################### Create Geometry GEOMETRY = GeometryCone3D(RECONSTRUCT_PARA['volume_shape'], RECONSTRUCT_PARA['volume_spacing'], PROJECTION_PARA['detector_shape'], PROJECTION_PARA['detector_spacing'], PROJECTION_PARA['number_of_projections'], PROJECTION_PARA['angular_range'], PROJECTION_PARA['source_detector_distance'], PROJECTION_PARA['source_isocenter_distance']) GEOMETRY.set_projection_matrices(circular_trajectory.circular_trajectory_3d(GEOMETRY))
import load_data ####################################### Create a list of Geometry voxel_size_list = load_data.load_voxel_size_list() GEO_LIST = [] for n in range(len(voxel_size_list)): GEO_LIST.append( GeometryCone3D(RECONSTRUCT_PARA['volume_shape'], voxel_size_list[n], PROJECTION_PARA['detector_shape'], PROJECTION_PARA['detector_spacing'], PROJECTION_PARA['number_of_projections'], PROJECTION_PARA['angular_range'], PROJECTION_PARA['source_detector_distance'], PROJECTION_PARA['source_isocenter_distance'])) GEO_LIST[n].set_projection_matrices( circular_trajectory.circular_trajectory_3d(GEO_LIST[n])) ################################################################## from fdk_nn_model import model_fdk_nn from cnn_projection_model import model_cnn_projection from cnn_reconstruction_model import model_cnn_reconstruction from dense_cnn_reconstruction_model import model_dense_cnn_reconstruction from unet_projection_model import model_unet_projection from unet_reconstruction_model import model_unet_reconstruction from unet_proposed_reconstruction_model import model_unet_proposed_reconstruction from combined_projection_reconstruction_model import model_combined_proj_recon # training parameters LEARNING_RATE = 1e-5 MAX_EPOCHS = 800
def reconstruction(limited_angle_num): """ procedures for reconstruction from projection data Parameters ---------- limited_angle_num : int The limited angle for the reconstruction """ volume_size_list = load_volume_size_list() # Volume Parameters: volume_shape = RECONSTRUCT_PARA['volume_shape'] volume_spacing = RECONSTRUCT_PARA['volume_spacing'] # Detector Parameters: detector_shape = PROJECTION_PARA['detector_shape'] detector_spacing = PROJECTION_PARA['detector_spacing'] # Trajectory Parameters: number_of_projections = limited_angle_num + 1 angular_range = np.radians(limited_angle_num) source_detector_distance = PROJECTION_PARA['source_detector_distance'] source_isocenter_distance = PROJECTION_PARA['source_isocenter_distance'] # create Geometry class geometry = GeometryCone3D(volume_shape, volume_spacing, detector_shape, detector_spacing, number_of_projections, angular_range, source_detector_distance, source_isocenter_distance) projection_geometry = circular_trajectory.circular_trajectory_3d(geometry) geometry.set_projection_matrices(projection_geometry) ############################# number of phantoms to reconstruct sinograms_dir = 'sinograms/' num_phantoms = len(os.listdir(sinograms_dir)) config = tf.ConfigProto() config.gpu_options.per_process_gpu_memory_fraction = 0.9 config.gpu_options.allow_growth = True # ------------------ Call Layers ------------------ with tf.Session(config=config) as sess: model = FDKBackProjection(geometry) sess.run(tf.global_variables_initializer()) sess.run(tf.local_variables_initializer()) for n in range(num_phantoms): sinogram_dir = sinograms_dir + 'sinogram_' + str(n + 1) + '.npy' sinogram = np.load(sinogram_dir) sinogram = normalize_sino(sinogram[:number_of_projections, :, :]) model.update_geometry_volume_spacing(volume_size_list[n]) recon = model.model(sinogram) recon_fdk = sess.run(recon) np.save('recon_' + str(limited_angle_num) + '/recon_' + str(n + 1), recon_fdk) print('recon_ ' + str(n + 1) + ' generated!')
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')