def test_fft_filter_private(self): p = np.ones((60, 60), dtype=np.uint8) w = Window("gaussian", shape=(10, 10), std=5) fft_shape, window_rfft, off1, off2 = barnes._fft_filter_setup( image_shape=p.shape, window=w ) p_filtered = barnes._fft_filter( image=p, fft_shape=fft_shape, window_shape=w.shape, transfer_function=window_rfft, offset_before_fft=off1, offset_after_ifft=off2, ) assert p_filtered.shape == p.shape
def get_dynamic_background( pattern: np.ndarray, filter_domain: str = "frequency", std: Union[None, int, float] = None, truncate: Union[int, float] = 4.0, ) -> np.ndarray: """Get the dynamic background in an EBSD pattern. The background is obtained either in the frequency domain, by a low pass Fast Fourier Transform (FFT) Gaussian filter, or in the spatial domain by a Gaussian filter. Data type is preserved. Parameters ---------- pattern EBSD pattern. filter_domain Whether to obtain the dynamic background by applying a Gaussian convolution filter in the "frequency" (default) or "spatial" domain. std Standard deviation of the Gaussian window. If None (default), a deviation of pattern width/8 is chosen. truncate Truncate the Gaussian window at this many standard deviations. Default is 4.0. Returns ------- dynamic_bg : numpy.ndarray The dynamic background. """ if std is None: std = pattern.shape[1] / 8 if filter_domain == "frequency": ( fft_shape, kernel_shape, kernel_fft, offset_before_fft, offset_after_ifft, ) = _dynamic_background_frequency_space_setup( pattern_shape=pattern.shape, std=std, truncate=truncate, ) dynamic_bg = _fft_filter( image=pattern, fft_shape=fft_shape, window_shape=kernel_shape, transfer_function=kernel_fft, offset_before_fft=offset_before_fft, offset_after_ifft=offset_after_ifft, ) elif filter_domain == "spatial": dynamic_bg = gaussian_filter( input=pattern, sigma=std, truncate=truncate, ) else: filter_domains = ["frequency", "spatial"] raise ValueError( f"{filter_domain} must be either of {filter_domains}.") return dynamic_bg.astype(pattern.dtype)
def remove_dynamic_background( pattern: np.ndarray, operation: str = "subtract", filter_domain: str = "frequency", std: Union[None, int, float] = None, truncate: Union[int, float] = 4.0, dtype_out: Union[None, np.dtype, Tuple[int, int], Tuple[float, float]] = None, ) -> np.ndarray: """Remove the dynamic background in an EBSD pattern. The removal is performed by subtracting or dividing by a Gaussian blurred version of the pattern. The blurred version is obtained either in the frequency domain, by a low pass Fast Fourier Transform (FFT) Gaussian filter, or in the spatial domain by a Gaussian filter. Returned pattern intensities are rescaled to fill the input data type range. Parameters ---------- pattern EBSD pattern. operation Whether to "subtract" (default) or "divide" by the dynamic background pattern. filter_domain Whether to obtain the dynamic background by applying a Gaussian convolution filter in the "frequency" (default) or "spatial" domain. std Standard deviation of the Gaussian window. If None (default), it is set to width/8. truncate Truncate the Gaussian window at this many standard deviations. Default is 4.0. dtype_out Data type of corrected pattern. If None (default), it is set to input patterns' data type. Returns ------- corrected_pattern : numpy.ndarray Pattern with the dynamic background removed. See Also -------- kikuchipy.signals.EBSD.remove_dynamic_background kikuchipy.pattern.remove_dynamic_background """ if std is None: std = pattern.shape[1] / 8 if dtype_out is None: dtype_out = pattern.dtype.type if filter_domain == "frequency": ( fft_shape, kernel_shape, kernel_fft, offset_before_fft, offset_after_ifft, ) = _dynamic_background_frequency_space_setup( pattern_shape=pattern.shape, std=std, truncate=truncate, ) dynamic_bg = _fft_filter( image=pattern, fft_shape=fft_shape, window_shape=kernel_shape, transfer_function=kernel_fft, offset_before_fft=offset_before_fft, offset_after_ifft=offset_after_ifft, ) elif filter_domain == "spatial": dynamic_bg = gaussian_filter( input=pattern, sigma=std, truncate=truncate, ) else: filter_domains = ["frequency", "spatial"] raise ValueError( f"{filter_domain} must be either of {filter_domains}.") # Remove dynamic background if operation == "subtract": corrected_pattern = pattern - dynamic_bg else: # operation == "divide" corrected_pattern = pattern / dynamic_bg # Rescale intensity corrected_pattern = rescale_intensity(corrected_pattern, dtype_out=dtype_out) return corrected_pattern