def adaptive_segment(args): """ Applies an adaptive threshold to reconstructed data. Also known as local or dynamic thresholding where the threshold value is the weighted mean for the local neighborhood of a pixel subtracted by constant. Alternatively the threshold can be determined dynamically by a given function using the 'generic' method. Parameters ---------- data : ndarray, float32 3-D reconstructed data with dimensions: [slices, pixels, pixels] block_size : scalar, int Uneven size of pixel neighborhood which is used to calculate the threshold value (e.g. 3, 5, 7, ..., 21, ...). offset : scalar, float Constant subtracted from weighted mean of neighborhood to calculate the local threshold value. Default offset is 0. Returns ------- output : ndarray Thresholded data. References ---------- - `http://scikit-image.org/docs/dev/auto_examples/plot_threshold_adaptive.html \ <http://scikit-image.org/docs/dev/auto_examples/plot_threshold_adaptive.html>`_ """ # Arguments passed by multi-processing wrapper ind, dshape, inputs = args # Function inputs data = mp.tonumpyarray(mp.shared_arr, dshape) # shared-array block_size, offset = inputs for m in ind: img = data[m, :, :] # Perform scikit adaptive thresholding. img = threshold_adaptive(img, block_size=block_size, offset=offset) # Remove small white regions img = ndimage.binary_opening(img) # Remove small black holes img = ndimage.binary_closing(img) data[m, :, :] = img
def median_filter(args): """ Apply median filter to data. Parameters ---------- data : ndarray 3-D tomographic data with dimensions: [projections, slices, pixels] size : scalar The size of the filter. Returns ------- output : ndarray Median filtered data. Examples -------- - Apply median-filter to sinograms: >>> import tomopy >>> >>> # Load data >>> myfile = 'demo/data.h5' >>> data, white, dark, theta = tomopy.xtomo_reader(myfile, slices_start=0, slices_end=1) >>> >>> # Save data before filtering >>> output_file='tmp/before_filtering_' >>> tomopy.xtomo_writer(data, output_file, axis=1) >>> print "Images are succesfully saved at " + output_file + '...' >>> >>> # Construct tomo object >>> d = tomopy.xtomo_dataset(log='error') >>> d.dataset(data, white, dark, theta) >>> >>> # Perform filtering >>> d.median_filter() >>> >>> # Save data after filtering >>> output_file='tmp/after_filtering_' >>> tomopy.xtomo_writer(d.data, output_file, axis=1) >>> print "Images are succesfully saved at " + output_file + '...' """ # Arguments passed by multi-processing wrapper ind, dshape, inputs = args # Function inputs data = mp.tonumpyarray(mp.shared_arr, dshape) # shared-array size = inputs for m in ind: data[:, m, :] = filters.median_filter(data[:, m, :], (1, size))
def threshold_segment(args): """ Applies threshold based on Otsu's method to reconstructed data. Otsu’s method calculates an “optimal” threshold (marked by a red line in the histogram below) by maximizing the variance between two classes of pixels, which are separated by the threshold. Equivalently, this threshold minimizes the intra-class variance. Parameters ---------- data : ndarray, float32 3-D reconstructed data with dimensions: [slices, pixels, pixels] cutoff : scalar, int Manually selected threshold value. Returns ------- output : ndarray Thresholded data. References ---------- - `http://en.wikipedia.org/wiki/Otsu’s_method \ <http://en.wikipedia.org/wiki/Otsu’s_method>`_ - `http://scikit-image.org/docs/dev/auto_examples/plot_otsu.html#example-plot-otsu-py \ <http://scikit-image.org/docs/dev/auto_examples/plot_otsu.html#example-plot-otsu-py>`_ """ # Arguments passed by multi-processing wrapper ind, dshape, inputs = args # Function inputs data = mp.tonumpyarray(mp.shared_arr, dshape) # shared-array cutoff = inputs for m in ind: img = data[m, :, :] if cutoff is None: cutoff = threshold_otsu(img) img = img > cutoff data[m, :, :] = img
def threshold_segment(args): """ Applies threshold based on Otsu's method to reconstructed data. Otsu’s method calculates an “optimal” threshold (marked by a red line in the histogram below) by maximizing the variance between two classes of pixels, which are separated by the threshold. Equivalently, this threshold minimizes the intra-class variance. Parameters ---------- data : ndarray, float32 3-D reconstructed data with dimensions: [slices, pixels, pixels] cutoff : scalar, int Manually selected threshold value. Returns ------- output : ndarray Thresholded data. References ---------- - `http://en.wikipedia.org/wiki/Otsu’s_method \ <http://en.wikipedia.org/wiki/Otsu’s_method>`_ - `http://scikit-image.org/docs/dev/auto_examples/plot_otsu.html#example-plot-otsu-py \ <http://scikit-image.org/docs/dev/auto_examples/plot_otsu.html#example-plot-otsu-py>`_ """ # Arguments passed by multi-processing wrapper ind, dshape, inputs = args # Function inputs data = mp.tonumpyarray(mp.shared_arr, dshape) # shared-array cutoff = inputs for m in ind: img = data[m, :, :] if cutoff == None: cutoff = threshold_otsu(img) img = img > cutoff data[m, :, :] = img
def remove_background(args): """ Remove background from reconstructed data. We use morphological reconstruction to create a background image, which we can subtract from the original image to isolate bright features. Parameters ---------- data : ndarray, float32 3-D reconstructed data with dimensions: [slices, pixels, pixels] Returns ------- output : ndarray Background removed data. References ---------- - `http://scikit-image.org/docs/dev/auto_examples/plot_regional_maxima.html \ <http://scikit-image.org/docs/dev/auto_examples/plot_regional_maxima.html>`_ """ # Arguments passed by multi-processing wrapper ind, dshape, inputs = args # Function inputs data = mp.tonumpyarray(mp.shared_arr, dshape) # shared-array for m in ind: img = data[m, :, :] # first remove background. seed = np.copy(img) seed[1:-1, 1:-1] = img.min() img -= reconstruction(seed, img, method='dilation') data[m, :, :] = img
def region_segment(args): """ Applies an region-based segementation to reconstructed data. Parameters ---------- data : ndarray, float32 3-D reconstructed data with dimensions: [slices, pixels, pixels] low : scalar, int Lowest value for the marker. high : scalar, int Higest value for the marker. Returns ------- output : ndarray Segmented data. """ # Arguments passed by multi-processing wrapper ind, dshape, inputs = args # Function inputs data = mp.tonumpyarray(mp.shared_arr, dshape) # shared-array low, high = inputs for m in ind: img = data[m, :, :] elevation_map = sobel(img) markers = np.zeros_like(img) markers[img < low] = 1 markers[img > high] = 2 img = morphology.watershed(elevation_map, markers) data[m, :, :] = img
def zinger_removal(args): """ Zinger removal. Parameters ---------- data : ndarray 3-D tomographic data with dimensions: [projections, slices, pixels] zinger_level : scalar Threshold of counts to cut zingers. median_width : scalar Median filter width. Returns ------- output : ndarray Zinger removed data. Examples -------- - Remove zingers: >>> import tomopy >>> import numpy as np >>> >>> # Load data >>> myfile = 'demo/data.h5' >>> data, white, dark, theta = tomopy.xtomo_reader(myfile, slices_start=0, slices_end=1) >>> >>> # Add some artificial zingers to data >>> ind = np.random.randint(low=0, high=1005, size=data.shape) >>> data[ind>1000] = 2000 >>> >>> # Save data before zinger removal >>> output_file='tmp/before_zinger_' >>> tomopy.xtomo_writer(data, output_file, axis=1) >>> print "Images are succesfully saved at " + output_file + '...' >>> >>> # Construct tomo object >>> d = tomopy.xtomo_dataset(log='error') >>> d.dataset(data, white, dark, theta) >>> >>> # Perform zinger removal >>> d.zinger_removal(median_width=10) >>> >>> # Save data after zinger removal >>> output_file='tmp/after_zinger_' >>> tomopy.xtomo_writer(d.data, output_file, axis=1) >>> print "Images are succesfully saved at " + output_file + '...' """ # Arguments passed by multi-processing wrapper ind, dshape, inputs = args # Function inputs data = mp.tonumpyarray(mp.shared_arr, dshape) # shared-array zinger_level, median_width = inputs zinger_mask = np.zeros((1, data.shape[1], data.shape[2])) for m in ind: tmp_img = filters.median_filter(data[m, :, :], (median_width, median_width)) zinger_mask = ((data[m, :, :] - tmp_img) >= zinger_level).astype(int) data[m, :, :] = tmp_img * zinger_mask + data[m, :, :] * (1 - zinger_mask)
def normalize(args): """ Normalize raw projection data with the white field projection data. Parameters ---------- data : ndarray 3-D tomographic data with dimensions: [projections, slices, pixels] data_white : ndarray 2-D white field projection data. data_dark : ndarray 2-D dark field projection data. cutoff : scalar Permitted maximum vaue of the normalized data. Returns ------- data : ndarray Normalized data. Examples -------- - Normalize using white and dark fields: >>> import tomopy >>> >>> # Load sinogram >>> myfile = 'demo/data.h5' >>> data, white, dark, theta = tomopy.xtomo_reader(myfile, slices_start=0, slices_end=1) >>> >>> # Save sinogram before normalization >>> output_file='tmp/before_normalization_' >>> tomopy.xtomo_writer(data, output_file, axis=1) >>> print "Images are succesfully saved at " + output_file + '...' >>> >>> # Construct tomo object >>> d = tomopy.xtomo_dataset(log='error') >>> d.dataset(data, white, dark, theta) >>> >>> # Perform normalization >>> d.normalize() >>> >>> # Save sinogram after normalization >>> output_file='tmp/after_normalization_' >>> tomopy.xtomo_writer(d.data, output_file, axis=1) >>> print "Images are succesfully saved at " + output_file + '...' """ # Arguments passed by multi-processing wrapper ind, dshape, inputs = args # Function inputs data = mp.tonumpyarray(mp.shared_arr, dshape) # shared-array data_white, data_dark, cutoff = inputs for m in ind: data[m, :, :] = np.divide(data[m, :, :]-data_dark, data_white-data_dark) if cutoff is not None: data[data > cutoff] = cutoff
def normalize(args): """ Normalize raw projection data with the white field projection data. Parameters ---------- data : ndarray 3-D tomographic data with dimensions: [projections, slices, pixels] data_white : ndarray 2-D white field projection data. data_dark : ndarray 2-D dark field projection data. cutoff : scalar Permitted maximum vaue of the normalized data. negvals : scalar Assigns new value to the nonpositive values after normalization. Returns ------- data : ndarray Normalized data. Examples -------- - Normalize using white and dark fields: >>> import tomopy >>> >>> # Load sinogram >>> myfile = 'demo/data.h5' >>> data, white, dark, theta = tomopy.xtomo_reader(myfile, slices_start=0, slices_end=1) >>> >>> # Save sinogram before normalization >>> output_file='tmp/before_normalization_' >>> tomopy.xtomo_writer(data, output_file, axis=1) >>> print "Images are succesfully saved at " + output_file + '...' >>> >>> # Construct tomo object >>> d = tomopy.xtomo_dataset(log='error') >>> d.dataset(data, white, dark, theta) >>> >>> # Perform normalization >>> d.normalize() >>> >>> # Save sinogram after normalization >>> output_file='tmp/after_normalization_' >>> tomopy.xtomo_writer(d.data, output_file, axis=1) >>> print "Images are succesfully saved at " + output_file + '...' """ # Arguments passed by multi-processing wrapper ind, dshape, inputs = args # Function inputs data = mp.tonumpyarray(mp.shared_arr, dshape) # shared-array data_white, data_dark, cutoff, negvals = inputs # Avoid zero division in normalization denominator = data_white - data_dark denominator[denominator == 0] = 1 for m in ind: proj = data[m, :, :] proj = np.divide(proj - data_dark, denominator) proj[proj <= 0] = negvals if cutoff is not None: proj[proj > cutoff] = cutoff data[m, :, :] = proj
def phase_retrieval(args): """ Perform single-material phase retrieval using projection data. Parameters ---------- data : ndarray 3-D tomographic data with dimensions: [projections, slices, pixels] pixel_size : scalar Detector pixel size in cm. dist : scalar Propagation distance of x-rays in cm. energy : scalar Energy of x-rays in keV. alpha : scalar, optional Regularization parameter. padding : bool, optional Applies padding for Fourier transform. For quick testing you can use False for faster results. Returns ------- phase : ndarray Retrieved phase. References ---------- - `J. of Microscopy, Vol 206(1), 33-40, 2001 \ <http://onlinelibrary.wiley.com/doi/10.1046/j.1365-2818.2002.01010.x/abstract>`_ Examples -------- - Phase retrieval: >>> import tomopy >>> >>> # Load data >>> myfile = 'demo/data.h5' >>> data, white, dark, theta = tomopy.xtomo_reader(myfile) >>> >>> # Construct tomo object >>> d = tomopy.xtomo_dataset(log='error') >>> d.dataset(data, white, dark, theta) >>> d.normalize() >>> >>> # Reconstruct data before phase retrieval >>> d.center=661.5 >>> d.gridrec() >>> >>> # Save reconstructed data before phase retrieval >>> output_file='tmp/before_phase_retrieval_' >>> tomopy.xtomo_writer(d.data_recon, output_file) >>> print "Images are succesfully saved at " + output_file + '...' >>> >>> # Reconstruct data after phase retrieval >>> d.phase_retrieval(pixel_size=1e-4, dist=70, energy=20) >>> d.gridrec() >>> >>> # Save reconstructed data after phase retrieval >>> output_file='tmp/after_phase_retrieval_' >>> tomopy.xtomo_writer(d.data_recon, output_file) >>> print "Images are succesfully saved at " + output_file + '...' """ # Arguments passed by multi-processing wrapper ind, dshape, inputs = args # Function inputs data = mp.tonumpyarray(mp.shared_arr, dshape) # shared-array pixel_size, dist, energy, alpha, padding = inputs # Compute the filter. H, x_shift, y_shift, tmp_proj = paganin_filter(data, pixel_size, dist, energy, alpha, padding) num_proj, dx, dy = dshape # dx:slices, dy:pixels for m in ind: proj = data[m, :, :] if padding: tmp_proj[x_shift:dx + x_shift, y_shift:dy + y_shift] = proj fft_proj = fftw.fftw2(tmp_proj) filtered_proj = np.multiply(H, fft_proj) tmp = np.real(fftw.ifftw2(filtered_proj)) / np.max(H) proj = tmp[x_shift:dx + x_shift, y_shift:dy + y_shift] elif not padding: fft_proj = fftw.fftw2(proj) filtered_proj = np.multiply(H, fft_proj) proj = np.real(fftw.ifftw2(filtered_proj)) / np.max(H) data[m, :, :] = proj
def stripe_removal2(args): """ Remove stripes from sinogram data. Parameters ---------- data : ndarray 3-D tomographic data with dimensions: [projections, slices, pixels] nblocks : scalar Number of blocks alpha : scalar Damping factor. Returns ------- output : ndarray Corrected data. References ---------- - `J. Synchrotron Rad. (2014). 21, 1333–1346 \ <http://journals.iucr.org/s/issues/2014/06/00/pp5053/index.html>`_ Examples -------- - Remove sinogram stripes: >>> import tomopy >>> >>> # Load data >>> myfile = 'demo/data.h5' >>> data, white, dark, theta = tomopy.xtomo_reader(myfile, slices_start=0, slices_end=1) >>> >>> # Save data before stripe removal >>> output_file='tmp/before_stripe_removal_' >>> tomopy.xtomo_writer(data, output_file, axis=1) >>> print "Images are succesfully saved at " + output_file + '...' >>> >>> # Construct tomo object >>> d = tomopy.xtomo_dataset(log='error') >>> d.dataset(data, white, dark, theta) >>> >>> # Perform stripe removal >>> d.stripe_removal2() >>> >>> # Save data after stripe removal >>> output_file='tmp/after_stripe_removal_' >>> tomopy.xtomo_writer(d.data, output_file, axis=1) >>> print "Images are succesfully saved at " + output_file + '...' """ # Arguments passed by multi-processing wrapper ind, dshape, inputs = args # Function inputs data = mp.tonumpyarray(mp.shared_arr, dshape) # shared-array nblocks, alpha = inputs dx, num_slices, dy = dshape sino = numpy.zeros((dx, dy), dtype='float32') for n in ind: sino[:, :] = -numpy.log(data[:, n, :]) if (nblocks == 0): d1 = _ring(sino, 1, 1) d2 = _ring(sino, 2, 1) p = d1 * d2 d = numpy.sqrt(p + alpha * numpy.abs(p.min())) else: # half = int(sino.shape[0] / 2) size = int(sino.shape[0] / nblocks) d1 = _ringb(sino, 1, 1, size) d2 = _ringb(sino, 2, 1, size) p = d1 * d2 d = numpy.sqrt(p + alpha * numpy.fabs(p.min())) data[:, n, :] = numpy.exp(-d[:, :])
def median_filter(args): """ Apply median filter to data. Parameters ---------- data : ndarray 3-D tomographic data with dimensions: [projections, slices, pixels] size : scalar The size of the filter. axis : scalar Define the axis of data for filtering. 0: projections, 1:sinograms, 2:pixels Returns ------- output : ndarray Median filtered data. Examples -------- - Apply median-filter to sinograms: >>> import tomopy >>> >>> # Load data >>> myfile = 'demo/data.h5' >>> data, white, dark, theta = tomopy.xtomo_reader(myfile, slices_start=0, slices_end=1) >>> >>> # Save data before filtering >>> output_file='tmp/before_filtering_' >>> tomopy.xtomo_writer(data, output_file, axis=1) >>> print "Images are succesfully saved at " + output_file + '...' >>> >>> # Construct tomo object >>> d = tomopy.xtomo_dataset(log='error') >>> d.dataset(data, white, dark, theta) >>> >>> # Perform filtering >>> d.median_filter() >>> >>> # Save data after filtering >>> output_file='tmp/after_filtering_' >>> tomopy.xtomo_writer(d.data, output_file, axis=1) >>> print "Images are succesfully saved at " + output_file + '...' """ # Arguments passed by multi-processing wrapper ind, dshape, inputs = args # Function inputs data = mp.tonumpyarray(mp.shared_arr, dshape) # shared-array size, axis = inputs if axis == 0: for m in ind: data[m, :, :] = filters.median_filter(data[m, :, :], (size, size)) elif axis == 1: for m in ind: data[:, m, :] = filters.median_filter(data[:, m, :], (size, size)) elif axis == 2: for m in ind: data[:, :, m] = filters.median_filter(data[:, :, m], (size, size))
def stripe_removal(args): """ Remove stripes from sinogram data. Parameters ---------- data : ndarray 3-D tomographic data with dimensions: [projections, slices, pixels] level : scalar Number of DWT levels. wname : str Type of the wavelet filter. sigma : scalar Damping parameter in Fourier space. Returns ------- output : ndarray Corrected data. References ---------- - `Optics Express, Vol 17(10), 8567-8591(2009) \ <http://www.opticsinfobase.org/oe/abstract.cfm?uri=oe-17-10-8567>`_ Examples -------- - Remove sinogram stripes: >>> import tomopy >>> >>> # Load data >>> myfile = 'demo/data.h5' >>> data, white, dark, theta = tomopy.xtomo_reader(myfile, slices_start=0, slices_end=1) >>> >>> # Save data before stripe removal >>> output_file='tmp/before_stripe_removal_' >>> tomopy.xtomo_writer(data, output_file, axis=1) >>> print "Images are succesfully saved at " + output_file + '...' >>> >>> # Construct tomo object >>> d = tomopy.xtomo_dataset(log='error') >>> d.dataset(data, white, dark, theta) >>> >>> # Perform stripe removal >>> d.stripe_removal(padding=True) >>> >>> # Save data after stripe removal >>> output_file='tmp/after_stripe_removal_' >>> tomopy.xtomo_writer(d.data, output_file, axis=1) >>> print "Images are succesfully saved at " + output_file + '...' """ # Arguments passed by multi-processing wrapper ind, dshape, inputs = args # Function inputs data = mp.tonumpyarray(mp.shared_arr, dshape) # shared-array level, wname, sigma, padding = inputs dx, num_slices, dy = dshape # Padded temp image. num_x = dx if padding: num_x = dx + dx / 8 x_shift = int((num_x - dx) / 2.0) sli = np.zeros((num_x, dy), dtype="float32") for n in ind: sli[x_shift : dx + x_shift, :] = data[:, n, :] # Wavelet decomposition. cH = [] cV = [] cD = [] for m in range(level): sli, (cHt, cVt, cDt) = pywt.dwt2(sli, wname) cH.append(cHt) cV.append(cVt) cD.append(cDt) # FFT transform of horizontal frequency bands. for m in range(level): # FFT fcV = np.fft.fftshift(np.fft.fft(cV[m], axis=0)) my, mx = fcV.shape # Damping of ring artifact information. y_hat = (np.arange(-my, my, 2, dtype="float") + 1) / 2 damp = 1 - np.exp(-np.power(y_hat, 2) / (2 * np.power(sigma, 2))) fcV = np.multiply(fcV, np.transpose(np.tile(damp, (mx, 1)))) # Inverse FFT. cV[m] = np.real(np.fft.ifft(np.fft.ifftshift(fcV), axis=0)) # Wavelet reconstruction. for m in range(level)[::-1]: sli = sli[0 : cH[m].shape[0], 0 : cH[m].shape[1]] sli = pywt.idwt2((sli, (cH[m], cV[m], cD[m])), wname) data[:, n, :] = sli[x_shift : dx + x_shift, 0:dy]
def phase_retrieval(args): """ Perform single-material phase retrieval using projection data. Parameters ---------- data : ndarray 3-D tomographic data with dimensions: [projections, slices, pixels] pixel_size : scalar Detector pixel size in cm. dist : scalar Propagation distance of x-rays in cm. energy : scalar Energy of x-rays in keV. alpha : scalar, optional Regularization parameter. padding : bool, optional Applies padding for Fourier transform. For quick testing you can use False for faster results. Returns ------- phase : ndarray Retrieved phase. References ---------- - `J. of Microscopy, Vol 206(1), 33-40, 2001 \ <http://onlinelibrary.wiley.com/doi/10.1046/j.1365-2818.2002.01010.x/abstract>`_ Examples -------- - Phase retrieval: >>> import tomopy >>> >>> # Load data >>> myfile = 'demo/data.h5' >>> data, white, dark, theta = tomopy.xtomo_reader(myfile) >>> >>> # Construct tomo object >>> d = tomopy.xtomo_dataset(log='error') >>> d.dataset(data, white, dark, theta) >>> d.normalize() >>> >>> # Reconstruct data before phase retrieval >>> d.center=661.5 >>> d.gridrec() >>> >>> # Save reconstructed data before phase retrieval >>> output_file='tmp/before_phase_retrieval_' >>> tomopy.xtomo_writer(d.data_recon, output_file) >>> print "Images are succesfully saved at " + output_file + '...' >>> >>> # Reconstruct data after phase retrieval >>> d.phase_retrieval(pixel_size=1e-4, dist=70, energy=20) >>> d.gridrec() >>> >>> # Save reconstructed data after phase retrieval >>> output_file='tmp/after_phase_retrieval_' >>> tomopy.xtomo_writer(d.data_recon, output_file) >>> print "Images are succesfully saved at " + output_file + '...' """ # Arguments passed by multi-processing wrapper ind, dshape, inputs = args # Function inputs data = mp.tonumpyarray(mp.shared_arr, dshape) # shared-array pixel_size, dist, energy, alpha, padding = inputs # Compute the filter. H, x_shift, y_shift, tmp_proj = paganin_filter(data, pixel_size, dist, energy, alpha, padding) num_proj, dx, dy = dshape # dx:slices, dy:pixels for m in ind: proj = data[m, :, :] if padding: tmp_proj[x_shift:dx+x_shift, y_shift:dy+y_shift] = proj fft_proj = fftw.fftw2(tmp_proj) filtered_proj = np.multiply(H, fft_proj) tmp = np.real(fftw.ifftw2(filtered_proj))/np.max(H) proj = tmp[x_shift:dx+x_shift, y_shift:dy+y_shift] elif not padding: fft_proj = fftw.fftw2(proj) filtered_proj = np.multiply(H, fft_proj) proj = np.real(fftw.ifftw2(filtered_proj))/np.max(H) data[m, :, :] = proj
def stripe_removal(args): """ Remove stripes from sinogram data. Parameters ---------- data : ndarray 3-D tomographic data with dimensions: [projections, slices, pixels] level : scalar Number of DWT levels. wname : str Type of the wavelet filter. sigma : scalar Damping parameter in Fourier space. Returns ------- output : ndarray Corrected data. References ---------- - `Optics Express, Vol 17(10), 8567-8591(2009) \ <http://www.opticsinfobase.org/oe/abstract.cfm?uri=oe-17-10-8567>`_ Examples -------- - Remove sinogram stripes: >>> import tomopy >>> >>> # Load data >>> myfile = 'demo/data.h5' >>> data, white, dark, theta = tomopy.xtomo_reader(myfile, slices_start=0, slices_end=1) >>> >>> # Save data before stripe removal >>> output_file='tmp/before_stripe_removal_' >>> tomopy.xtomo_writer(data, output_file, axis=1) >>> print "Images are succesfully saved at " + output_file + '...' >>> >>> # Construct tomo object >>> d = tomopy.xtomo_dataset(log='error') >>> d.dataset(data, white, dark, theta) >>> >>> # Perform stripe removal >>> d.stripe_removal(padding=True) >>> >>> # Save data after stripe removal >>> output_file='tmp/after_stripe_removal_' >>> tomopy.xtomo_writer(d.data, output_file, axis=1) >>> print "Images are succesfully saved at " + output_file + '...' """ # Arguments passed by multi-processing wrapper ind, dshape, inputs = args # Function inputs data = mp.tonumpyarray(mp.shared_arr, dshape) # shared-array level, wname, sigma, padding = inputs dx, num_slices, dy = dshape # Padded temp image. num_x = dx if padding: num_x = dx + dx / 8 x_shift = int((num_x - dx) / 2.) sli = np.zeros((num_x, dy), dtype='float32') for n in ind: sli[x_shift:dx + x_shift, :] = data[:, n, :] # Wavelet decomposition. cH = [] cV = [] cD = [] for m in range(level): sli, (cHt, cVt, cDt) = pywt.dwt2(sli, wname) cH.append(cHt) cV.append(cVt) cD.append(cDt) # FFT transform of horizontal frequency bands. for m in range(level): # FFT fcV = np.fft.fftshift(np.fft.fft(cV[m], axis=0)) my, mx = fcV.shape # Damping of ring artifact information. y_hat = (np.arange(-my, my, 2, dtype='float') + 1) / 2 damp = 1 - np.exp(-np.power(y_hat, 2) / (2 * np.power(sigma, 2))) fcV = np.multiply(fcV, np.transpose(np.tile(damp, (mx, 1)))) # Inverse FFT. cV[m] = np.real(np.fft.ifft(np.fft.ifftshift(fcV), axis=0)) # Wavelet reconstruction. for m in range(level)[::-1]: sli = sli[0:cH[m].shape[0], 0:cH[m].shape[1]] sli = pywt.idwt2((sli, (cH[m], cV[m], cD[m])), wname) data[:, n, :] = sli[x_shift:dx + x_shift, 0:dy]