def _search_coarse(sino, smin, smax, ratio, drop): """ Coarse search for finding the rotation center. """ (Nrow, Ncol) = sino.shape centerfliplr = (Ncol - 1.0) / 2.0 # Copy the sinogram and flip left right, the purpose is to # make a full [0;2Pi] sinogram _copy_sino = np.fliplr(sino[1:]) # This image is used for compensating the shift of sinogram 2 temp_img = np.zeros((Nrow - 1, Ncol), dtype='float32') temp_img[:] = np.flipud(sino)[1:] # Start coarse search in which the shift step is 1 listshift = np.arange(smin, smax + 1) listmetric = np.zeros(len(listshift), dtype='float32') mask = _create_mask(2 * Nrow - 1, Ncol, 0.5 * ratio * Ncol, drop) sino_sino = np.vstack((sino, _copy_sino)) abs_fft2_sino = np.empty_like(sino_sino) for i in listshift: _sino = sino_sino[len(sino):] _sino[...] = np.roll(_copy_sino, i, axis=1) if i >= 0: _sino[:, 0:i] = temp_img[:, 0:i] else: _sino[:, i:] = temp_img[:, i:] fft2sino = np.fft.fftshift(fft2(sino_sino)) np.abs(fft2sino, out=abs_fft2_sino) abs_fft2_sino *= mask listmetric[i - smin] = abs_fft2_sino.sum() minpos = np.argmin(listmetric) return centerfliplr + listshift[minpos] / 2.0
def _search_fine(sino, srad, step, init_cen, ratio, drop): """ Fine search for finding the rotation center. """ Nrow, Ncol = sino.shape centerfliplr = (Ncol + 1.0) / 2.0 - 1.0 # Use to shift the sinogram 2 to the raw CoR. shiftsino = np.int16(2 * (init_cen - centerfliplr)) _copy_sino = np.roll(np.fliplr(sino[1:]), shiftsino, axis=1) if init_cen <= centerfliplr: lefttake = np.int16(np.ceil(srad + 1)) righttake = np.int16(np.floor(2 * init_cen - srad - 1)) else: lefttake = np.int16( np.ceil(init_cen - (Ncol - 1 - init_cen) + srad + 1)) righttake = np.int16(np.floor(Ncol - 1 - srad - 1)) Ncol1 = righttake - lefttake + 1 mask = _create_mask(2 * Nrow - 1, Ncol1, 0.5 * ratio * Ncol, drop) numshift = np.int16((2 * srad) / step) + 1 listshift = np.linspace(-srad, srad, num=numshift) listmetric = np.zeros(len(listshift), dtype='float32') factor1 = np.mean(sino[-1, lefttake:righttake]) factor2 = np.mean(_copy_sino[0, lefttake:righttake]) _copy_sino = _copy_sino * factor1 / factor2 num1 = 0 for i in listshift: _sino = ndimage.interpolation.shift(_copy_sino, (0, i), prefilter=False) sinojoin = np.vstack((sino, _sino)) listmetric[num1] = np.sum( np.abs(np.fft.fftshift(fft2(sinojoin[:, lefttake:righttake + 1]))) * mask) num1 = num1 + 1 minpos = np.argmin(listmetric) return init_cen + listshift[minpos] / 2.0
def _2d_filter(mat, win2d, matsign, pad): """ Filtering an image using a 2D window. Parameters ---------- mat : 2D array of floats nrow : int Height of the window. ncol: int Width of the window. sigma: tuple of 2 floats Sigmas of the window. pad : int Padding. Returns ------- Filtered image. """ matpad = np.pad(mat, ((0, 0), (pad, pad)), mode='edge') matpad = np.pad(matpad, ((pad, pad), (0, 0)), mode='mean') (nrow, ncol) = matpad.shape matfilter = np.real(ifft2(fft2(matpad * matsign) * win2d) * matsign) return matfilter[pad:nrow - pad, pad:ncol - pad]
def _search_fine(sino, srad, step, init_cen, ratio, drop): """ Fine search for finding the rotation center. """ (nrow, ncol) = sino.shape cen_fliplr = (ncol - 1.0) / 2.0 srad = np.clip(np.abs(srad), 1.0, ncol / 4.0) step = np.clip(np.abs(step), 0.1, srad) init_cen = np.clip(init_cen, srad, ncol - srad - 1) list_cor = init_cen + np.arange(-srad, srad + step, step) flip_sino = np.fliplr(sino) comp_sino = np.flipud(sino) # Used to avoid local minima list_metric = np.zeros(len(list_cor), dtype=np.float32) mask = _create_mask(2 * nrow, ncol, 0.5 * ratio * ncol, drop) for i, cor in enumerate(list_cor): shift = 2.0 * (cor - cen_fliplr) sino_shift = ndimage.interpolation.shift(flip_sino, (0, shift), order=3, prefilter=True) if shift >= 0: shift_int = np.int16(np.ceil(shift)) sino_shift[:, :shift_int] = comp_sino[:, :shift_int] else: shift_int = np.int16(np.floor(shift)) sino_shift[:, shift_int:] = comp_sino[:, shift_int:] sinojoin = np.vstack((sino, sino_shift)) list_metric[i] = np.mean( np.abs(np.fft.fftshift(fft2(sinojoin))) * mask) cor = list_cor[np.argmin(list_metric)] return cor
def _search_fine(sino, srad, step, init_cen, ratio, drop): """ Fine search for finding the rotation center. """ Nrow, Ncol = sino.shape centerfliplr = (Ncol + 1.0) / 2.0 - 1.0 # Use to shift the sinogram 2 to the raw CoR. shiftsino = np.int16(2 * (init_cen - centerfliplr)) _copy_sino = np.roll(np.fliplr(sino[1:]), shiftsino, axis=1) if init_cen <= centerfliplr: lefttake = np.int16(np.ceil(srad + 1)) righttake = np.int16(np.floor(2 * init_cen - srad - 1)) else: lefttake = np.int16(np.ceil( init_cen - (Ncol - 1 - init_cen) + srad + 1)) righttake = np.int16(np.floor(Ncol - 1 - srad - 1)) Ncol1 = righttake - lefttake + 1 mask = _create_mask(2 * Nrow - 1, Ncol1, 0.5 * ratio * Ncol, drop) numshift = np.int16((2 * srad) / step) + 1 listshift = np.linspace(-srad, srad, num=numshift) listmetric = np.zeros(len(listshift), dtype='float32') factor1 = np.mean(sino[-1, lefttake:righttake]) factor2 = np.mean(_copy_sino[0, lefttake:righttake]) _copy_sino = _copy_sino * factor1 / factor2 num1 = 0 for i in listshift: _sino = ndimage.interpolation.shift( _copy_sino, (0, i), prefilter=False) sinojoin = np.vstack((sino, _sino)) listmetric[num1] = np.sum(np.abs(np.fft.fftshift( fft2( sinojoin[:, lefttake:righttake + 1]))) * mask) num1 = num1 + 1 minpos = np.argmin(listmetric) return init_cen + listshift[minpos] / 2.0
def _calculate_metric(shift_col, sino1, sino2, sino3, mask): """ Metric calculation. """ shift_col = 1.0 * np.squeeze(shift_col) if np.abs(shift_col - np.floor(shift_col)) == 0.0: shift_col = int(shift_col) sino_shift = np.roll(sino2, shift_col, axis=1) if shift_col >= 0: sino_shift[:, :shift_col] = sino3[:, :shift_col] else: sino_shift[:, shift_col:] = sino3[:, shift_col:] mat = np.vstack((sino1, sino_shift)) else: sino_shift = ndimage.interpolation.shift(sino2, (0, shift_col), order=3, prefilter=True) if shift_col >= 0: shift_int = int(np.ceil(shift_col)) sino_shift[:, :shift_int] = sino3[:, :shift_int] else: shift_int = int(np.floor(shift_col)) sino_shift[:, shift_int:] = sino3[:, shift_int:] mat = np.vstack((sino1, sino_shift)) metric = np.mean(np.abs(np.fft.fftshift(fft2(mat))) * mask) return np.asarray([metric], dtype=np.float32)
def _search_fine(sino, srad, step, init_cen, ratio, drop): """ Fine search for finding the rotation center. """ (nrow, ncol) = sino.shape cen_fliplr = (ncol - 1.0) / 2.0 srad = np.clip(np.abs(srad), 1.0, ncol / 4.0) step = np.clip(np.abs(step), 0.1, srad) init_cen = np.clip(init_cen, srad, ncol - srad - 1) list_cor = init_cen + np.arange(-srad, srad + step, step) flip_sino = np.fliplr(sino) comp_sino = np.flipud(sino) # Used to avoid local minima list_metric = np.zeros(len(list_cor), dtype=np.float32) mask = _create_mask(2 * nrow, ncol, 0.5 * ratio * ncol, drop) for i, cor in enumerate(list_cor): shift = 2.0 * (cor - cen_fliplr) sino_shift = ndimage.interpolation.shift( flip_sino, (0, shift), order=3, prefilter=True) if shift >= 0: shift_int = np.int16(np.ceil(shift)) sino_shift[:, :shift_int] = comp_sino[:, :shift_int] else: shift_int = np.int16(np.floor(shift)) sino_shift[:, shift_int:] = comp_sino[:, shift_int:] sinojoin = np.vstack((sino, sino_shift)) list_metric[i] = np.mean(np.abs( np.fft.fftshift(fft2(sinojoin))) * mask) cor = list_cor[np.argmin(list_metric)] return cor
def _retrieve_phase(tomo, phase_filter, px, py, prj, pad): dx, dy, dz = tomo.shape num_jobs = tomo.shape[0] normalized_phase_filter = phase_filter / phase_filter.max() for m in range(num_jobs): prj[px:dy + px, py:dz + py] = tomo[m] prj[:px] = prj[px] prj[-px:] = prj[-px-1] prj[:, :py] = prj[:, py][:, np.newaxis] prj[:, -py:] = prj[:, -py-1][:, np.newaxis] fproj = fft2(prj, extra_info=num_jobs) fproj *= normalized_phase_filter proj = np.real(ifft2(fproj, extra_info=num_jobs, overwrite_input=True)) if pad: proj = proj[px:dy + px, py:dz + py] tomo[m] = proj
def _search_coarse(sino, smin, smax, ratio, drop): """ Coarse search for finding the rotation center. """ (nrow, ncol) = sino.shape cen_fliplr = (ncol - 1.0) / 2.0 smin = np.int16(np.clip(smin + cen_fliplr, 0, ncol - 1) - cen_fliplr) smax = np.int16(np.clip(smax + cen_fliplr, 0, ncol - 1) - cen_fliplr) # Flip left-right the [0:Pi ] sinogram to make a full [0;2Pi] sinogram flip_sino = np.fliplr(sino) # Below image is used for compensating the shift of the [Pi;2Pi] sinogram # It helps to avoid local minima. comp_sino = np.flipud(sino) list_shift = np.arange(smin, smax + 1) list_metric = np.zeros(len(list_shift), dtype='float32') mask = _create_mask(2 * nrow, ncol, 0.5 * ratio * ncol, drop) sino_sino = np.vstack((sino, flip_sino)) abs_fft2_sino = np.empty_like(sino_sino) for i in list_shift: _sino = sino_sino[nrow:] _sino[...] = np.roll(flip_sino, i, axis=1) if i >= 0: _sino[:, 0:i] = comp_sino[:, 0:i] else: _sino[:, i:] = comp_sino[:, i:] fft2sino = np.fft.fftshift(fft2(sino_sino)) np.abs(fft2sino, out=abs_fft2_sino) abs_fft2_sino *= mask list_metric[i - smin] = abs_fft2_sino.mean() minpos = np.argmin(list_metric) if minpos == 0: logger.debug('WARNING!!!Global minimum is out of searching range') logger.debug('Please extend smin: %i', smin) if minpos == len(list_metric) - 1: logger.debug('WARNING!!!Global minimum is out of searching range') logger.debug('Please extend smax: %i', smax) init_cen = cen_fliplr + list_shift[minpos] / 2.0 return init_cen