def find_center_vo(tomo, ind=None, smin=-50, smax=50, srad=6, step=0.5, ratio=0.5, drop=20): """ Find rotation axis location using Nghia Vo's method. :cite:`Vo:14`. Parameters ---------- tomo : ndarray 3D tomographic data. ind : int, optional Index of the slice to be used for reconstruction. smin, smax : int, optional Coarse search radius. Reference to the horizontal center of the sinogram. srad : float, optional Fine search radius. step : float, optional Step of fine searching. ratio : float, optional The ratio between the FOV of the camera and the size of object. It's used to generate the mask. drop : int, optional Drop lines around vertical center of the mask. Returns ------- float Rotation axis location. """ tomo = dtype.as_float32(tomo) if ind is None: ind = tomo.shape[1] // 2 _tomo = tomo[:, ind, :] # Enable cache for FFTW. pyfftw.interfaces.cache.enable() # Reduce noise by smooth filters. Use different filters for coarse and fine search _tomo_cs = ndimage.filters.gaussian_filter(_tomo, (3, 1)) _tomo_fs = ndimage.filters.median_filter(_tomo, (2, 2)) # Coarse and fine searches for finding the rotation center. if _tomo.shape[0] * _tomo.shape[1] > 4e6: # If data is large (>2kx2k) _tomo_coarse = downsample(np.expand_dims(_tomo_cs, 1), level=2)[:, 0, :] init_cen = _search_coarse(_tomo_coarse, smin, smax, ratio, drop) fine_cen = _search_fine(_tomo_fs, srad, step, init_cen * 4, ratio, drop) else: init_cen = _search_coarse(_tomo_cs, smin, smax, ratio, drop) fine_cen = _search_fine(_tomo_fs, srad, step, init_cen, ratio, drop) logger.debug('Rotation center search finished: %i', fine_cen) return fine_cen
def find_center_vo(tomo, ind=None, smin=-50, smax=50, srad=6, step=0.25, ratio=0.5, drop=20): """ Find rotation axis location using Nghia Vo's method. :cite:`Vo:14`. Parameters ---------- tomo : ndarray 3D tomographic data. ind : int, optional Index of the slice to be used for reconstruction. smin, smax : int, optional Coarse search radius. Reference to the horizontal center of the sinogram. srad : float, optional Fine search radius. step : float, optional Step of fine searching. ratio : float, optional The ratio between the FOV of the camera and the size of object. It's used to generate the mask. drop : int, optional Drop lines around vertical center of the mask. Returns ------- float Rotation axis location. """ tomo = dtype.as_float32(tomo) (depth, height, width) = tomo.shape if ind is None: ind = height // 2 if height > 10: # Averaging sinograms to improve SNR _tomo = np.mean(tomo[:, ind - 5:ind + 5, :], axis=1) else: _tomo = tomo[:, ind, :] else: _tomo = tomo[:, ind, :] # Denoising # There's a critical reason to use different window sizes # between coarse and fine search. _tomo_cs = ndimage.filters.gaussian_filter(_tomo, (3, 1)) _tomo_fs = ndimage.filters.gaussian_filter(_tomo, (2, 2)) # Coarse and fine searches for finding the rotation center. if _tomo.shape[0] * _tomo.shape[1] > 4e6: # If data is large (>2kx2k) _tomo_coarse = downsample( np.expand_dims(_tomo_cs, 1), level=2)[:, 0, :] init_cen = _search_coarse( _tomo_coarse, smin / 4.0, smax / 4.0, ratio, drop) fine_cen = _search_fine(_tomo_fs, srad, step, init_cen * 4, ratio, drop) else: init_cen = _search_coarse(_tomo_cs, smin, smax, ratio, drop) fine_cen = _search_fine(_tomo_fs, srad, step, init_cen, ratio, drop) logger.debug('Rotation center search finished: %i', fine_cen) return fine_cen
def downsample(self, vol): """Automatically convert the volume to manageable size.""" levels = [] for axis, shape in enumerate(vol.shape): level = int(np.log2(math.ceil(shape / self.max_shape))) levels.append(level) log.debug("Downsampling axis %d (level = %d)", axis, level) if level > 0: vol = downsample(vol, level=level, axis=axis) return vol
def find_center_vo(tomo, ind=None, smin=-50, smax=50, srad=6, step=0.5, ratio=0.5, drop=20): """ Find rotation axis location using Nghia Vo's method. :cite:`Vo:14`. Parameters ---------- tomo : ndarray 3D tomographic data. ind : int, optional Index of the slice to be used for reconstruction. smin, smax : int, optional Coarse search radius. Reference to the horizontal center of the sinogram. srad : float, optional Fine search radius. step : float, optional Step of fine searching. ratio : float, optional The ratio between the FOV of the camera and the size of object. It's used to generate the mask. drop : int, optional Drop lines around vertical center of the mask. Returns ------- float Rotation axis location. """ tomo = dtype.as_float32(tomo) if ind is None: ind = tomo.shape[1] // 2 _tomo = tomo[:, ind, :] # Enable cache for FFTW. pyfftw.interfaces.cache.enable() # Reduce noise by smooth filters. Use different filters for coarse and fine search _tomo_cs = ndimage.filters.gaussian_filter(_tomo, (3, 1)) _tomo_fs = ndimage.filters.median_filter(_tomo, (2, 2)) # Coarse and fine searches for finding the rotation center. if _tomo.shape[0] * _tomo.shape[1] > 4e6: # If data is large (>2kx2k) _tomo_coarse = downsample(np.expand_dims(_tomo_cs,1), level=2)[:, 0, :] init_cen = _search_coarse(_tomo_coarse, smin / 4.0, smax / 4.0, ratio, drop) fine_cen = _search_fine(_tomo_fs, srad, step, init_cen*4, ratio, drop) else: init_cen = _search_coarse(_tomo_cs, smin, smax, ratio, drop) fine_cen = _search_fine(_tomo_fs, srad, step, init_cen, ratio, drop) logger.debug('Rotation center search finished: %i', fine_cen) return fine_cen
def find_center_vo(tomo, ind=None, smin=-40, smax=40, srad=10, step=1, ratio=2., drop=20): """ Find rotation axis location using Nghia Vo's method. :cite:`Vo:14`. Parameters ---------- tomo : ndarray 3D tomographic data. ind : int, optional Index of the slice to be used for reconstruction. smin, smax : int, optional Reference to the horizontal center of the sinogram. srad : float, optional Fine search radius. step : float, optional Step of fine searching. ratio : float, optional The ratio between the FOV of the camera and the size of object. It's used to generate the mask. drop : int, optional Drop lines around vertical center of the mask. Returns ------- float Rotation axis location. """ tomo = dtype.as_float32(tomo) if ind is None: ind = tomo.shape[1] // 2 _tomo = tomo[:, ind, :] # Reduce noise by smooth filtering. _tomo = ndimage.filters.gaussian_filter(_tomo, sigma=(3, 1)) # Coarse search for finiding the roataion center. if _tomo.shape[0] * _tomo.shape[1] > 4e6: # If data is large (>2kx2k) _tomo_coarse = downsample(tomo, level=2)[:, ind, :] init_cen = _search_coarse(_tomo_coarse, smin, smax, ratio, drop) else: init_cen = _search_coarse(_tomo, smin, smax, ratio, drop) # Fine search for finiding the roataion center. fine_cen = _search_fine(_tomo, srad, step, init_cen*4, ratio, drop) logger.debug('Rotation center search finished: %i', fine_cen) return fine_cen
def find_center_vo(tomo, ind=None, smin=-50, smax=50, srad=6, step=0.25, ratio=0.5, drop=20): """ Find rotation axis location using Nghia Vo's method. :cite:`Vo:14`. Parameters ---------- tomo : ndarray 3D tomographic data. ind : int, optional Index of the slice to be used for reconstruction. smin, smax : int, optional Coarse search radius. Reference to the horizontal center of the sinogram. srad : float, optional Fine search radius. step : float, optional Step of fine searching. ratio : float, optional The ratio between the FOV of the camera and the size of object. It's used to generate the mask. drop : int, optional Drop lines around vertical center of the mask. Returns ------- float Rotation axis location. """ tomo = dtype.as_float32(tomo) (depth, height, width) = tomo.shape if ind is None: ind = height // 2 if height > 10: # Averaging sinograms to improve SNR _tomo = np.mean(tomo[:, ind - 5:ind + 5, :], axis=1) else: _tomo = tomo[:, ind, :] else: _tomo = tomo[:, ind, :] # Denoising # There's a critical reason to use different window sizes # between coarse and fine search. _tomo_cs = ndimage.filters.gaussian_filter(_tomo, (3, 1)) _tomo_fs = ndimage.filters.gaussian_filter(_tomo, (2, 2)) # Coarse and fine searches for finding the rotation center. if _tomo.shape[0] * _tomo.shape[1] > 4e6: # If data is large (>2kx2k) _tomo_coarse = downsample(np.expand_dims(_tomo_cs, 1), level=2)[:, 0, :] init_cen = _search_coarse(_tomo_coarse, smin / 4.0, smax / 4.0, ratio, drop) fine_cen = _search_fine(_tomo_fs, srad, step, init_cen * 4, ratio, drop) else: init_cen = _search_coarse(_tomo_cs, smin, smax, ratio, drop) fine_cen = _search_fine(_tomo_fs, srad, step, init_cen, ratio, drop) logger.debug('Rotation center search finished: %i', fine_cen) return fine_cen
def find_center_vo(tomo, ind=None, smin=-40, smax=40, srad=10, step=1, ratio=2., drop=20): """ Find rotation axis location using Nghia Vo's method. :cite:`Vo:14`. Parameters ---------- tomo : ndarray 3D tomographic data. ind : int, optional Index of the slice to be used for reconstruction. smin, smax : int, optional Reference to the horizontal center of the sinogram. srad : float, optional Fine search radius. step : float, optional Step of fine searching. ratio : float, optional The ratio between the FOV of the camera and the size of object. It's used to generate the mask. drop : int, optional Drop lines around vertical center of the mask. Returns ------- float Rotation axis location. Notes ----- The function may not yield a correct estimate, if: - the sample size is bigger than the field of view of the camera. In this case the ``ratio`` argument need to be set larger than the default of 2.0. - there is distortion in the imaging hardware. If there's no correction applied, the center of the projection image may yield a better estimate. - the sample contrast is weak. Paganin's filter need to be applied to overcome this. - there are horizontal stripes in sinogram, which may be induced by some types of detectors. We need to rotate the sinogram image by 90 Degree, apply ring removal, and then rotate it back before calling the function. - the sample was changed during the scan. """ tomo = dtype.as_float32(tomo) if ind is None: ind = tomo.shape[1] // 2 _tomo = tomo[:, ind, :] # Enable cache for FFTW. pyfftw.interfaces.cache.enable() # Reduce noise by smooth filtering. _tomo = ndimage.filters.gaussian_filter(_tomo, sigma=(3, 1)) # Coarse and fine searches for finding the rotation center. if _tomo.shape[0] * _tomo.shape[1] > 4e6: # If data is large (>2kx2k) _tomo_coarse = downsample(tomo, level=2)[:, ind, :] init_cen = _search_coarse(_tomo_coarse, smin, smax, ratio, drop) fine_cen = _search_fine(_tomo, srad, step, init_cen * 4, ratio, drop) else: init_cen = _search_coarse(_tomo, smin, smax, ratio, drop) fine_cen = _search_fine(_tomo, srad, step, init_cen, ratio, drop) logger.debug('Rotation center search finished: %i', fine_cen) return fine_cen
def find_center_vo(tomo, ind=None, smin=-40, smax=40, srad=10, step=1, ratio=2., drop=20): """ Find rotation axis location using Nghia Vo's method. :cite:`Vo:14`. Parameters ---------- tomo : ndarray 3D tomographic data. ind : int, optional Index of the slice to be used for reconstruction. smin, smax : int, optional Reference to the horizontal center of the sinogram. srad : float, optional Fine search radius. step : float, optional Step of fine searching. ratio : float, optional The ratio between the FOV of the camera and the size of object. It's used to generate the mask. drop : int, optional Drop lines around vertical center of the mask. Returns ------- float Rotation axis location. Notes ----- The function may not yield a correct estimate, if: - the sample size is bigger than the field of view of the camera. In this case the ``ratio`` argument need to be set larger than the default of 2.0. - there is distortion in the imaging hardware. If there's no correction applied, the center of the projection image may yield a better estimate. - the sample contrast is weak. Paganin's filter need to be applied to overcome this. - there are horizontal stripes in sinogram, which may be induced by some types of detectors. We need to rotate the sinogram image by 90 Degree, apply ring removal, and then rotate it back before calling the function. - the sample was changed during the scan. """ tomo = dtype.as_float32(tomo) if ind is None: ind = tomo.shape[1] // 2 _tomo = tomo[:, ind, :] # Enable cache for FFTW. pyfftw.interfaces.cache.enable() # Reduce noise by smooth filtering. _tomo = ndimage.filters.gaussian_filter(_tomo, sigma=(3, 1)) # Coarse and fine searches for finding the rotation center. if _tomo.shape[0] * _tomo.shape[1] > 4e6: # If data is large (>2kx2k) _tomo_coarse = downsample(tomo, level=2)[:, ind, :] init_cen = _search_coarse(_tomo_coarse, smin, smax, ratio, drop) fine_cen = _search_fine(_tomo, srad, step, init_cen*4, ratio, drop) else: init_cen = _search_coarse(_tomo, smin, smax, ratio, drop) fine_cen = _search_fine(_tomo, srad, step, init_cen, ratio, drop) logger.debug('Rotation center search finished: %i', fine_cen) return fine_cen