def align(image, reference, mask=None, fill_value=0.0, fast=True): """ Align a diffraction image to a reference. Subpixel resolution available. Parameters ---------- image : `~numpy.ndarray`, shape (M,N) Image to be aligned. reference : `~numpy.ndarray`, shape (M,N) `image` will be align onto the `reference` image. mask : `~numpy.ndarray` or None, optional Mask that evaluates to True on valid pixels of the array `image`. fill_value : float, optional Edges will be filled with `fill_value` after alignment. fast : bool, optional If True (default), alignment is done on images cropped to half (one quarter area). Disable for small images, e.g. 256x256. Returns ------- aligned : `~numpy.ndarray`, shape (M,N) Aligned image. See Also -------- ialign : generator of aligned images """ if mask is None: mask = np.ones_like(image, dtype=np.bool) shift = masked_register_translation(src_image=image, target_image=reference, src_mask=mask) return shift_image(image, -1 * shift, fill_value=fill_value)
def estimate_velocity(first_image, second_image, dt): """Find the relative shift between the two tiles.""" # Use structural similarity index as a weight for frame transaltion computation. sim, diff = structural_similarity(first_image, second_image, full=True) if sim == 1: print(sim) mask = np.ones_like(first_image).astype(bool) delta = feature.masked_register_translation(second_image, first_image, mask, overlap_ratio=3 / 10) # Reorient to translate matrix motion to 2D image. delta[0] = delta[0] * -1 return delta / dt, sim
def register_imgset(imgset, mask): """ Register the input tensor imgset of shape (H, W, T) with respect to the image with the best quality map Parameters ---------- imgset: numpy array imgset to register masks: numpy array tensor with the quality maps of the imgset """ ref = imgset[...,np.argmax(np.mean(mask,axis=(0,1)))] #best image imgset_reg = np.empty(imgset.shape) mask_reg = np.empty(mask.shape) for i in range(imgset.shape[-1]): x = imgset[...,i]; m = mask[...,i] s = masked_register_translation(ref, x, m) x = shift(x, s, mode='reflect') m = shift(m, s, mode='constant', cval=0) imgset_reg[...,i] = x mask_reg[...,i] = m return imgset,mask_reg
# However, the masked_register_translation function requires # too much memory, and so readthedocs would kill the documentation # build. Therefore, we render the image locally instead. import matplotlib.pyplot as plt import numpy as np from skimage.feature import masked_register_translation from skued import shift_image, diffread ref = diffread("Cr_1.tif") im = diffread("Cr_2.tif") mask = np.ones_like(ref, dtype=np.bool) mask[0:1250, 950:1250] = False shift = masked_register_translation(im, ref, mask) shifted = shift_image(im, -1 * shift) fig, ((ax1, ax2, ax3), (ax4, ax5, ax6)) = plt.subplots(nrows=2, ncols=3, figsize=(9, 6)) ax1.imshow(ref, vmin=0, vmax=200) ax2.imshow(im, vmin=0, vmax=200) ax3.imshow(ref - im, cmap="RdBu_r", vmin=-100, vmax=100) ax4.imshow(mask, vmin=0, vmax=1, cmap="binary") ax5.imshow(shifted, vmin=0, vmax=200) ax6.imshow(ref - shifted, cmap="RdBu_r", vmin=-100, vmax=100) for ax in (ax1, ax2, ax3, ax4, ax5, ax6): ax.get_xaxis().set_visible(False) ax.get_yaxis().set_visible(False)
def register_frame(frame, mask, reference): detected_shift = masked_register_translation(reference, frame, mask) shifted_frame = ndi.shift(frame, detected_shift, mode='reflect') shifted_mask = ndi.shift(mask, detected_shift, mode='constant', cval=0) return shifted_frame, shifted_mask
# See reference paper for more examples corrupted_pixels = np.random.choice([False, True], size=image.shape, p=[0.25, 0.75]) # The shift corresponds to the pixel offset relative to the reference image offset_image = ndi.shift(image, shift) offset_image *= corrupted_pixels print("Known offset (y, x): {}".format(shift)) # Determine what the mask is based on which pixels are invalid # In this case, we know what the mask should be since we corrupted # the pixels ourselves mask = corrupted_pixels shift = masked_register_translation(image, offset_image, mask) print("Detected pixel offset (y, x): {}".format(shift)) fig = plt.figure(figsize=(8, 3)) ax1 = plt.subplot(1, 3, 1) ax2 = plt.subplot(1, 3, 2, sharex=ax1, sharey=ax1) ax3 = plt.subplot(1, 3, 3, sharex=ax1, sharey=ax1) ax1.imshow(image, cmap='gray') ax1.set_axis_off() ax1.set_title('Reference image') ax2.imshow(offset_image.real, cmap='gray') ax2.set_axis_off() ax2.set_title('Corrupted, offset image')
corrupted_pixels = np.random.choice([False, True], size = image.shape, p = [0.25, 0.75]) # The shift corresponds to the pixel offset relative to the reference image offset_image = ndi.shift(image, shift) offset_image *= corrupted_pixels print("Known offset (row, col): {}".format(shift)) # Determine what the mask is based on which pixels are invalid # In this case, we know what the mask should be since we corrupted # the pixels ourselves mask = corrupted_pixels detected_shift = masked_register_translation(image, offset_image, mask) print("Detected pixel offset (row, col): {}".format(-detected_shift)) fig = plt.figure(figsize=(8, 3)) ax1 = plt.subplot(1, 3, 1) ax2 = plt.subplot(1, 3, 2, sharex=ax1, sharey=ax1) ax3 = plt.subplot(1, 3, 3, sharex=ax1, sharey=ax1) ax1.imshow(image, cmap='gray') ax1.set_axis_off() ax1.set_title('Reference image') ax2.imshow(offset_image.real, cmap='gray') ax2.set_axis_off() ax2.set_title('Corrupted, offset image')
corrupted_pixels = np.random.choice([False, True], size=image.shape, p=[0.25, 0.75]) # The shift corresponds to the pixel offset relative to the reference image offset_image = ndi.shift(image, shift) offset_image *= corrupted_pixels print(f"Known offset (row, col): {shift}") # Determine what the mask is based on which pixels are invalid # In this case, we know what the mask should be since we corrupted # the pixels ourselves mask = corrupted_pixels detected_shift = masked_register_translation(image, offset_image, mask) print(f"Detected pixel offset (row, col): {-detected_shift}") fig = plt.figure(figsize=(8, 3)) ax1 = plt.subplot(1, 3, 1) ax2 = plt.subplot(1, 3, 2, sharex=ax1, sharey=ax1) ax3 = plt.subplot(1, 3, 3, sharex=ax1, sharey=ax1) ax1.imshow(image, cmap='gray') ax1.set_axis_off() ax1.set_title('Reference image') ax2.imshow(offset_image.real, cmap='gray') ax2.set_axis_off() ax2.set_title('Corrupted, offset image')