def _adjust_hist_limits(tomo, theta, ind, mask, emission): # Make an initial reconstruction to adjust histogram limits. rec = recon(tomo, theta, emission=emission, algorithm='gridrec') # Apply circular mask. if mask is True: rec = circ_mask(rec, axis=0) # Adjust histogram boundaries according to reconstruction. return _adjust_hist_min(rec.min()), _adjust_hist_max(rec.max())
def _adjust_hist_limits(tomo_ind, theta, mask, sinogram_order): # Make an initial reconstruction to adjust histogram limits. rec = recon( tomo_ind, theta, sinogram_order=sinogram_order, algorithm=algorithm, filter_name=filter_name, ) # Apply circular mask. if mask is True: rec = circ_mask(rec, axis=0) # Adjust histogram boundaries according to reconstruction. return _adjust_hist_min(rec.min()), _adjust_hist_max(rec.max())
def _find_center_cost( center, tomo, theta, ind, hmin, hmax, mask, ratio, emission): """ Cost function used for the ``find_center`` routine. """ logger.info('Trying center: %s', center) center = np.array(center, dtype='float32') rec = recon( tomo[:, ind:ind + 1, :], theta, center, emission=emission, algorithm='gridrec') if mask is True: rec = circ_mask(rec, axis=0) hist, e = np.histogram(rec, bins=64, range=[hmin, hmax]) hist = hist.astype('float32') / rec.size + 1e-12 return -np.dot(hist, np.log2(hist))
def _find_center_cost(center, tomo, theta, ind, hmin, hmax, mask, ratio, emission): """ Cost function used for the ``find_center`` routine. """ logger.info('Trying center: %s', center) center = np.array(center, dtype='float32') rec = recon(tomo[:, ind:ind + 1, :], theta, center, emission=emission, algorithm='gridrec') if mask is True: rec = circ_mask(rec, axis=0) hist, e = np.histogram(rec, bins=64, range=[hmin, hmax]) hist = hist.astype('float32') / rec.size + 1e-12 return -np.dot(hist, np.log2(hist))
def _find_center_cost( center, tomo_ind, theta, hmin, hmax, mask, ratio, sinogram_order=False): """ Cost function used for the ``find_center`` routine. """ logger.info('Trying rotation center: %s', center) center = np.array(center, dtype='float32') rec = recon( tomo_ind, theta, center, sinogram_order=sinogram_order, algorithm='gridrec') if mask is True: rec = circ_mask(rec, axis=0) hist, e = np.histogram(rec, bins=64, range=[hmin, hmax]) hist = hist.astype('float32') / rec.size + 1e-12 val = -np.dot(hist, np.log2(hist)) logger.info("Function value = %f"%val) return val
def _find_center_cost( center, tomo_ind, theta, hmin, hmax, mask, ratio, sinogram_order=False): """ Cost function used for the ``find_center`` routine. """ logger.warn('Trying center: %s', center) center = np.array(center, dtype='float32') rec = recon( tomo_ind, theta, center, sinogram_order=sinogram_order, algorithm='gridrec') if mask is True: rec = circ_mask(rec, axis=0) hist, e = np.histogram(rec, bins=64, range=[hmin, hmax]) hist = hist.astype('float32') / rec.size + 1e-12 val = -np.dot(hist, np.log2(hist)) logger.warn("val = %f"%val) return val
def write_center( tomo, theta, dpath='tmp/center', cen_range=None, ind=None, emission=True, mask=False, ratio=1.): """ Save images reconstructed with a range of rotation centers. Helps finding the rotation center manually by visual inspection of images reconstructed with a set of different centers.The output images are put into a specified folder and are named by the center position corresponding to the image. Parameters ---------- tomo : ndarray 3D tomographic data. theta : array Projection angles in radian. dpath : str, optional Folder name to save output images. cen_range : list, optional [start, end, step] Range of center values. ind : int, optional Index of the slice to be used for reconstruction. emission : bool, optional Determines whether data is emission or transmission type. mask : bool, optional If ``True``, apply a circular mask to the reconstructed image to limit the analysis into a circular region. ratio : float, optional The ratio of the radius of the circular mask to the edge of the reconstructed image. """ tomo = dtype.as_float32(tomo) theta = dtype.as_float32(theta) dx, dy, dz = tomo.shape if ind is None: ind = dy // 2 if cen_range is None: center = np.arange(dz / 2 - 5, dz / 2 + 5, 0.5) if len(cen_range) < 3: cen_range[2] = 1 else: center = np.arange(cen_range[0], cen_range[1], cen_range[2] / 2.) stack = np.zeros((dx, len(center), dz)) for m in range(center.size): stack[:, m, :] = tomo[:, ind, :] # Reconstruct the same slice with a range of centers. rec = recon( stack, theta, center=center, emission=emission, algorithm='gridrec') # Apply circular mask. if mask is True: rec = circ_mask(rec, axis=0) # Save images to a temporary folder. for m in range(len(center)): if m % 2 == 0: # 2 slices same bec of gridrec. fname = os.path.join( dpath, str('{0:.2f}'.format(center[m]) + '.tiff')) write_tiff(rec[m:m + 1], fname=fname, overwrite=True)
def write_center(tomo, theta, dpath='tmp/center', cen_range=None, ind=None, mask=False, ratio=1., sinogram_order=False, algorithm='gridrec', filter_name='parzen'): """ Save images reconstructed with a range of rotation centers. Helps finding the rotation center manually by visual inspection of images reconstructed with a set of different centers.The output images are put into a specified folder and are named by the center position corresponding to the image. Parameters ---------- tomo : ndarray 3D tomographic data. theta : array Projection angles in radian. dpath : str, optional Folder name to save output images. cen_range : list, optional [start, end, step] Range of center values. ind : int, optional Index of the slice to be used for reconstruction. mask : bool, optional If ``True``, apply a circular mask to the reconstructed image to limit the analysis into a circular region. ratio : float, optional The ratio of the radius of the circular mask to the edge of the reconstructed image. sinogram_order: bool, optional Determins whether data is a stack of sinograms (True, y-axis first axis) or a stack of radiographs (False, theta first axis). algorithm : {str, function} One of the following string values. 'art' Algebraic reconstruction technique :cite:`Kak:98`. 'bart' Block algebraic reconstruction technique. 'fbp' Filtered back-projection algorithm. 'gridrec' Fourier grid reconstruction algorithm :cite:`Dowd:99`, :cite:`Rivers:06`. 'mlem' Maximum-likelihood expectation maximization algorithm :cite:`Dempster:77`. 'osem' Ordered-subset expectation maximization algorithm :cite:`Hudson:94`. 'ospml_hybrid' Ordered-subset penalized maximum likelihood algorithm with weighted linear and quadratic penalties. 'ospml_quad' Ordered-subset penalized maximum likelihood algorithm with quadratic penalties. 'pml_hybrid' Penalized maximum likelihood algorithm with weighted linear and quadratic penalties :cite:`Chang:04`. 'pml_quad' Penalized maximum likelihood algorithm with quadratic penalty. 'sirt' Simultaneous algebraic reconstruction technique. 'tv' Total Variation reconstruction technique :cite:`Chambolle:11`. 'grad' Gradient descent method with a constant step size filter_name : str, optional Name of the filter for analytic reconstruction. 'none' No filter. 'shepp' Shepp-Logan filter (default). 'cosine' Cosine filter. 'hann' Cosine filter. 'hamming' Hamming filter. 'ramlak' Ram-Lak filter. 'parzen' Parzen filter. 'butterworth' Butterworth filter. 'custom' A numpy array of size `next_power_of_2(num_detector_columns)/2` specifying a custom filter in Fourier domain. The first element of the filter should be the zero-frequency component. 'custom2d' A numpy array of size `num_projections*next_power_of_2(num_detector_columns)/2` specifying a custom angle-dependent filter in Fourier domain. The first element of each filter should be the zero-frequency component. """ tomo = dtype.as_float32(tomo) theta = dtype.as_float32(theta) if sinogram_order: dy, dt, dx = tomo.shape else: dt, dy, dx = tomo.shape if ind is None: ind = dy // 2 if cen_range is None: center = np.arange(dx / 2 - 5, dx / 2 + 5, 0.5) else: center = np.arange(*cen_range) stack = dtype.empty_shared_array((len(center), dt, dx)) for m in range(center.size): if sinogram_order: stack[m] = tomo[ind] else: stack[m] = tomo[:, ind, :] # Reconstruct the same slice with a range of centers. rec = recon(stack, theta, center=center, sinogram_order=True, algorithm=algorithm, filter_name=filter_name, nchunk=1) # Apply circular mask. if mask is True: rec = circ_mask(rec, axis=0) # Save images to a temporary folder. for m in range(len(center)): fname = os.path.join(dpath, str('{0:.2f}'.format(center[m]) + '.tiff')) dxchange.write_tiff(rec[m], fname=fname, overwrite=True)
def write_center( tomo, theta, dpath='tmp/center', cen_range=None, ind=None, mask=False, ratio=1., sinogram_order=False): """ Save images reconstructed with a range of rotation centers. Helps finding the rotation center manually by visual inspection of images reconstructed with a set of different centers.The output images are put into a specified folder and are named by the center position corresponding to the image. Parameters ---------- tomo : ndarray 3D tomographic data. theta : array Projection angles in radian. dpath : str, optional Folder name to save output images. cen_range : list, optional [start, end, step] Range of center values. ind : int, optional Index of the slice to be used for reconstruction. mask : bool, optional If ``True``, apply a circular mask to the reconstructed image to limit the analysis into a circular region. ratio : float, optional The ratio of the radius of the circular mask to the edge of the reconstructed image. sinogram_order: bool, optional Determins whether data is a stack of sinograms (True, y-axis first axis) or a stack of radiographs (False, theta first axis). """ tomo = dtype.as_float32(tomo) theta = dtype.as_float32(theta) if sinogram_order: dy, dt, dx = tomo.shape else: dt, dy, dx = tomo.shape if ind is None: ind = dy // 2 if cen_range is None: center = np.arange(dx / 2 - 5, dx / 2 + 5, 0.5) else: center = np.arange(*cen_range) stack = dtype.empty_shared_array((len(center), dt, dx)) for m in range(center.size): if sinogram_order: stack[m] = tomo[ind] else: stack[m] = tomo[:, ind, :] # Reconstruct the same slice with a range of centers. rec = recon(stack, theta, center=center, sinogram_order=True, algorithm='gridrec', nchunk=1) # Apply circular mask. if mask is True: rec = circ_mask(rec, axis=0) # Save images to a temporary folder. for m in range(len(center)): fname = os.path.join( dpath, str('{0:.2f}'.format(center[m]) + '.tiff')) dxchange.write_tiff(rec[m], fname=fname, overwrite=True)
def write_center( tomo, theta, dpath='tmp/center', cen_range=None, ind=None, mask=False, ratio=1., sinogram_order=False, algorithm='gridrec', filter_name='parzen'): """ Save images reconstructed with a range of rotation centers. Helps finding the rotation center manually by visual inspection of images reconstructed with a set of different centers.The output images are put into a specified folder and are named by the center position corresponding to the image. Parameters ---------- tomo : ndarray 3D tomographic data. theta : array Projection angles in radian. dpath : str, optional Folder name to save output images. cen_range : list, optional [start, end, step] Range of center values. ind : int, optional Index of the slice to be used for reconstruction. mask : bool, optional If ``True``, apply a circular mask to the reconstructed image to limit the analysis into a circular region. ratio : float, optional The ratio of the radius of the circular mask to the edge of the reconstructed image. sinogram_order: bool, optional Determins whether data is a stack of sinograms (True, y-axis first axis) or a stack of radiographs (False, theta first axis). algorithm : {str, function} One of the following string values. 'art' Algebraic reconstruction technique :cite:`Kak:98`. 'bart' Block algebraic reconstruction technique. 'fbp' Filtered back-projection algorithm. 'gridrec' Fourier grid reconstruction algorithm :cite:`Dowd:99`, :cite:`Rivers:06`. 'mlem' Maximum-likelihood expectation maximization algorithm :cite:`Dempster:77`. 'osem' Ordered-subset expectation maximization algorithm :cite:`Hudson:94`. 'ospml_hybrid' Ordered-subset penalized maximum likelihood algorithm with weighted linear and quadratic penalties. 'ospml_quad' Ordered-subset penalized maximum likelihood algorithm with quadratic penalties. 'pml_hybrid' Penalized maximum likelihood algorithm with weighted linear and quadratic penalties :cite:`Chang:04`. 'pml_quad' Penalized maximum likelihood algorithm with quadratic penalty. 'sirt' Simultaneous algebraic reconstruction technique. 'tv' Total Variation reconstruction technique :cite:`Chambolle:11`. 'grad' Gradient descent method with a constant step size filter_name : str, optional Name of the filter for analytic reconstruction. 'none' No filter. 'shepp' Shepp-Logan filter (default). 'cosine' Cosine filter. 'hann' Cosine filter. 'hamming' Hamming filter. 'ramlak' Ram-Lak filter. 'parzen' Parzen filter. 'butterworth' Butterworth filter. 'custom' A numpy array of size `next_power_of_2(num_detector_columns)/2` specifying a custom filter in Fourier domain. The first element of the filter should be the zero-frequency component. 'custom2d' A numpy array of size `num_projections*next_power_of_2(num_detector_columns)/2` specifying a custom angle-dependent filter in Fourier domain. The first element of each filter should be the zero-frequency component. """ tomo = dtype.as_float32(tomo) theta = dtype.as_float32(theta) if sinogram_order: dy, dt, dx = tomo.shape else: dt, dy, dx = tomo.shape if ind is None: ind = dy // 2 if cen_range is None: center = np.arange(dx / 2 - 5, dx / 2 + 5, 0.5) else: center = np.arange(*cen_range) stack = dtype.empty_shared_array((len(center), dt, dx)) for m in range(center.size): if sinogram_order: stack[m] = tomo[ind] else: stack[m] = tomo[:, ind, :] # Reconstruct the same slice with a range of centers. rec = recon(stack, theta, center=center, sinogram_order=True, algorithm=algorithm, filter_name=filter_name, nchunk=1) # Apply circular mask. if mask is True: rec = circ_mask(rec, axis=0) # Save images to a temporary folder. dpath = os.path.abspath(dpath) if not os.path.exists(dpath): os.makedirs(dpath) for m in range(len(center)): fname = os.path.join( dpath, str('{0:.2f}'.format(center[m]) + '.tiff')) tifffile.imsave(file=fname, data=rec[m])
def write_center(tomo, theta, dpath='tmp/center', cen_range=None, ind=None, emission=True, mask=False, ratio=1.): """ Save images reconstructed with a range of rotation centers. Helps finding the rotation center manually by visual inspection of images reconstructed with a set of different centers.The output images are put into a specified folder and are named by the center position corresponding to the image. Parameters ---------- tomo : ndarray 3D tomographic data. theta : array Projection angles in radian. dpath : str, optional Folder name to save output images. cen_range : list, optional [start, end, step] Range of center values. ind : int, optional Index of the slice to be used for reconstruction. emission : bool, optional Determines whether data is emission or transmission type. mask : bool, optional If ``True``, apply a circular mask to the reconstructed image to limit the analysis into a circular region. ratio : float, optional The ratio of the radius of the circular mask to the edge of the reconstructed image. """ tomo = dtype.as_float32(tomo) theta = dtype.as_float32(theta) dx, dy, dz = tomo.shape if ind is None: ind = dy // 2 if cen_range is None: center = np.arange(dz / 2 - 5, dz / 2 + 5, 0.5) if len(cen_range) < 3: cen_range[2] = 1 else: center = np.arange(cen_range[0], cen_range[1], cen_range[2] / 2.) stack = np.zeros((dx, len(center), dz)) for m in range(center.size): stack[:, m, :] = tomo[:, ind, :] # Reconstruct the same slice with a range of centers. rec = recon(stack, theta, center=center, emission=emission, algorithm='gridrec') # Apply circular mask. if mask is True: rec = circ_mask(rec, axis=0) # Save images to a temporary folder. for m in range(len(center)): if m % 2 == 0: # 2 slices same bec of gridrec. fname = os.path.join(dpath, str('{0:.2f}'.format(center[m]) + '.tiff')) write_tiff(rec[m:m + 1], fname=fname, overwrite=True)