def test_margin(): size = (10, 10) edge = 1 mask1 = mask.margin(size, edge) mask2 = np.zeros(size) mask2[:, :edge] = 1 mask2[:, -edge:] = 1 mask2[:edge, :] = 1 mask2[-edge:, :] = 1 mask2 = mask2.astype(bool) assert_array_equal(mask1, ~mask2)
def mask_img(img, geo, edge=30, lower_thresh=0.0, upper_thresh=None, bs_width=13, tri_offset=13, v_asym=0, alpha=2.5, tmsk=None): """ Mask an image based off of various methods Parameters ---------- img: np.ndarray The image to be masked geo: pyFAI.geometry.Geometry The pyFAI description of the detector orientation or any subclass of pyFAI.geometry.Geometry class edge: int, optional The number of edge pixels to mask. Defaults to 30. If None, no edge mask is applied lower_thresh: float, optional Pixels with values less than or equal to this threshold will be masked. Defaults to 0.0. If None, no lower threshold mask is applied upper_thresh: float, optional Pixels with values greater than or equal to this threshold will be masked. Defaults to None. If None, no upper threshold mask is applied. bs_width: int, optional The width of the beamstop in pixels. Defaults to 13. If None, no beamstop polygon mask is applied. tri_offset: int, optional The triangular pixel offset to create a pointed beamstop polygon mask. Defaults to 13. If None, no beamstop polygon mask is applied. v_asym: int, optional The vertical asymmetry of the polygon beamstop mask. Defaults to 0. If None, no beamstop polygon mask is applied. alpha: float or tuple or, 1darray, optional Then number of acceptable standard deviations, if tuple then we use a linear distribution of alphas from alpha[0] to alpha[1], if array then we just use that as the distribution of alphas. Defaults to 2.5. If None, no outlier masking applied. tmsk: np.ndarray, optional The starting mask to be compounded on. Defaults to None. If None mask generated from scratch. Returns ------- tmsk: np.ndarray The mask as a boolean array. True pixels are good pixels, False pixels are masked out. """ if tmsk is None: working_mask = np.ones(img.shape).astype(bool) else: working_mask = tmsk.copy() if edge: working_mask *= margin(img.shape, edge) if lower_thresh: working_mask *= (img >= lower_thresh).astype(bool) if upper_thresh: working_mask *= (img <= upper_thresh).astype(bool) if all([a is not None for a in [bs_width, tri_offset, v_asym]]): center_x, center_y = [geo.getFit2D()[k] for k in ['centerX', 'centerY']] nx, ny = img.shape mask_verts = [(center_x - bs_width, center_y), (center_x, center_y - tri_offset), (center_x + bs_width, center_y), (center_x + bs_width + v_asym, ny), (center_x - bs_width - v_asym, ny)] x, y = np.meshgrid(np.arange(nx), np.arange(ny)) x, y = x.flatten(), y.flatten() points = np.vstack((x, y)).T path = Path(mask_verts) grid = path.contains_points(points) # Plug msk_grid into into next (edge-mask) step in automask working_mask *= ~grid.reshape((ny, nx)) if alpha: working_mask *= new_masking_method(img, geo, alpha=alpha, tmsk=working_mask) working_mask = working_mask.astype(np.bool) return working_mask
def old_mask_img(img, geo, edge=30, lower_thresh=0.0, upper_thresh=None, bs_width=13, tri_offset=13, v_asym=0, alpha=2.5, tmsk=None): """ Mask an image based off of various methods Parameters ---------- img: np.ndarray The image to be masked geo: pyFAI.geometry.Geometry The pyFAI description of the detector orientation or any subclass of pyFAI.geometry.Geometry class edge: int, optional The number of edge pixels to mask. Defaults to 30. If None, no edge mask is applied lower_thresh: float, optional Pixels with values less than or equal to this threshold will be masked. Defaults to 0.0. If None, no lower threshold mask is applied upper_thresh: float, optional Pixels with values greater than or equal to this threshold will be masked. Defaults to None. If None, no upper threshold mask is applied. bs_width: int, optional The width of the beamstop in pixels. Defaults to 13. If None, no beamstop polygon mask is applied. tri_offset: int, optional The triangular pixel offset to create a pointed beamstop polygon mask. Defaults to 13. If None, no beamstop polygon mask is applied. v_asym: int, optional The vertical asymmetry of the polygon beamstop mask. Defaults to 0. If None, no beamstop polygon mask is applied. alpha: float or tuple or, 1darray, optional Then number of acceptable standard deviations, if tuple then we use a linear distribution of alphas from alpha[0] to alpha[1], if array then we just use that as the distribution of alphas. Defaults to 2.5. If None, no outlier masking applied. tmsk: np.ndarray, optional The starting mask to be compounded on. Defaults to None. If None mask generated from scratch. Returns ------- tmsk: np.ndarray The mask as a boolean array. True pixels are good pixels, False pixels are masked out. """ q = geo.qArray(img.shape) qbinned = generate_binner(geo, img.shape) if tmsk is None: working_mask = np.ones(img.shape).astype(bool) else: working_mask = tmsk.copy() if edge: working_mask *= margin(img.shape, edge) if lower_thresh: working_mask *= (img >= lower_thresh).astype(bool) if upper_thresh: working_mask *= (img <= upper_thresh).astype(bool) if all([a is not None for a in [bs_width, tri_offset, v_asym]]): center_x, center_y = [geo.getFit2D()[k] for k in ['centerX', 'centerY']] nx, ny = img.shape mask_verts = [(center_x - bs_width, center_y), (center_x, center_y - tri_offset), (center_x + bs_width, center_y), (center_x + bs_width + v_asym, ny), (center_x - bs_width - v_asym, ny)] x, y = np.meshgrid(np.arange(nx), np.arange(ny)) x, y = x.flatten(), y.flatten() points = np.vstack((x, y)).T path = Path(mask_verts) grid = path.contains_points(points) # Plug msk_grid into into next (edge-mask) step in automask working_mask *= ~grid.reshape((ny, nx)) if alpha: working_mask *= binned_outlier(img, q, alpha, qbinned.bin_edges, mask=working_mask) return working_mask
def mask_img(img, binner, edge=30, lower_thresh=0.0, upper_thresh=None, alpha=3, auto_type='median', tmsk=None): """ Mask an image based off of various methods Parameters ---------- img: np.ndarray The image to be masked binner: pyFAI.geometry.Geometry The pyFAI description of the detector orientation or any subclass of pyFAI.geometry.Geometry class edge: int, optional The number of edge pixels to mask. Defaults to 30. If None, no edge mask is applied lower_thresh: float, optional Pixels with values less than or equal to this threshold will be masked. Defaults to 0.0. If None, no lower threshold mask is applied upper_thresh: float, optional Pixels with values greater than or equal to this threshold will be masked. Defaults to None. If None, no upper threshold mask is applied. alpha: float, optional Then number of acceptable standard deviations, if tuple then we use a linear distribution of alphas from alpha[0] to alpha[1], if array then we just use that as the distribution of alphas. Defaults to 3. If None, no outlier masking applied. auto_type: {'median', 'mean'}, optional The type of binned outlier masking to be done, 'median' is faster, where 'mean' is more accurate, defaults to 'median'. tmsk: np.ndarray, optional The starting mask to be compounded on. Defaults to None. If None mask generated from scratch. Returns ------- tmsk: np.ndarray The mask as a boolean array. True pixels are good pixels, False pixels are masked out. """ if tmsk is None: working_mask = np.ones(img.shape).astype(bool) else: working_mask = tmsk.copy() if edge: working_mask *= margin(img.shape, edge) if lower_thresh: working_mask *= (img >= lower_thresh).astype(bool) if upper_thresh: working_mask *= (img <= upper_thresh).astype(bool) if alpha: working_mask *= binned_outlier(img, binner, alpha=alpha, tmsk=working_mask, mask_method=auto_type) working_mask = working_mask.astype(np.bool) return working_mask
def mask_img( img, binner, edge=30, lower_thresh=0.0, upper_thresh=None, alpha=3, auto_type="median", tmsk=None, pool=None, ): """ Mask an image based off of various methods Parameters ---------- img: np.ndarray The image to be masked binner : BinnedStatistic1D instance The binned statistics information edge: int, optional The number of edge pixels to mask. Defaults to 30. If None, no edge mask is applied lower_thresh: float, optional Pixels with values less than or equal to this threshold will be masked. Defaults to 0.0. If None, no lower threshold mask is applied upper_thresh: float, optional Pixels with values greater than or equal to this threshold will be masked. Defaults to None. If None, no upper threshold mask is applied. alpha: float, optional Then number of acceptable standard deviations, if tuple then we use a linear distribution of alphas from alpha[0] to alpha[1], if array then we just use that as the distribution of alphas. Defaults to 3. If None, no outlier masking applied. auto_type: {'median', 'mean'}, optional The type of binned outlier masking to be done, 'median' is faster, where 'mean' is more accurate, defaults to 'median'. tmsk: np.ndarray, optional The starting mask to be compounded on. Defaults to None. If None mask generated from scratch. pool : Executor instance A pool against which jobs can be submitted for parallel processing Returns ------- tmsk: np.ndarray The mask as a boolean array. True pixels are good pixels, False pixels are masked out. """ if tmsk is None: working_mask = np.ones(np.shape(img)).astype(bool) else: working_mask = tmsk.copy() if edge: working_mask *= margin(np.shape(img), edge) if lower_thresh: working_mask *= (img >= lower_thresh).astype(bool) if upper_thresh: working_mask *= (img <= upper_thresh).astype(bool) if alpha: working_mask *= binned_outlier( img, binner, alpha=alpha, tmsk=working_mask, mask_method=auto_type, pool=pool, ) working_mask = working_mask.astype(np.bool) return working_mask