def invert(img, mx=None): """ INVERT applies inverse video transformation on single channel images. Usage: res = invert(img, max_intensity) Args: img (numpy.ndarray): single channel image max_intensity (implicit none): the maximum intensity of the type of images provided as input (e.g. a 8 bit/pixel image has normally max_intensity=255) Returns: numpy.ndarray: an image of the same shape as the original, but with the intensity levels inverted (max_intensity - initial_value) Raises: ValueError: if the input image is not single channel """ if img.ndim != 2: raise ValueError('A single channel image is expected') if mx is None: mx = dtype_limits(img)[1] else: mx = np.min(dtype_limits(img)[1], mx) res = mx - img return res
def threshold_sauvola(image, window_size=15, k=0.2, r=None): """Applies Sauvola local threshold to an array. Sauvola is a modification of Niblack technique. In the original method a threshold T is calculated for every pixel in the image using the following formula: T = m(x,y) * (1 + k * ((s(x,y) / R) - 1)) where m(x,y) and s(x,y) are the mean and standard deviation of pixel (x,y) neighborhood defined by a rectangular window with size w times w centered around the pixel. k is a configurable parameter that weights the effect of standard deviation. R is the maximum standard deviation of a greyscale image. Parameters ---------- image: (N, M) ndarray Grayscale input image. window_size : int, optional Odd size of pixel neighborhood window (e.g. 3, 5, 7...). k : float, optional Value of the positive parameter k. r : float, optional Value of R, the dynamic range of standard deviation. If None, set to the half of the image dtype range. offset : float, optional Constant subtracted from obtained local thresholds. Returns ------- threshold : (N, M) ndarray Threshold mask. All pixels with an intensity higher than this value are assumed to be foreground. Notes ----- This algorithm is originally designed for text recognition. References ---------- .. [1] J. Sauvola and M. Pietikainen, "Adaptive document image binarization," Pattern Recognition 33(2), pp. 225-236, 2000. DOI:10.1016/S0031-3203(99)00055-2 Examples -------- >>> from skimage import data >>> image = data.page() >>> binary_sauvola = threshold_sauvola(image, ... window_size=15, k=0.2) """ if r is None: imin, imax = dtype_limits(image, clip_negative=False) r = 0.5 * (imax - imin) m, s = _mean_std(image, window_size) return m * (1 + k * ((s / r) - 1))
def imshowg(img, ax=None): """Show image using grayscale color map. """ vmin, vmax = util.dtype_limits(img, clip_negative=True) if ax is None: ax = plt.imshow(img, cmap="gray", vmin=vmin, vmax=vmax) else: ax.imshow(img, cmap="gray", vmin=vmin, vmax=vmax) return ax
def draw_points(size, num_points, radius, seed=1, func=draw_circle_point, dtype=np.uint8): """ Draw points on the top of an image at random positions. Parameters ---------- size : tuple of 2 elements Image size. num_points : int Number of points. radius : int Point radius. func : callable, optional Function to generate points. The function must return a tuple with point positions and intensities. seed : int, optional Seed used to generate random point positions. Returns ------- image : (N, M) ndarray Examples -------- >>> size = (100, 100) >>> img = draw_points(size, 100, 4, seed=1, func=draw_circle_point) """ np.random.seed(seed) max_y, max_x = size imin, imax = dtype_limits(np.zeros((0, ), dtype=dtype), clip_negative=False) img = np.ones(size, dtype=dtype) * imin points_x = np.random.randint(radius, high=max_x - 1 - radius, size=num_points) points_y = np.random.randint(radius, high=max_y - 1 - radius, size=num_points) for px, py in zip(points_x, points_y): points = func(py, px, radius, dtype=img.dtype) for rr, cc, intensity in points: img[rr, cc] = intensity return img
def remove_small_blobs(bw_img, min_area=35, **label_kwargs): """ Remove small blobs in the bw img. """ labels = label(bw_img, **label_kwargs) # pick the background and foreground colors bg = label_kwargs.get('background', 0) fg = dtype_limits(bw_img, clip_negative=True)[1] - bg # create an empty image new_bw = np.ones_like(bw_img) * bg # check the area of each region for roi in regionprops(labels): if roi.area >= min_area: new_bw[labels == roi.label] = fg return new_bw
def visualizeROI(roidict, img, cmap="gray", alpha=0.35, **args): colors = plt.cm.tab10(np.linspace(0, 1, len(roidict))) fig, ax = plt.subplots(1, 1) vmin, vmax = util.dtype_limits(img, clip_negative=True) ax.imshow(img, cmap=cmap, vmin=vmin, vmax=vmax) for i, region in enumerate(roidict.values()): minr, minc, maxr, maxc = region height = maxr - minr width = maxc - minc rect = patches.Rectangle((minc, minr), width, height, alpha=alpha, color=colors[i], **args) ax.add_patch(rect) return fig, ax
def draw_square_point(cy, cx, halfwidth, dtype=np.uint8): """ Draw a point made of concentric squares. Parameters ---------- cy, cx : int Center coordinates of the point. halfwidth : int Half width of the point. dtype : numpy dtype Data type used to generate the intensity values. Returns ------- rr, cc, intensity : (N,) ndarray of int Notes ----- The intensity decreases linearly along the radial position. Examples -------- >>> img = np.zeros((100, 100), dtype=np.uint8) >>> points = draw_square_point(30, 30, 5) >>> for rr, cc, intensity in points: ... img[rr, cc] = intensity """ imin, imax = dtype_limits(np.zeros((0, ), dtype=dtype), clip_negative=False) if dtype in dtypes_float: intensity_step = (imax - imin) / halfwidth else: intensity_step = (imax - imin) // halfwidth data = [] for pos in range(0, halfwidth): yi = [cy - pos, cy + pos, cy + pos, cy - pos] xi = [cx - pos, cx - pos, cx + pos, cx + pos] pixels = draw.polygon_perimeter(yi, xi) intensity = imax - pos * intensity_step intensity = intensity * np.ones(pixels[0].size) data.append((pixels[0], pixels[1], intensity)) return data
def draw_circle_point(cy, cx, radius, dtype=np.uint8): """ Draw a point made of concentric Andres' circles. Parameters ---------- cy, cx : int Center coordinates of the point. radius : int Radius of the point. dtype : numpy dtype Data type used to generate the intensity values. Returns ------- rr, cc, intensity : (N,) ndarray of int Notes ----- The intensity decreases linearly along the radial position. Examples -------- >>> img = np.zeros((100, 100), dtype=np.uint8) >>> points = draw_circle_point(30, 30, 5) >>> for rr, cc, intensity in points: ... img[rr, cc] = intensity """ imin, imax = dtype_limits(np.zeros((0, ), dtype=dtype), clip_negative=False) if dtype in dtypes_float: intensity_step = (imax - imin) / radius else: intensity_step = (imax - imin) // radius data = [] for rad in range(0, radius): pixels = draw.circle_perimeter(cy, cx, rad, method='andres') intensity = imax - rad * intensity_step intensity = intensity * np.ones(pixels[0].size) data.append((pixels[0], pixels[1], intensity)) return data
def contrast_stretch(image, min_percentile=2, max_percentile=98): p2, p98 = np.percentile(image, (min_percentile, max_percentile)) image = exposure.rescale_intensity(image, in_range=(p2, p98)) min_val, max_val = dtype_limits(image, clip_negative=True) image = np.clip(image, min_val, max_val) return image