def main(): np.random.seed(1000) if len(sys.argv) < 3: print('register_example.py: Too few parameters. Give the path to two gray-scale image files.') print('Example: python2 register_example.py reference_image floating_image') return False ref_im_path = sys.argv[1] flo_im_path = sys.argv[2] ref_im = scipy.misc.imread(ref_im_path, 'L') flo_im = scipy.misc.imread(flo_im_path, 'L') # Save copies of original images ref_im_orig = ref_im.copy() flo_im_orig = flo_im.copy() ref_im = filters.normalize(ref_im, 0.0, None) flo_im = filters.normalize(flo_im, 0.0, None) diag = 0.5 * (transforms.image_diagonal(ref_im, spacing) + transforms.image_diagonal(flo_im, spacing)) weights1 = np.ones(ref_im.shape) mask1 = np.ones(ref_im.shape, 'bool') weights2 = np.ones(flo_im.shape) mask2 = np.ones(flo_im.shape, 'bool') # Initialize registration framework for 2d images reg = Register(2) reg.set_report_freq(param_report_freq) reg.set_alpha_levels(alpha_levels) reg.set_reference_image(ref_im) reg.set_reference_mask(mask1) reg.set_reference_weights(weights1) reg.set_floating_image(flo_im) reg.set_floating_mask(mask2) reg.set_floating_weights(weights2) # Setup the Gaussian pyramid resolution levels reg.add_pyramid_level(4, 5.0) reg.add_pyramid_level(2, 3.0) reg.add_pyramid_level(1, 0.0) # Learning-rate / Step lengths [[start1, end1], [start2, end2] ...] (for each pyramid level) step_lengths = np.array([[1.0 ,1.0], [1.0, 0.5], [0.5, 0.1]]) # Create the transform and add it to the registration framework (switch between affine/rigid transforms by commenting/uncommenting) # Affine reg.add_initial_transform(AffineTransform(2), np.array([1.0/diag, 1.0/diag, 1.0/diag, 1.0/diag, 1.0, 1.0])) # Rigid 2D #reg.add_initial_transform(Rigid2DTransform(2), np.array([1.0/diag, 1.0, 1.0])) # Set the parameters reg.set_iterations(param_iterations) reg.set_gradient_magnitude_threshold(0.001) reg.set_sampling_fraction(param_sampling_fraction) reg.set_step_lengths(step_lengths) # Create output directory directory = os.path.dirname('./test_images/output/') if not os.path.exists(directory): os.makedirs(directory) # Start the pre-processing reg.initialize('./test_images/output/') # Control the formatting of numpy np.set_printoptions(suppress=True, linewidth=200) # Start the registration reg.run() (transform, value) = reg.get_output(0) ### Warp final image c = transforms.make_image_centered_transform(transform, ref_im, flo_im, spacing, spacing) # Print out transformation parameters print('Transformation parameters: %s.' % str(transform.get_params())) # Create the output image ref_im_warped = np.zeros(ref_im.shape) # Transform the floating image into the reference image space by applying transformation 'c' c.warp(In = flo_im_orig, Out = ref_im_warped, in_spacing=spacing, out_spacing=spacing, mode='spline', bg_value = 0.0) # Save the registered image scipy.misc.imsave('./test_images/output/registered.png', ref_im_warped) # Compute the absolute difference image between the reference and registered images D1 = np.abs(ref_im_orig-ref_im_warped) err = np.sum(D1) print("Err: %f" % err) scipy.misc.imsave('./test_images/output/diff.png', D1) return True
def main(): np.random.seed(1000) if len(sys.argv) < 3: print( f'{sys.argv[0]}: Too few parameters. Give the path to two gray-scale image files.' ) print(f'Example: python {sys.argv[0]} reference_image floating_image') return False ref_im_path = sys.argv[1] flo_im_path = sys.argv[2] ref_im = Image.open(ref_im_path).convert('L') flo_im = Image.open(flo_im_path).convert('L') ref_im = np.asarray(ref_im) / 255. flo_im = np.asarray(flo_im) / 255. # Make copies of original images ref_im_orig = ref_im.copy() flo_im_orig = flo_im.copy() # Preprocess images ref_im = filters.normalize(ref_im, 0.0, None) flo_im = filters.normalize(flo_im, 0.0, None) weights1 = np.ones(ref_im.shape) mask1 = np.ones(ref_im.shape, 'bool') weights2 = np.ones(flo_im.shape) mask2 = np.ones(flo_im.shape, 'bool') # Initialize registration framework for 2d images reg = Register(2) reg.set_image_data(ref_im, flo_im, mask1, mask2, weights1, weights2) # Choose a registration model reg.set_model('alphaAMD', alpha_levels=alpha_levels, \ symmetric_measure=symmetric_measure, \ squared_measure=squared_measure) # Setup the Gaussian pyramid resolution levels reg.add_pyramid_level(4, 5.0) reg.add_pyramid_level(2, 3.0) reg.add_pyramid_level(1, 0.0) # Choose an optimizer and set optimizer-specific parameters # For GD and adam, learning-rate / Step lengths given by [[start1, end1], [start2, end2] ...] (for each pyramid level) reg.set_optimizer('adam', \ gradient_magnitude_threshold=0.01, \ iterations=param_iterations ) # reg.set_optimizer('gd', \ # step_length=np.array([1., 0.5, 0.25]), \ # end_step_length=np.array([0.4, 0.2, 0.01]), \ # gradient_magnitude_threshold=0.01, \ # iterations=param_iterations # ) # reg.set_optimizer('scipy', \ # iterations=param_iterations, \ # epsilon=0.001 \ # ) # Scale all transform parameters to approximately the same order of magnitude, based on sizes of images diag = 0.5 * (transforms.image_diagonal(ref_im, spacing) + transforms.image_diagonal(flo_im, spacing)) # Create the initial transform and add it to the registration framework # (switch between affine/rigid transforms by commenting/uncommenting) # # Affine # initial_transform = transforms.AffineTransform(2) # param_scaling = np.array([1.0/diag, 1.0/diag, 1.0/diag, 1.0/diag, 1.0, 1.0]) # reg.add_initial_transform(initial_transform, param_scaling=param_scaling) # # Rigid 2D # initial_transform = transforms.Rigid2DTransform() # param_scaling = np.array([1.0/diag, 1.0, 1.0]) # reg.add_initial_transform(initial_transform, param_scaling=param_scaling) # Composite scale + rigid param_scaling = np.array([1.0 / diag, 1.0 / diag, 1.0, 1.0]) initial_transform = transforms.CompositeTransform(2, [transforms.ScalingTransform(2, uniform=True), \ transforms.Rigid2DTransform()]) reg.add_initial_transform(initial_transform, param_scaling=param_scaling) # Set up other registration framework parameters reg.set_report_freq(param_report_freq) reg.set_sampling_fraction(param_sampling_fraction) # Create output directory directory = os.path.dirname(outdir) if not os.path.exists(directory): os.makedirs(directory) # Start the pre-processing reg.initialize(outdir) # Control the formatting of numpy np.set_printoptions(suppress=True, linewidth=200) # Start the registration reg.run() (transform, value) = reg.get_output(0) ### Warp final image c = transforms.make_image_centered_transform(transform, ref_im, flo_im, spacing, spacing) # Print out transformation parameters and status print('Starting from %s, optimizer terminated with message: %s'%(str(initial_transform.get_params()), \ reg.get_output_messages()[0])) print('Final transformation parameters: %s.' % str(transform.get_params())) # Create the output image ref_im_warped = np.zeros(ref_im.shape) mask = np.ones(flo_im_orig.shape, dtype='bool') warped_mask = np.zeros(ref_im.shape, dtype='bool') # Transform the floating image into the reference image space by applying transformation 'c' c.warp(In=flo_im_orig, Out=ref_im_warped, in_spacing=spacing, out_spacing=spacing, mode='spline', bg_value=0.0) c.warp(In=mask, Out=warped_mask, in_spacing=spacing, out_spacing=spacing, mode='spline', bg_value=0.0) # Save the registered image Image.fromarray(ref_im_warped).convert('RGB').save(outdir + 'registered.png') # Compute the absolute difference image between the reference and registered images D1 = np.abs(ref_im_orig - ref_im_warped) err = np.mean(D1[warped_mask]) print("Err: %f" % err) Image.fromarray(D1).convert('RGB').save(outdir + 'diff.png') return True