def get_integer_translation(mraw_path, roi_reference, roi_size, file_shape, initial_only=False, n_im=0, progressBar=None): ''' Quickly get integer precision rigid body translation data from image, using FFT cross correlation. Only valid for object with minimal rotations and deformation. :param mraw_path: Path to .mraw file containing image data. :param roi_reference: Upper left coordinate point of ROI, (y, x). :param roi_size: ROI size, (h, w) [px]. :param file_shape: Tuple, (ntotal, height, width) of images in .mraw file. :param initial_only: If True, only the initial guess is returned. :param n_im: Number of images to be extracted from original sequence. If 0, whole sequence is used. :return: trans: Array of integer precision translation data, extracted fro mimage sequence, shaped [y, x]. ''' ntotal, h, w = file_shape with open(mraw_path, 'rb') as mraw: memmap = np.memmap(mraw, dtype=np.uint16, mode='r', shape=file_shape) if n_im: inc = ntotal // n_im + 1 else: inc = 1 imarray = memmap[::inc, :, :] image = imarray[0] roi_image = _get_roi_image(image, roi_reference, roi_size) initial_guess = dic.get_initial_guess(image, roi_image)[0] if initial_only: return initial_guess trans = np.array([[0, 0]], dtype=int) for i in range(imarray.shape[0]): image = imarray[i] new_trans = (dic.get_initial_guess(image, roi_image)[0] - initial_guess).astype(int) trans = np.vstack((trans, new_trans + trans[i])) roi_image = _get_roi_image(image, roi_reference, roi_size) if progressBar: progressBar.setValue(i / ntotal * 100) return trans, inc
def get_affine_deformations(mraw_path, roi_reference, roi_size, file_shape, progressBar=None, tol=1e-5, maxiter=100, int_order=3, increment=1, crop=False, debug=False): ''' Get defformations of te Region of Interest, using the Newton-Gauss optimization method with a Zero Normalized Cross Correlation based DIC algorithm. :param mraw_path: Path to .mraw file containing image data. :param roi_reference: Upper left coordinate point of ROI, (y, x). :param roi_size: ROI size, (h, w) [px]. :param file_shape: Tuple, (ntotal, height, width) of images in .mraw file. :param tol: Convergence condition (maximum parameter iteration vector norm). :param int_order: Bivariate spline interpolation order. :param increment: Only read every n-th image from sequence. :param: crop: Border size to crop loaded images (if 0, do not crop). :param: debug: If True, display debug output. :return: results: Numpy array, containing extracted data, shaped as [p1, p2, p3, p4, p5, p6] arrays for all images. :return: iters: Array, number of iterations required to reach converegence for each image pair. ''' with open(mraw_path, 'rb') as mraw: memmap = np.memmap(mraw, dtype=np.uint16, mode='r', shape=file_shape) # Map to all images in file memmap = memmap[::increment] # Apply sequence increment N_inc = len(memmap) errors = {} # Initialize warnings dictionary # Precomputable stuff: F = memmap[0] # Initial image of the sequence is only used once. ROI = _get_roi_image( F, roi_reference, roi_size) # First ROI image, used for the initial guess. ROI_st = (np.mean(ROI), np.std(ROI) ) # Mean and standard deviation of ROI gray values. if crop: crop_slice = _crop_with_border_slice(roi_reference, roi_size, crop) F = F[crop_slice] # Crop the initial image. in_guess = dic.get_initial_guess( F, ROI)[0] # Cross-correlation initial guess is only used once. jac = dic.jacobian_affine( roi_size[0], roi_size[1] ) # The Jacobian is constant throughout the computation. ## grad = dic.get_gradient( ROI, prefilter_gauss=True) # Compute gradient images of ROI. sd_im = dic.sd_images(grad, jac) # Steepest descent images for the current ROI. H = dic.hessian( sd_im, n_param=6 ) # Hessian matrix for the current ROI. ## inv_H = np.linalg.inv(H) # Inverse of Hessian. results = np.array([ np.zeros(6, dtype=np.float64) ]) # Initialize the results array. ## iters = np.array([], dtype=int) # Initialize array of iteration counters. p_shift = np.zeros( 6, dtype=np.float64 ) # Initialize cropped image shift ## p_ref = np.zeros( 6, dtype=np.float64 ) # Initialize a reference for all following calculations. p_ref[2], p_ref[5] = in_guess[1], in_guess[0] # ... # Loop through all the images in .mraw file: for i in range(1, len(memmap)): # First image was loaded already. if crop: this_p = results[-1] roi_translation = np.array([this_p[5], this_p[2]]).astype( int) # Last calculated integer displacement new_roi_reference = roi_reference + roi_translation # Shift cropped section new position crop_slice = _crop_with_border_slice( new_roi_reference, roi_size, crop) # Calculate crop indices for new image section if _is_in_image(crop_slice, file_shape): # If still inside image frame G = memmap[i][crop_slice] # Load the next target image. else: roi_translation = np.zeros( 2, dtype=int ) # If crop indices outside image frame: don't crop G = memmap[i] else: roi_translation = np.zeros(2, dtype=int) G = memmap[i] h, w = G.shape # Get the shape of the current image for interpolation. spl = RectBivariateSpline( x=np.arange( h), # Calculate cubic bivariate spline interpolation of G. y=np.arange(w), z=G, kx=int_order, ky=int_order, s=0) err = 1. # Initialize the convergence condition. niter = 0 # Initialize optimization loop iteration counter. # Optimization loop: while err > tol and niter < maxiter: if not 'p' in locals(): # If this is the first iteration: p = np.zeros( 6, dtype=np.float64 ) # Initialize optimization parameters vector ## p[2], p[5] = in_guess[1], in_guess[ 0] # Set initial parameters to in_guess. ## warped_ROI = _get_roi_image( G, in_guess, roi_size ) # Since in_guess are integer, extract new ROI directly. warp = dic.affine_transform_matrix( p ) # Get the affine transformation matrix form initial p. ## else: # Else, use last computed parameters, interpolate new ROI. xi, yi = dic.coordinate_warp( warp, roi_size ) # Get warped coordinates to new ROI, using last optimal warp. warped_ROI = dic.interpolate_warp( xi, yi, # Compute new ROI image by interpolating the reference image target=G, output_shape=roi_size, spl=spl, order=int_order) error_im = dic.get_error_image( ROI, ROI_st, warped_ROI ) # Compute error image, according to the ZNSSD criterion. b = dic.get_sd_error_vector( sd_im, error_im, 6 ) # Compute the right-side vector in the optimization system. ## dp = np.dot( inv_H, b) # Compute the optimal transform parameters increment. err = np.linalg.norm( dp) # Incremental parameter norm = convergence criterion. dp_warp = dic.affine_transform_matrix( dp ) # Construct the increment transformation matrix. ## try: # Singular warp matrix error handling. inverse_increment_warp = np.linalg.inv( dp_warp ) # Construct the inverse of increment warp materix. warp = np.dot(warp, inverse_increment_warp ) # The updated iteration of warp matrix. p = dic.param_from_affine_matrix( warp ) # The updated iteration of transformation parameters. ## except Exception as e: errors[i] = { 'image': G, 'ROI': warped_ROI, 'message': e, 'warp_matrix': dp_warp } niter += 1 # Update the optimization loop iteration counter. p_shift = np.zeros(6, dtype=np.float64) p_shift[2], p_shift[5] = roi_translation[1], roi_translation[0] p_relative = p_shift + p - p_ref # Calculate the relative translation and rotation. results = np.vstack((results, p_relative)) # Update the results array. iters = np.append(iters, niter) # Append current iteration number to list. if progressBar: progressBar.setValue(i / N_inc * 100) # Update the progress bar. else: stdout_print_progress(i - 2, N_inc) # Print progress info to stdout. if debug: # DEBUG if len(errors) != 0: fig, ax = plt.subplots(1, 3) ax[0].imshow(G, cmap='gray', interpolation='nearest') ax[1].imshow(ROI, cmap='gray', interpolation='nearest') ax[2].imshow(warped_ROI, cmap='gray', interpolation='nearest') #plt.show() if np.max( iters) >= maxiter: # If maximum number of iterations was reached: iters = np.append(iters, np.argmax( iters)) # Append index of first iteration number maximum. iters = np.append(iters, 0) # Append 0 to the iters list (warning signal!) print('Max niter: ', np.max(iters), ' (mean, std: ', np.mean(iters), np.std(iters), ')') memmap._mmap.close() # Close the loaded memmap return results, errors, iters, increment