def registerImagesBetweenThemselves(im1, im2, sliceReference=0): Is = im1.copy() Ir = im2.copy() refImage = Is[sliceReference, :, :] nbSlices, height, width = Is.shape for slice in (range(0, nbSlices)): if slice != sliceReference: imageToMove = Is[slice, :, :] shift = getShift(refImage, imageToMove, precision=1000) if shift[0] > 1: shift[0] = 0 print('Slice:' + str(slice) + 'Shift:' + str(shift)) offset_image = fourier_shift(np.fft.fftn(imageToMove), shift) offset_image = np.fft.ifftn(offset_image).real Is[slice, :, :] = offset_image refToMove = Ir[slice, :, :] offset_image = fourier_shift(np.fft.fftn(refToMove), shift) offset_image = np.fft.ifftn(offset_image).real Ir[slice, :, :] = offset_image return Is, Ir
def caculate_TD(d_Ir_xy_roi, I_xy_roi, window, dy, dx): temp = fourier_shift(np.fft.fftn(d_Ir_xy_roi), (dy, dx)) # shift the reference image of sandpaper Ir_xy_shift = np.fft.ifftn(temp) Ir_xy_shift = Ir_xy_shift.real # delta_Ir(x-dx, y-dy) #Ir_xy_shift = d_Ir_xy_roi assert np.shape(window) == np.shape(I_xy_roi), " size doesn't match!" Img_avg_roi = window*I_xy_roi I_avg_roi = np.sum(window*I_xy_roi)# I_mean assert np.shape(Ir_xy_shift) == np.shape(window), " size doesn't match!" T_upper_left =I_avg_roi* np.sum((window*(Ir_xy_shift*Ir_xy_shift))) T_upper_right1 = np.sum(window*Ir_xy_shift) T_upper_right2 = np.sum(window*I_xy_roi*Ir_xy_shift) T_upper_right = T_upper_right1*T_upper_right2 T_bottom_left = np.sum(window*Ir_xy_shift*Ir_xy_shift) T_bottom_right = (np.sum(window*Ir_xy_shift))**2 T = T_upper_left - T_upper_right T = T/(T_bottom_left - T_bottom_right) T = T/Io #print('calculated T:',T) D_upper = np.sum((window*I_xy_roi)*Ir_xy_shift)- I_avg_roi*(np.sum(window*Ir_xy_shift)) D_lower = T*(np.sum(window*(Ir_xy_shift*Ir_xy_shift))-(np.sum(window*Ir_xy_shift))**2) D = D_upper/D_lower return(T, D)
def test_masked_registration_random_masks_non_equal_sizes(): """masked_register_translation should be able to register translations between images that are not the same size even with random masks.""" # See random number generator for reproducible results np.random.seed(23) reference_image = camera() shift = (-7, 12) shifted = np.real( fft.ifft2(fourier_shift(fft.fft2(reference_image), shift))) # Crop the shifted image shifted = shifted[64:-64, 64:-64] # Random masks with 75% of pixels being valid ref_mask = np.random.choice([True, False], reference_image.shape, p=[3 / 4, 1 / 4]) shifted_mask = np.random.choice([True, False], shifted.shape, p=[3 / 4, 1 / 4]) measured_shift = masked_register_translation( reference_image, shifted, reference_mask=np.ones_like(ref_mask), moving_mask=np.ones_like(shifted_mask)) assert_equal(measured_shift, -np.array(shift))
def shift_image(image, shift_yx, interpolation, mode='constant'): """ Function to shift an image. Parameters ---------- image : numpy.ndarray Input image (2D). shift_yx : tuple(float, float) Shift (y, x) to be applied (pix). interpolation : str Interpolation type ("spline", "bilinear", or "fft"). Returns ------- numpy.ndarray Shifted image. """ if interpolation == "spline": im_center = shift(image, shift_yx, order=5, mode=mode) elif interpolation == "bilinear": im_center = shift(image, shift_yx, order=1, mode=mode) elif interpolation == "fft": fft_shift = fourier_shift(np.fft.fftn(image), shift_yx) im_center = np.fft.ifftn(fft_shift).real return im_center
def subpixel(a, plot=False): optIntShift, aTemp = closest_pixel(a, plot=plot) def func(x): return -(a[::2,...]*np.fft.ifftn(fourier_shift(np.fft.fftn(a[1::2,...]), [0, x[0]])).real).sum() - (a[2::2,...]*np.fft.ifftn(fourier_shift(np.fft.fftn(a[1:-1:2,...]), [0, x[0]])).real).sum() res = scipy.optimize.minimize(func, x0=[optIntShift], method='Nelder-Mead') if res['success']: optimalShift = res['x'][0] aOut = np.copy(a) aOut[1::2,...] = np.fft.ifftn(fourier_shift(np.fft.fftn(aOut[1::2,...]), [0, optimalShift])).real if plot: upsample_factor=20 shifts = np.arange(optIntShift-1, optIntShift+1, 1./upsample_factor) corrs = np.zeros(shifts.shape, dtype='float') for i, shift in enumerate(shifts): corrs[i] = func([shift]) plt.plot(optimalShift, corrs.min(), 'rx') plt.text(optimalShift, corrs.min(), 'optimal') plt.plot(shifts, corrs, 'g.') plt.xlabel('Horizonal shift') return optimalShift, aOut
def realign_image(arr, shift, angle=0): """ Translate and rotate image via Fourier Parameters ---------- arr : ndarray Image array. shift: float Mininum and maximum values to rescale data. angle: float, optional Mininum and maximum values to rescale data. Returns ------- ndarray Output array. """ # if both shifts are integers, do circular shift; otherwise perform Fourier shift. if np.count_nonzero(np.abs(np.array(shift) - np.round(shift)) < 0.01) == 2: temp = np.roll(arr, int(shift[0]), axis=0) temp = np.roll(temp, int(shift[1]), axis=1) temp = temp.astype('float32') else: temp = fourier_shift(np.fft.fftn(arr), shift) temp = np.fft.ifftn(temp) temp = np.abs(temp).astype('float32') return temp
def fourier_imshift(image, xshift, yshift, pad=False): ''' Shift an image by use of Fourier shift theorem Parameters: image : nd array N x K image xshift : float Pixel value by which to shift image in the x direction yshift : float Pixel value by which to shift image in the x direction pad : bool Should we pad the array before shifting, then truncate? Otherwise, the image is wrapped. Returns: offset : nd array Shifted image ''' # Pad ends with zeros if pad: padx = np.abs(np.int(xshift)) + 1 pady = np.abs(np.int(yshift)) + 1 pad_vals = ([pady]*2,[padx]*2) im = np.pad(image,pad_vals,'constant') else: padx = 0; pady = 0 im = image offset = fourier_shift( np.fft.fft2(im), (yshift,xshift) ) offset = np.fft.ifft2(offset).real offset = offset[pady:pady+image.shape[0], padx:padx+image.shape[1]] return offset
def shift(img, x, y): """ Apply a shift to an image """ offset_image = fourier_shift(pyfftw.interfaces.numpy_fft.fftn(img), (x, y)) offset_image = pyfftw.interfaces.numpy_fft.ifftn(offset_image).real return offset_image
def shift_stack(a, shift): aOut = np.copy(a) shiftVector = np.zeros(a.ndim, dtype='float') shiftVector[1] = shift aOut[1::2, ...] = np.fft.ifftn( fourier_shift(np.fft.fftn(aOut[1::2, ...]), shiftVector)).real return aOut
def setUp(self): ref_image = ascent() center = np.array((256, 256)) shifts = np.array( [ (0.0, 0.0), (4.3, 2.13), (1.65, 3.58), (-2.3, 2.9), (5.2, -2.1), (2.7, 2.9), (5.0, 6.8), (-9.1, -9.5), (-9.0, -9.9), (-6.3, -9.2), ] ) s = hs.signals.Signal2D(np.zeros((10, 100, 100))) for i in range(10): # Apply each sup-pixel shift using FFT and InverseFFT offset_image = fourier_shift(np.fft.fftn(ref_image), shifts[i]) offset_image = np.fft.ifftn(offset_image).real # Crop central regions of shifted images to avoid wrap around s.data[i, ...] = offset_image[center[0] : center[0] + 100, center[1] : center[1] + 100] self.signal = s self.shifts = shifts
def register_image(inp): if 'inRAM_flag' in globals(): inRAM = inRAM_flag else: inRAM = True if 'refIm' in globals(): refIm_ = refIm if 'crop' not in globals() and 'crop' not in locals(): if inp[1].shape[0]>256: crop_ = True refIm_ = inp[0][128:-128,128:-128] upsample_factor = 10 else: crop_ = False refIm_ = inp[0] upsample_factor = 1 image = inp[1] else: crop_ = crop upsample_factor = 10 if not inRAM: image_idx = inp[0] image = inp[1] regFile = inp[2] else: image = inp #print refIm_.shape, if crop_==True: tmpII = image[128:-128,128:-128] - ndimage.gaussian_filter(image[128:-128,128:-128],5) #shift, _, _ = register_translation(refIm_,image[128:-128,128:-128],upsample_factor=upsample_factor) shift, _, _ = register_translation(refIm_,tmpII,upsample_factor=upsample_factor) else: shift, _, _ = register_translation(refIm_, image, upsample_factor=upsample_factor) #set this if np.any(np.abs(shift)>=20): shift = np.array([0,0]) #print("! WARNING VERY LARGE SHIFTS ! %s" %shift) if np.sum(np.abs(shift))!=0: regIm = np.fft.ifftn(fourier_shift(np.fft.fftn(image), shift)).real else: regIm = image #added for reduce memory test if not inRAM: regFile[image_idx] = regIm return shift else: return [shift,regIm]
def shift_image(image, shift_yx, interpolation, mode='constant'): """ Function to shift an image. :param images: Input image. :type images: numpy.ndarray :param shift_yx: Shift (y, x) to be applied (pixel). :type shift_yx: (float, float) :param interpolation: Interpolation type (spline, bilinear, fft) :type interpolation: str :return: Shifted image. :rtype: numpy.ndarray """ if interpolation == "spline": im_center = shift(image, shift_yx, order=5, mode=mode) elif interpolation == "bilinear": im_center = shift(image, shift_yx, order=1, mode=mode) elif interpolation == "fft": fft_shift = fourier_shift(np.fft.fftn(image), shift_yx) im_center = np.fft.ifftn(fft_shift).real return im_center
def shift_im(im, shift): import numpy as np from scipy.ndimage import fourier_shift fim_shift = fourier_shift(np.fft.fftn(im), map(lambda x: -x, shift)) im_shift = np.fft.ifftn(fim_shift) return im_shift.real
def test_masked_registration_random_masks_non_equal_sizes(): """masked_register_translation should be able to register translations between images that are not the same size even with random masks.""" # See random number generator for reproducible results np.random.seed(23) reference_image = camera() shift = (-7, 12) shifted = np.real(np.fft.ifft2(fourier_shift( np.fft.fft2(reference_image), shift))) # Crop the shifted image shifted = shifted[64:-64, 64:-64] # Random masks with 75% of pixels being valid ref_mask = np.random.choice( [True, False], reference_image.shape, p=[3 / 4, 1 / 4]) shifted_mask = np.random.choice( [True, False], shifted.shape, p=[3 / 4, 1 / 4]) measured_shift = masked_register_translation( reference_image, shifted, np.ones_like(ref_mask), np.ones_like(shifted_mask)) assert_equal(measured_shift, -np.array(shift))
def apply_shifts(im,shift): offset_image = [] for i in range(im.shape[2]): offset_im = fourier_shift(np.fft.fftn(im[:,:,i]), shift) offset_image.append(np.fft.ifftn(offset_im)) offset_image = np.transpose(offset_image,axes=[1,2,0]).astype(np.float32) return offset_image
def phase_correlation_registration(fixed_image, moving_image, subpixel=100, verbose=False, resample=True): """ A simple Phase Correlation based image registration method. :param verbose: enable print functions :param subpixel: resampling factor; registration will be perfromed to 1/subpixel accuracy :param fixed_image: the reference image as MIPLIB Image object :param moving_image: the moving image as MIPLIB Image object :return: returns the SimpleITK transform """ assert isinstance(fixed_image, Image) assert isinstance(moving_image, Image) shift, error, diffphase = register_translation(fixed_image, moving_image, subpixel) scaled_shifts = list( -offset * spacing for offset, spacing in zip(shift, fixed_image.spacing)) if verbose: print(("Detected offset (y, x): {}".format(scaled_shifts))) if resample: resampled = np.abs( np.fft.ifftn(fourier_shift(np.fft.fftn(moving_image), shift)).real) return Image(resampled, fixed_image.spacing) else: return scaled_shifts
def setUp(self): # Starting high-res is a 121x121 image of an Airy disk hr = np.array(AiryDisk2DKernel(radius=15)) hr = normalize(hr, new_min=0, new_max=1) # Crop to 120x120 to simplify debugging calculations hr = hr[0:120, 0:120] # Arbitrary PSF psf = np.ones((7, 7)) / 7**2 # Create low-res frames with no motion camera = ObservationModel(hr, n=5, psf=psf, downsample_factor=10, translation_range=(0, 0), rotation_range=(0, 0), noise_scale=0.001) self.low_resolution = [] self.translations = [] # Add motion to the lr frames and store the exact amount for lr in camera.low_res_images: # There's no significant rotation in the actual data set only translation tx, ty = np.random.randint(-3, 3, size=(1, 2))[0] im = fourier_shift(np.fft.fftn(lr), (ty, tx)) im = np.fft.ifftn(im).real self.low_resolution.append(im) self.translations.append((tx, ty))
def score(self, ref_im): """ Align the reconstruction using phase correlation and calculate the MSE and SSIM. Inputs: - ref_im: A numpy array of shape (N,N) contaning a reference image. Outputs: - mse: Mean squared error (float). - ssim: Structural similarity index (float). """ if isinstance(self.res, type(None)): raise Exception('Result is not yet aviable.') shift = register_translation(ref_im, self.res)[0] shifted_res = fourier_shift(np.fft.fft2(self.res), shift) shifted_res = np.real(np.fft.ifft2(shifted_res)) mse = np.linalg.norm(shifted_res - ref_im) drange = np.max(shifted_res) - np.min(shifted_res) ssim = compare_ssim(ref_im, shifted_res, data_range=drange) return mse, ssim
def setup(self, ndims, image_size, upscale_factor, *args): if phase_cross_correlation is None: raise NotImplementedError("phase_cross_correlation unavailable") shifts = (-2.3, 1.7, 5.4, -3.2)[:ndims] phantom = img_as_float( data.binary_blobs(length=image_size, n_dim=ndims)) self.reference_image = np.fft.fftn(phantom) self.shifted_image = ndi.fourier_shift(self.reference_image, shifts)
def fixImage(image): for i in range(Sz[3]): oddLines = image[range(1, Sz[1], 2), :, i] Shift = (0, medianShift) shiftedOdd = fourier_shift(np.fft.fftn(oddLines), Shift) shiftedOdd = np.real(np.fft.ifftn(shiftedOdd)) image[range(1, Sz[1], 2), :, i] = shiftedOdd return image
def imgsubshift(img,shift): tmp = img.copy() fftimg = fft.fft2(tmp) tmp0 = ndm.fourier_shift(fftimg, shift) result = fft.ifft2(tmp0).real return result
def fixPerTimepointFunc(kv): k, image = kv shift = (0, shifts[k]) for i in range(Sz[3]): oddLines = image[range(1, Sz[1], 2), :, i] shiftedOdd = fourier_shift(np.fft.fftn(oddLines), shift) shiftedOdd = np.real(np.fft.ifftn(shiftedOdd)) image[range(1, Sz[1], 2), :, i] = shiftedOdd return image
def test_4d_input_pixel(): phantom = img_as_float(binary_blobs(length=32, n_dim=4)) reference_image = fft.fftn(phantom) shift = (-2., 1., 5., -3) shifted_image = fourier_shift(reference_image, shift) result, error, diffphase = phase_cross_correlation(reference_image, shifted_image, space="fourier") assert_allclose(result, -np.array(shift), atol=0.05)
def test_4d_input_pixel(): phantom = img_as_float(binary_blobs(length=32, n_dim=4)) reference_image = np.fft.fftn(phantom) shift = (-2., 1., 5., -3) shifted_image = fourier_shift(reference_image, shift) result, error, diffphase = register_translation(reference_image, shifted_image, space="fourier") assert_allclose(result, -np.array(shift), atol=0.05)
def apply_shift(res, psi, p, id): """Apply shift for one projection.""" # padding to avoid signal wrapping [nz, n] = psi[id].shape tmp = np.zeros([nz + nz // 4, n + n // 4], dtype='float32') tmp[nz // 8:nz + nz // 8, n // 8:n + n // 8] = psi[id] res0 = np.fft.ifft2(ndimage.fourier_shift(np.fft.fft2(tmp), p)) res[id] = np.real(res0[nz // 8:nz + nz // 8, n // 8:n + n // 8]) return res[id]
def imgsubshift_cupy(img_cupy,shift): fftimg_cupy = cp.fft.fft2(img_cupy) fftimg=cp.asnumpy(fftimg_cupy) tmp0=ndm.fourier_shift(fftimg, shift) tmp0_cupy=cp.asarray(tmp0) result_cupy=cp.fft.ifft2(tmp0_cupy).real return result_cupy
def image_registration(ref_image, off_image, img_to_reg=None, upsample_fac=50): """ Function to co-register off_image with respect to off_image""" shift, error, diffphase = phase_cross_correlation( ref_image, off_image, upsample_factor=upsample_fac) if img_to_reg is None: img_to_reg = off_image reg_image = np.real( np.fft.ifftn(fourier_shift(np.fft.fftn(img_to_reg), shift))) return reg_image
def test_correlation(): reference_image = fft.fftn(camera()) shift = (-7, 12) shifted_image = fourier_shift(reference_image, shift) # pixel precision result, error, diffphase = phase_cross_correlation(reference_image, shifted_image, space="fourier") assert_allclose(result[:2], -np.array(shift))
def test_real_input(): reference_image = camera() subpixel_shift = (-2.4, 1.32) shifted_image = fourier_shift(np.fft.fftn(reference_image), subpixel_shift) shifted_image = np.fft.ifftn(shifted_image) # subpixel precision result, error, diffphase = register_translation(reference_image, shifted_image, 100) assert_allclose(result[:2], -np.array(subpixel_shift), atol=0.05)
def test_subpixel_precision(): reference_image = np.fft.fftn(camera()) subpixel_shift = (-2.4, 1.32) shifted_image = fourier_shift(reference_image, subpixel_shift) # subpixel precision result, error, diffphase = register_translation(reference_image, shifted_image, 100, space="fourier") assert_allclose(result[:2], -np.array(subpixel_shift), atol=0.05)
def test_correlation(): reference_image = np.fft.fftn(camera()) shift = (-7, 12) shifted_image = fourier_shift(reference_image, shift) # pixel precision result, error, diffphase = register_translation(reference_image, shifted_image, space="fourier") assert_allclose(result[:2], -np.array(shift))
def test_4d_input_subpixel(): phantom = img_as_float(binary_blobs(length=32, n_dim=4)) reference_image = fft.fftn(phantom) subpixel_shift = (-2.3, 1.7, 5.4, -3.2) shifted_image = fourier_shift(reference_image, subpixel_shift) result, error, diffphase = register_translation(reference_image, shifted_image, 10, space="fourier") assert_allclose(result, -np.array(subpixel_shift), atol=0.05)
def shift_momentum(self, psik=None, scale=1.0, frac=(0.5, 0.5)): """Shifts momentum components of `psi` by a fracion of +/- kL_recoil. The ground-state solutions of Raman-coupled spinor systems in general have spinor components with both left- and right-moving momentum peaks. Providing a manual shift on the momentum-space wavefunction components better approximates these solutions, i.e. faster convergence in imaginary time propagation. Parameters ---------- psik : :obj:`list` of NumPy :obj:`array`, optional. The momentum-space pseudospinor wavefunction. If `psik` is not provided, then this function uses the current class attribute `self.psik`. scale : :obj:`float`, default=1.0 By default, the function shifts the momentum peaks by a single unit of recoil momenta `kL_recoil`. `scale` gives the option of scaling the shift larger or smaller for faster convergence. frac : :obj:`iterable`, default=(0.5, 0.5) The fraction of each spinor component's momentum peak to shift in either direction. frac=(0.5, 0.5) splits into two equal peaks, while (0.0, 1.0) and (1.0, 0.0) move the entire peak one direction or the other. """ assert self.is_coupling, ("The `is_coupling` option is " f"{self.is_coupling}. Initialize coupling " "with `coupling_setup()`.") if psik is None: psik = self.psik shift = scale * self.kL_recoil / self.space['dk'][0] input_ = ttools.fft_2d(psik, self.space['dr']) result = [np.zeros_like(pk) for pk in psik] for i in range(len(psik)): positive = fourier_shift(input_[i], shift=[0, shift], axis=1) negative = fourier_shift(input_[i], shift=[0, -shift], axis=1) result[i] = frac[0] * positive + frac[1] * negative frac = np.flip(frac) self.psik = ttools.ifft_2d(result, self.space['dr']) self.psi = ttools.ifft_2d(self.psik, self.space['dr'])
def test_fourier_shift_real01(self, shape, dtype, dec): expected = numpy.arange(shape[0] * shape[1], dtype=dtype) expected.shape = shape a = fft.rfft(expected, shape[0], 0) a = fft.fft(a, shape[1], 1) a = ndimage.fourier_shift(a, [1, 1], shape[0], 0) a = fft.ifft(a, shape[1], 1) a = fft.irfft(a, shape[0], 0) assert_array_almost_equal(a[1:, 1:], expected[:-1, :-1], decimal=dec) assert_array_almost_equal(a.imag, numpy.zeros(shape), decimal=dec)
def test_size_one_dimension_input(): # take a strip of the input image reference_image = np.fft.fftn(camera()[:, 15]).reshape((-1, 1)) subpixel_shift = (-2.4, 4) shifted_image = fourier_shift(reference_image, subpixel_shift) # subpixel precision result, error, diffphase = register_translation(reference_image, shifted_image, 100, space="fourier") assert_allclose(result[:2], -np.array((-2.4, 0)), atol=0.05)
def test_3d_input(): phantom = img_as_float(binary_blobs(length=32, n_dim=3)) reference_image = fft.fftn(phantom) shift = (-2., 1., 5.) shifted_image = fourier_shift(reference_image, shift) result, error, diffphase = phase_cross_correlation(reference_image, shifted_image, space="fourier") assert_allclose(result, -np.array(shift), atol=0.05) # subpixel precision now available for 3-D data subpixel_shift = (-2.3, 1.7, 5.4) shifted_image = fourier_shift(reference_image, subpixel_shift) result, error, diffphase = phase_cross_correlation(reference_image, shifted_image, upsample_factor=100, space="fourier") assert_allclose(result, -np.array(subpixel_shift), atol=0.05)
def test_3d_input(): phantom = img_as_float(binary_blobs(length=32, n_dim=3)) reference_image = np.fft.fftn(phantom) shift = (-2., 1., 5.) shifted_image = fourier_shift(reference_image, shift) result, error, diffphase = register_translation(reference_image, shifted_image, space="fourier") assert_allclose(result, -np.array(shift), atol=0.05) # subpixel precision not available for 3-D data subpixel_shift = (-2.3, 1., 5.) shifted_image = fourier_shift(reference_image, subpixel_shift) result, error, diffphase = register_translation(reference_image, shifted_image, space="fourier") assert_allclose(result, -np.array(shift), atol=0.5) assert_raises(NotImplementedError, register_translation, reference_image, shifted_image, upsample_factor=100, space="fourier")
def Register_Image(image,refIm,crop=False): if crop==True: shift, _, _ = register_translation(refIm,image[128:-128,128:-128],upsample_factor=10) else: shift, _, _ = register_translation(refIm, image, upsample_factor=10) if np.sum(np.abs(shift))!=0: regIm = np.fft.ifftn(fourier_shift(np.fft.fftn(image), shift)).real else: regIm = image return [shift,regIm]
def test_masked_registration_vs_register_translation(): """masked_register_translation should give the same results as register_translation in the case of trivial masks.""" reference_image = camera() shift = (-7, 12) shifted = np.real(np.fft.ifft2(fourier_shift( np.fft.fft2(reference_image), shift))) trivial_mask = np.ones_like(reference_image) nonmasked_result, *_ = register_translation(reference_image, shifted) masked_result = masked_register_translation( reference_image, shifted, trivial_mask, overlap_ratio=1 / 10) assert_equal(nonmasked_result, masked_result)
def fourier_imshift(image, shift): ''' Shift an image by use of Fourier shift theorem Parameters ---------- image : numpy.ndarray A 2D (``NxK``) or 3D (``LxNxK``) image. shift : numpy.ndarray A 1D or 2D array of shape ``Lx2`` containing pixel values by which to shift image slices in the X and Y directions. Returns ------- offset : numpy.ndarray Shifted image ''' ndim = len(image.shape) if ndim == 2: shift = np.asanyarray(shift)[:2] offset_image = fourier_shift( np.fft.fftn(image), shift[::-1] ) offset = np.fft.ifftn(offset_image).real elif ndim == 3: nslices = image.shape[0] shift = np.asanyarray(shift)[:, :2] if (shift.shape[0] != nslices): raise ValueError("The number of provided shifts must be equal " "to the number of slices in the input image.") offset = np.empty_like(image, dtype=np.float) for k in range(nslices): offset[k] = fourier_imshift(image[k], shift[k]) else: raise ValueError("Input image must be either a 2D or a 3D array.") return offset
def fourier_imshift(image,xshift,yshift): ''' Shift an image by use of Fourier shift theorem Parameters: image : nd array N x K image xshift : float Pixel value by which to shift image in the x direction yshift : float Pixel value by which to shift image in the y direction Returns: offset : nd array Shifted image ''' offset = fourier_shift( np.fft.fftn(image), (-yshift,xshift) ) offset = np.fft.ifftn(offset).real return offset
def subpixel(a, plot=False): optIntShift, aTemp = closest_pixel(a, plot=plot) def func(x): return -(a[::2,...]*np.fft.ifftn(fourier_shift(np.fft.fftn(a[1::2,...]), [0, x[0]])).real).sum() - (a[2::2,...]*np.fft.ifftn(fourier_shift(np.fft.fftn(a[1:-1:2,...]), [0, x[0]])).real).sum() res = scipy.optimize.minimize(func, x0=[optIntShift], method='Nelder-Mead') if res['success']: optimalShift = res['x'][0] aOut = np.copy(a) aOut[1::2,...] = np.fft.ifftn(fourier_shift(np.fft.fftn(aOut[1::2,...]), [0, optimalShift])).real if plot: upsample_factor=20 shifts = np.arange(optIntShift-1, optIntShift+1, 1./upsample_factor) corrs = np.zeros(shifts.shape, dtype='float') for i, shift in enumerate(shifts): corrs[i] = func([shift]) plt.plot(optimalShift, corrs.max(), 'rx') plt.plot(shifts, corrs, 'g.') return optimalShift, aOut
def setup(self, ndims, image_size, upscale_factor, *args): shifts = (-2.3, 1.7, 5.4, -3.2)[:ndims] phantom = img_as_float(binary_blobs(length=image_size, n_dim=ndims)) self.reference_image = np.fft.fftn(phantom) self.shifted_image = ndi.fourier_shift(self.reference_image, shifts)
def register_dayData(HDF_File,session_ID,inRAM=True,poolSize=4,abs_loc='foo',common_ref=False,show_ref_mean=1): print('srm',show_ref_mean,type(show_ref_mean)) print(abs_loc) hdfPath = HDF_File.filename hdfDir = os.path.split(hdfPath)[0] global inRAM_flag inRAM_flag=inRAM if 'registered_data' not in HDF_File[session_ID].keys(): HDF_File[session_ID].create_group('registered_data') HDF_File.close() HDF_File = h5py.File(hdfPath,'a',libver='latest') print('Creating Registered Data Group') regData_dir = os.path.join(hdfDir,'regInfo') if not os.path.exists(regData_dir): os.mkdir(regData_dir) for f_idx, file_key in enumerate(HDF_File[session_ID]['raw_data'].keys()): if f_idx >0: HDF_File = h5py.File(hdfPath,'a',libver='latest') if file_key in HDF_File[session_ID]['registered_data'].keys(): del HDF_File[session_ID]['registered_data'][file_key] print('deleting old version') st = time.time() try: #raw_file = np.array(HDF_File[session_ID]['raw_data'][file_key]) raw_file = HDF_File[session_ID]['raw_data'][file_key] frames = raw_file.shape[0] chunkSize = np.max(np.array([x for x in range(1, 11) if frames%x == 0])) #corrs_ = [] #print frames #nChunks = np.floor(frames/50) #raw_file[:50*nChunks].reshape(-50,nChunks) #for j in raw_file[:frames]: # corrs_.append(np. corrcoef(i.flatten(),j.flatten())[0,1]) #ord_ = np.argsort(corrs_) if common_ref and f_idx==0: """print 'creating global reference' #refIm_glob = np.mean(raw_file[ord_[-200:]],axis=0)[:,128:-128] import Register_Image ############# HERE TRY TO FIND A REFERENCE IMAGE ############### refss = [] for ix_,as_ in enumerate(HDF_File[session_ID]['raw_data'].keys()): a_ = np.mean(HDF_File[session_ID]['raw_data'][as_][-500:],axis=0) refss.append(a_) plt.figure(ix_) plt.imshow(a_,interpolation='None',cmap='gray') plt.title(ix_) plt.show(block=False) sel_ref = int(raw_input("selected mean: "))""" ########### refss = [] im_grads = [] hdf_keys = sorted(HDF_File[session_ID]['raw_data'].keys()) st = time.time() kix_ = hdf_keys[-2] temp = np.array(HDF_File[session_ID]['raw_data'][kix_]) print(kix_) print ('load time:', np.round(time.time() - st,decimals=1)) ixs_sets = [] for ii in range(200): #kix = np.random.randint(len(hdf_keys)) ixs = np.random.permutation(np.arange(HDF_File[session_ID]['raw_data'][kix_].shape[0]))[:500] ixs_sets.append(ixs) a_ = np.mean(temp[np.array(sorted(ixs)),:,:],axis=0) refss.append(a_) im_grads.append(np.sum(np.abs(np.gradient(refss[-1])))) #print time.time() - st ord_grads = np.argsort(np.array(im_grads))[-10:] sortImLst = [] print(len(ixs_sets[ord_grads[-1]])) for iikk,imIx in enumerate(ixs_sets[ord_grads[-1]]): #print(iikk,) if iikk==0: REF__ = refss[ord_grads[-1]] else: shift, _, _ = register_translation(REF__[128:-128,128:-128],temp[imIx][128:-128,128:-128],upsample_factor=2) if np.any(np.abs(shift)>20): shift = np.array([0,0]) if np.sum(np.abs(shift))!=0: RegIm = np.fft.ifftn(fourier_shift(np.fft.fftn(temp[imIx]), shift)).real else: RegIm = temp[imIx] sortImLst.append(RegIm) #REF__ = REF__/((1-1/(iikk+1))) + RegIm/float(iikk+1) #for ux in ord_grads: # plt.figure() # plt.title(ux) # plt.imshow(refss[ux],interpolation='None',cmap='gray') # plt.show(block=False) #sel_ref = int(raw_input("selected mean: ")) #refIm_glob = refss[ord_grads[-1]] refIm_glob = np.mean(np.array(sortImLst),axis=0) if show_ref_mean: plt.figure() plt.title("NEW") plt.imshow(refIm_glob,cmap='binary_r') plt.figure() plt.title("OLD") plt.imshow(refss[ord_grads[-1]],cmap='binary_r') plt.show(block=1) #np.mean(raw_file[:5000],axis=0)#raw_file[ord_[-100]].astype('float') #for i in ord_[-99:]: #image_idx = inp[0] #image = inp[1] #regFile = inp[2] #out=Register_Image.Register_Image(raw_file[i],refIm_glob) #refIm_glob += out[1].astype('float') #refIm_glob /= 100. #plt.imshow(refIm_glob,cmap='gray') #plt.show() refIm_glob = refIm_glob[128:-128,128:-128] refIm_glob = refIm_glob - ndimage.gaussian_filter(refIm_glob,5) elif not common_ref: refIm_glob = None #print 'file open %ss' %(time.time() - st) st = time.time() print '\n registering %s \n' %file_key if not inRAM: regFile = HDF_File[session_ID]['registered_data'].create_dataset(name=file_key, shape=raw_file.shape, chunks=(chunkSize,512,512), dtype='uint16') st = time.time() shifts, tot_shifts = motion_register(raw_file, regFile, maxIter=1, Crop=True, inRAM=inRAM, common_ref=common_ref, refIm_glob=refIm_glob) regFile.attrs['mean_image'] = np.mean(regFile,axis=0) else: #________________________________________________________________ regFile = None regIms, shifts, tot_shifts = motion_register(raw_file, regFile, maxIter=2, Crop=True, inRAM=inRAM, poolSize=16, common_ref=common_ref, refIm_glob=None) print 'Motion Register Duration %ss' %(time.time() - st) #________________________________________________________________ st = time.time() regFile = HDF_File[session_ID]['registered_data'].create_dataset(name=file_key, data=np.round(regIms).astype('uint16'), chunks=(chunkSize,512,512), dtype='uint16') regFile.attrs['mean_image'] = np.mean(regIms.astype('uint16'),axis=0) regFile.attrs['regInfo'] = regData_dir try: regFile.attrs['GRABinfo'] = raw_file.attrs['GRABinfo'] except KeyError: print "Warning could not find GRABinfo file" if 'stimattrs' in raw_file.attrs.keys(): regFile.attrs['stimattrs'] = raw_file.attrs['stimattrs'] if common_ref: regFile.attrs['common_ref'] = True else: regFile.attrs['common_ref'] = False build_registration_log(regFile,abs_loc=regData_dir,tot_shifts=tot_shifts) HDF_File.close() print 'file write in ram %ss' %(time.time() - st) HDF_File = h5py.File(hdfPath,'a',libver='latest') except IOError: print '!!!!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!! \n %s could not be loaded. Skipping \n !!!!!!!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!!!!' %file_key HDF_File.close() #________________________________________________________________ st = time.time() print 'Write to Disk time %ss:' %(time.time() - st) HDF_File = h5py.File(hdfPath,'a',libver='latest') return HDF_File
ystart = int(y*(nr-kerLen)) arr[xstart:xstart+kerLen, ystart:ystart+kerLen] += ker return arr ##Define or import an image. image = make_img(num_obj=8, obj_rad=8, nr=512, nc=512) plt.imshow(image) ## The shift corresponds to the pixel offset relative to the reference image. shift = (-22.4, 13.32) ## fourier_shift(input, shift) = Multi-dimensional fourier shift filter. #The array is multiplied with the fourier transform of a shift operation. #offset_image is a frequency domain shift of reference image. offset_image = fourier_shift(np.fft.fftn(image), shift) # Compute the N-dimensional DFT of an 'image'. offset_image = np.fft.ifftn(offset_image) #Computes the N-dimensional inverse discrete Fourier Transform. print("Known offset (y, x): {}".format(shift)) ## pixel precision first shift, error, diffphase = register_translation(image, offset_image) #Efficient subpixel image #translation registration by cross-correlation. fig = plt.figure(figsize=(8, 3)) ax1 = plt.subplot(1, 3, 1, adjustable='box-forced') ax2 = plt.subplot(1, 3, 2, sharex=ax1, sharey=ax1, adjustable='box-forced') ax3 = plt.subplot(1, 3, 3) ax1.imshow(image, cmap='gray') ax1.set_axis_off() ax1.set_title('Reference image')
def func(x): return -(a[::2,...]*np.fft.ifftn(fourier_shift(np.fft.fftn(a[1::2,...]), [0, x[0]])).real).sum() - (a[2::2,...]*np.fft.ifftn(fourier_shift(np.fft.fftn(a[1:-1:2,...]), [0, x[0]])).real).sum()
def frame_shift(array, shift_y, shift_x, imlib='opencv', interpolation='lanczos4', border_mode='reflect'): """ Shifts a 2D array by shift_y, shift_x. Boundaries are filled with zeros. Parameters ---------- array : array_like Input 2d array. shift_y, shift_x: float Shifts in y and x directions. imlib : {'opencv', 'ndimage-fourier', 'ndimage-interp'}, string optional Library or method used for performing the image shift. 'ndimage-fourier', does a fourier shift operation and preserves better the pixel values (therefore the flux and photometry). Interpolation based shift ('opencv' and 'ndimage-interp') is faster than the fourier shift. 'opencv' is recommended when speed is critical. interpolation : str, optional Only used in case of imlib is set to 'opencv' or 'ndimage-interp' (Scipy.ndimage), where the images are shifted via interpolation. For Scipy.ndimage the options are: 'nearneig', bilinear', 'bicuadratic', 'bicubic', 'biquartic' or 'biquintic'. The 'nearneig' interpolation is the fastest and the 'biquintic' the slowest. The 'nearneig' is the poorer option for interpolation of noisy astronomical images. For Opencv the options are: 'nearneig', 'bilinear', 'bicubic' or 'lanczos4'. The 'nearneig' interpolation is the fastest and the 'lanczos4' the slowest and accurate. 'lanczos4' is the default for Opencv and 'biquartic' for Scipy.ndimage. border_mode : {'reflect', 'nearest', 'constant', 'mirror', 'wrap'} Points outside the boundaries of the input are filled accordingly. With 'reflect', the input is extended by reflecting about the edge of the last pixel. With 'nearest', the input is extended by replicating the last pixel. With 'constant', the input is extended by filling all values beyond the edge with zeros. With 'mirror', the input is extended by reflecting about the center of the last pixel. With 'wrap', the input is extended by wrapping around to the opposite edge. Default is 'reflect'. Returns ------- array_shifted : array_like Shifted 2d array. """ check_array(array, dim=2) image = array.copy() if imlib == 'ndimage-fourier': shift_val = (shift_y, shift_x) array_shifted = fourier_shift(np.fft.fftn(image), shift_val) array_shifted = np.fft.ifftn(array_shifted) array_shifted = array_shifted.real elif imlib == 'ndimage-interp': if interpolation == 'nearneig': order = 0 elif interpolation == 'bilinear': order = 1 elif interpolation == 'bicuadratic': order = 2 elif interpolation == 'bicubic': order = 3 elif interpolation == 'biquartic' or interpolation == 'lanczos4': order = 4 elif interpolation == 'biquintic': order = 5 else: raise ValueError('Scipy.ndimage interpolation method not ' 'recognized') if border_mode not in ['reflect', 'nearest', 'constant', 'mirror', 'wrap']: raise ValueError('`border_mode` not recognized') array_shifted = shift(image, (shift_y, shift_x), order=order, mode=border_mode) elif imlib == 'opencv': if no_opencv: msg = 'Opencv python bindings cannot be imported. Install opencv or' msg += ' set imlib to ndimage-fourier or ndimage-interp' raise RuntimeError(msg) if interpolation == 'bilinear': intp = cv2.INTER_LINEAR elif interpolation == 'bicubic': intp = cv2.INTER_CUBIC elif interpolation == 'nearneig': intp = cv2.INTER_NEAREST elif interpolation == 'lanczos4': intp = cv2.INTER_LANCZOS4 else: raise ValueError('Opencv interpolation method not recognized') if border_mode == 'mirror': bormo = cv2.BORDER_REFLECT_101 # gfedcb|abcdefgh|gfedcba elif border_mode == 'reflect': bormo = cv2.BORDER_REFLECT # fedcba|abcdefgh|hgfedcb elif border_mode == 'wrap': bormo = cv2.BORDER_WRAP # cdefgh|abcdefgh|abcdefg elif border_mode == 'constant': bormo = cv2.BORDER_CONSTANT # iiiiii|abcdefgh|iiiiiii elif border_mode == 'nearest': bormo = cv2.BORDER_REPLICATE # aaaaaa|abcdefgh|hhhhhhh else: raise ValueError('`border_mode` not recognized') image = np.float32(image) y, x = image.shape M = np.float32([[1, 0, shift_x], [0, 1, shift_y]]) array_shifted = cv2.warpAffine(image, M, (x, y), flags=intp, borderMode=bormo) else: raise ValueError('Image transformation library not recognized') return array_shifted
def func(dframe): frame1,frame2 = dframe[0], dframe[1] shift,error,diffphase = register_translation(frame1, frame2, 10) tframe = fourier_shift(np.fft.fftn(frame2), shift) tframe = np.fft.ifftn(tframe) return tframe.real
def patch_register_roi_locs(meanIm1,meanIm2,roiinfo1,im_path,l=32): """ Function that takes as input two mean images and roi coordinates on one of the images and returns the ROI coordinates on a second image Arguments: ============================ meanIm1: np.array mean image with known roi coordinates meanIm2: np.array mean image to map rois onto roiinfo1: dict contains field idxs which is a list of arrays of roi coordinates on meanIm1 l: int size of grid on which to motion register patches """ xsz,ysz = meanIm1.shape mask_num = np.zeros([512,512]) for n_,idxp in enumerate(roiinfo1['idxs']): #if n_ in table[table.columns[1]].tolist(): mask_num[idxp[1],idxp[0]] = n_ nPatch = xsz/float(l) #First register the whole images in rigid fashion to one another out = MP.image_registration.Register_Image(meanIm1,meanIm2[128:-128,128:-128],crop=1) shift_all = out[0] regIm2 = np.fft.ifftn(fourier_shift(np.fft.fftn(meanIm1), shift_all)).real #plt.figure(figsize=(12,12)) #plt.imshow(regIm2,cmap='binary_r',interpolation='None') #pth = os.path.join(im_path,'reg_img'+str(len(os.listdir(im_path)))+'.jpg') #plt.savefig(pth,dpi=100) #plt.clf() rois1 = [] im_pairs = [] roi_pairs = [] roi_locs = cp.deepcopy(roiinfo1['idxs']) moved_rois = [] shifts = [] for i in range(int(nPatch)): sty = i*l for j in range(int(nPatch)): stx = j*l patch = meanIm2[stx:stx+l,sty:sty+l] bigpatch = patch#np.pad(patch,maxShift,mode='median') shift,_,_ = register_translation(bigpatch, regIm2[stx:stx+l,sty:sty+l] ,upsample_factor=5.) #print shift if np.any(shift>30): shift = np.array([0,0]) rois_patch = np.unique(mask_num[stx:stx+l,sty:sty+l]).tolist() for roi in rois_patch: roi = int(roi) if roi not in moved_rois: roi_locs[roi][0] = roi_locs[roi][0] + 1*int(shift[1]) + 1*int(shift_all[1]) roi_locs[roi][1] = roi_locs[roi][1] + 1*int(shift[0]) + 1*int(shift_all[0]) moved_rois = moved_rois + rois_patch return roi_locs,shift_all
"Efficient subpixel image registration algorithms," Optics Letters 33, 156-158 (2008). :DOI:`10.1364/OL.33.000156` """ import numpy as np import matplotlib.pyplot as plt from skimage import data from skimage.feature import register_translation from skimage.feature.register_translation import _upsampled_dft from scipy.ndimage import fourier_shift image = data.camera() shift = (-22.4, 13.32) # The shift corresponds to the pixel offset relative to the reference image offset_image = fourier_shift(np.fft.fftn(image), shift) offset_image = np.fft.ifftn(offset_image) print("Known offset (y, x): {}".format(shift)) # pixel precision first shift, error, diffphase = register_translation(image, offset_image) 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) ax1.imshow(image, cmap='gray') ax1.set_axis_off() ax1.set_title('Reference image')
def shift_stack(a, shift): aOut = np.copy(a) shiftVector = np.zeros(a.ndim, dtype='float') shiftVector[1] = shift aOut[1::2,...] = np.fft.ifftn(fourier_shift(np.fft.fftn(aOut[1::2,...]), shiftVector)).real return aOut