Example #1
0
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
Example #2
0
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