Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
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))
Ejemplo n.º 4
0
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
Ejemplo n.º 5
0
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
Ejemplo n.º 6
0
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
Ejemplo n.º 7
0
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
Ejemplo n.º 8
0
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
Ejemplo n.º 9
0
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
Ejemplo n.º 10
0
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