def process_image(pil_image, values):
    img = np.array(pil_image)
    selected_channels = [
        values["-OTSU RED CHANNEL-"], values["-OTSU GREEN CHANNEL-"],
        values["-OTSU BLUE CHANNEL-"]
    ]

    if np.where(selected_channels)[0].size == 1 and len(img.shape) == 2:
        if values["-APPLY LOCAL OTSU-"]:
            radius = values["-LOCAL OTSU SIZE-"]
            local_mask = disk(
                radius
            ) if values["-LOCAL OTSU SHAPE-"] == "Disk" else rectangle(
                int(radius), int(radius))
            otsu_img = img >= rank.otsu(img, local_mask)
        else:
            otsu_img = img >= threshold_otsu(img)

        otsu_np_img = 255 * np.asarray(otsu_img, dtype=np.uint8)
        if values["-OTSU OVERLAY WITH IMAGE-"]:
            cnts = cv2.findContours(otsu_np_img, cv2.RETR_LIST,
                                    cv2.CHAIN_APPROX_NONE)[0]
            cv2.drawContours(img, cnts, -1, 255, 1)
            otsu_np_img = img
        ret_img = Image.fromarray(otsu_np_img)

    elif np.where(selected_channels)[0].size == 1:
        if values["-APPLY LOCAL OTSU-"]:
            radius = values["-LOCAL OTSU SIZE-"]
            local_mask = disk(
                radius
            ) if values["-LOCAL OTSU SHAPE-"] == "Disk" else rectangle(
                int(radius), int(radius))
            otsu_img = img[...,
                           np.where(selected_channels)[0][0]] >= rank.otsu(
                               img[..., np.where(selected_channels)[0][0]],
                               local_mask)
        else:
            threshold_global_otsu = threshold_otsu(
                img[..., np.where(selected_channels)[0][0]])
            otsu_img = img[..., np.where(selected_channels
                                         )[0][0]] >= threshold_global_otsu

        otsu_np_img = 255 * np.asarray(otsu_img, dtype=np.uint8)
        if values["-OTSU OVERLAY WITH IMAGE-"]:
            cnts = cv2.findContours(otsu_np_img, cv2.RETR_LIST,
                                    cv2.CHAIN_APPROX_NONE)[0]
            cv2.drawContours(img, cnts, -1, 255, 1)
            otsu_np_img = img
        ret_img = Image.fromarray(otsu_np_img)

    else:
        ret_img = pil_image

    return ret_img
Exemple #2
0
def robust_binarize(base_image,
                    _dilation=0,
                    heterogeity_size=10,
                    feature_size=50):
    """
    Robust binarization algorithm based off random walker clustering

    :param base_image:
    :param _dilation: if set to anything other than 0, would perform a morphological dilation using this parameter value as size
    :param heterogeity_size: size of the feature (px) that the method will try to eliminate by smoothing
    :param feature_size: size of the feature (px) that the method will try to segment out
    :return: binary_labels
    """
    if np.percentile(base_image, 99) < 0.20:
        if np.percentile(base_image, 99) > 0:
            mult = 0.20 / np.percentile(
                base_image, 99)  # poissonean background assumptions
        else:
            mult = 1000. / np.sum(base_image)
        base_image = base_image * mult
        base_image[base_image > 1] = 1

    clustering_markers = np.zeros(base_image.shape, dtype=np.uint8)

    selem = disk(heterogeity_size)
    smooth = gaussian_filter(base_image, heterogeity_size, mode='constant')
    smooth_median = median(smooth, selem)
    uniform_median = median(base_image, selem)

    selem2 = disk(feature_size)
    local_otsu = rank.otsu(smooth_median, selem2)
    uniform_median_otsu = rank.otsu(uniform_median, selem2)

    clustering_markers[smooth_median < local_otsu * 0.9] = 1
    clustering_markers[smooth_median > local_otsu * 1.1] = 2

    # dbg.random_walker_debug(smooth_median, clustering_markers)
    # dbg.robust_binarize_debug(base_image, smooth_median, smooth_median, local_otsu, clustering_markers,
    #                           0, uniform_median, uniform_median_otsu)

    binary_labels = random_walker(
        smooth_median, clustering_markers, beta=10, mode='bf') - 1

    if _dilation:
        selem = disk(_dilation)
        binary_labels = dilation(binary_labels, selem)

    # dbg.robust_binarize_debug(binary_labels, base_image)
    # dbg.voronoi_debug(binary_labels, local_maxi, dist, segmented_cells_labels)
    # dbg.Kristen_robust_binarize(binary_labels, base_image)
    return binary_labels
Exemple #3
0
    def load_edge2(self, img, low_rate=False):
        radius = 15
        selem = disk(radius)
        if (low_rate == False):
            img_blur = skimage.filters.gaussian(img, sigma=1)
            #thresh = threshold_yen(img_blur)
            #binary = img_blur > thresh
            binary = rank.otsu(img_blur, selem)
        else:
            #thresh = threshold_yen(img)
            #binary = img > thresh
            binary = rank.otsu(img, selem)

        canny_img = canny(img.astype(np.float), sigma=self.sigma)
        return np.bitwise_and(canny_img, binary).astype(np.float)
Exemple #4
0
def get_local_otsu(img):
    radius = 5
    selem = disk(radius)
    local_otsu = rank.otsu(img, selem)
    # blur = cv2.GaussianBlur(img, (5, 5), 0)
    # ret, th = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
    return img > local_otsu
Exemple #5
0
def binarize_image(base_image, _dilation=0, feature_size=2):
    '''
	Binarizes an image using local otsu and random walker
	Borrowed from Andrei's Imagepipe

	:param base_image: [np.ndarray] input image
	:param _dilation: [float] amount of dilation to implement in Binarization
	:param feature_size: [float] size of the structuring disk for random Walker
	:return: [np.ndarray] binarized image
	'''
    print "> Binarizing Image..."
    if np.percentile(base_image, 99) < 0.20:
        if np.percentile(base_image, 99) > 0:
            mult = 0.20 / np.percentile(
                base_image, 99)  # poissonean background assumptions
        else:
            mult = 1000. / np.sum(base_image)
        base_image = base_image * mult
        base_image[base_image > 1] = 1

    clustering_markers = np.zeros(base_image.shape, dtype=np.uint8)
    selem2 = disk(feature_size)
    print '> Performing Local Otsu'
    local_otsu = rank.otsu(base_image, selem2)
    # view_2d_img(local_otsu)
    clustering_markers[base_image < local_otsu * 0.9] = 1
    clustering_markers[base_image > local_otsu * 1.1] = 2
    print "> Performing Random Walker Binarization"
    binary_labels = random_walker(
        base_image, clustering_markers, beta=10, mode='bf') - 1

    if _dilation:
        selem = disk(_dilation)
        binary_labels = dilation(binary_labels, selem)
    return binary_labels
Exemple #6
0
def autoThresholding(image2d, method='triangle', radius=10, value=50):
    """Autothreshold an 2D intensity image which is calculated using:
    binary = image2d >= thresh

    :param image2d: input image for thresholding
    :type image2d: NumPy.Array
    :param method: choice of thresholding method, defaults to 'triangle'
    :type method: str, optional
    :param radius: radius of disk when using local Otsu threshold, defaults to 10
    :type radius: int, optional
    :param value: manual threshold value, defaults to 50
    :type value: int, optional
    :return: binary - binary mask from thresholding
    :rtype: NumPy.Array
    """

    # calculate global Otsu threshold
    if method == 'global_otsu':
        thresh = threshold_otsu(image2d)

    # calculate local Otsu threshold
    if method == 'local_otsu':
        thresh = rank.otsu(image2d, disk(radius))

    if method == 'value_based':
        thresh = value

    if method == 'triangle':
        thresh = threshold_triangle(image2d)

    binary = image2d >= thresh

    return binary
Exemple #7
0
def threshold_img(img, method='global_otsu', radius=50):
    """ Given a gray scale image return a thresholded binary image using Otsu's thresholding method.
    img: A gray scale numpy array.
    method: 
      - 'global_otsu' computes a global threshold  value for the whole image and uses this to binarize the
      input image. (default)
      - 'local_otsu' computes a local threshols value for each pixel (threshold is computed within a neighborhood of a radius). 

    radius: The 2D neighborhood to compute local thresholds in local_otsu method

    Returns:
    
    img_binary: A binary image (same size as input img).
    threshold: Threshold value used to binarize the image.
    
    """
    if len(img.shape) > 2:
        img = rgb2gray(img)

    if method == 'global_otsu':
        threshold = threshold_otsu(img)
        img_binary = img >= threshold

    elif method == 'local_otsu':
        selem = disk(radius)
        threshold = rank.otsu(img, selem)
        img_binary = img >= threshold

    return np.uint8(img_binary), threshold
Exemple #8
0
def threshold(im, binary=False, local=False):
    '''
    im: array
    TODO:
    - noise filtering
    - use local otsu: rank.otsu
    '''
    #im = histeq(im)
    #im = contrast(im)
    #imshow(im)
    
    minval, maxval = 0, 255
    
    im_gray = im.copy()
    
    if is_colored(im):
        im_gray = cv2.cvtColor(im, cv2.COLOR_RGB2GRAY)
    
    #im_gray = cv2.normalize(im_gray, None, alpha=minval, beta=maxval, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_8UC1)
    
    if binary:
        minval = 5
        thresh_type = cv2.THRESH_BINARY
        retval, im_thresh = cv2.threshold(im_gray,minval,maxval,thresh_type)
    elif local == False:
        #thresh_type = cv2.THRESH_BINARY+cv2.THRESH_OTSU
        thresh = filters.threshold_otsu(im_gray)
        im_thresh = (im_gray > thresh).astype('uint8')*255
    else:
        im_thresh = rank.otsu(im_gray, morphology.disk(5))
        im_thresh = (im_gray >= im_thresh).astype('uint8')*255
        
    return im_thresh
Exemple #9
0
def binarize_2d(float_surface, cutoff_type='static', mcc_cutoff=None):
    """
    Performs a 2d binarization based on several possible methods

    :param float_surface:
    :param cutoff_type: ['otsu', 'local_otsu', 'static', 'log-otsu"]. Local Otsu is done with 5px mask
    :param mcc_cutoff: is cutoff_type is 'static', this will be the cutoff threshold
    :return: binary labels
    """
    if cutoff_type == 'otsu':
        mcc_cutoff = threshold_otsu(float_surface)

    elif cutoff_type == 'local otsu':
        selem = disk(5)
        mcc_cutoff = rank.otsu(float_surface, selem)

    elif cutoff_type == 'static':
        pass

    elif cutoff_type == 'log-otsu':
        mcc_cutoff = threshold_otsu(
            np.log(float_surface + np.min(float_surface[float_surface > 0])))

    else:
        raise PipeArgError('unknown cutoff type')

    binary_stack = np.zeros_like(float_surface).astype(np.bool)
    binary_stack[float_surface > mcc_cutoff] = 1

    return binary_stack
Exemple #10
0
    def __otsu_method(
            image: Union[np.ndarray, Iterable, np.uint8]) -> np.ndarray:
        selem = disk(20)
        t_otsu = otsu(image, selem=selem)
        print(t_otsu)
        imshow(t_otsu)
        # th_motsu = threshold_multiotsu(image, classes=2)
        # im = np.digitize(image, bins=th_motsu)
        # imshow(im)
        plt.show()
        test = (image * 255 + 15) <= t_otsu
        result = np.zeros(image.shape, dtype=np.uint8)
        for i, l in enumerate(test):
            for j, v in enumerate(l):
                if v:
                    result[i, j] = 255
        imshow(result)
        plt.show()
        # result = gaussian(gaussian(result, 7), 7)
        result = gaussian(result, 7)
        imshow(result)
        plt.show()
        result = minimum(maximum(result, disk(5)), disk(12))
        imshow(result)
        plt.show()
        result = gaussian(result, 3)
        imshow(result)
        plt.show()

        # return self.__ending(gaussian(self.__ending(result), 7))
        # return self.__ending(result)
        return result
Exemple #11
0
def local_otsu(image, radius=15):
    # radius = 15
    selem = disk(radius)

    local_otsu = rank.otsu(image, selem)

    return (image >= local_otsu) * 255
Exemple #12
0
def getIntensityThresholdOtsu(s, params):
    logging.info(
        f"{s['filename']} - \tLightDarkModule.getIntensityThresholdOtsu")
    name = "otsu"
    local = strtobool(params.get("local", "False"))
    radius = float(params.get("radius", 15))
    selem = disk(radius)

    img = s.getImgThumb(s["image_work_size"])
    img = color.rgb2gray(img)

    if local:
        thresh = rank.otsu(img, selem)
        name += "local"
    else:
        thresh = threshold_otsu(img)

    map = img < thresh
    s.addToPrintList(name, str(map.mean()))
    io.imsave(s["outdir"] + os.sep + s["filename"] + "_" + name + ".png",
              map * 255)
    s["img_mask_" + name] = (map * 255) > 0
    if strtobool(params.get("invert", "False")):
        s["img_mask_use"] = s["img_mask_use"] & ~s["img_mask_" + name]
    else:
        s["img_mask_use"] = s["img_mask_use"] & s["img_mask_" + name]

    return
Exemple #13
0
 def estimate_background(_img):
     *extrem, _img = gaussian_normalize(_img)
     local_otsu = rank.otsu(_img, disk(otsu_disk_radii))
     ub_background = rank.mean(_img,
                               disk(mean_disk_radii),
                               mask=_img <= local_otsu)
     return anti_gaussian_normalize(ub_background / 256., *extrem)
Exemple #14
0
def otsu_binarize(img):
    radius = 13
    selem = disk(radius)
    local_otsu = rank.otsu(img, selem)
    threshold_global_otsu = threshold_otsu(img)
    global_otsu = img >= threshold_global_otsu

    # fig, ax = plt.subplots(2, 2, figsize=(8, 5))
    # ax1, ax2, ax3, ax4 = ax.ravel()
    #
    # fig.colorbar(ax1.imshow(img, cmap=plt.cm.gray),
    #            ax=ax1, orientation='horizontal')
    # ax1.set_title('Original')
    # ax1.axis('off')
    #
    # fig.colorbar(ax2.imshow(local_otsu, cmap=plt.cm.gray),
    #            ax=ax2, orientation='horizontal')
    # ax2.set_title('Local Otsu (radius=%d)' % radius)
    # ax2.axis('off')
    #
    # ax3.imshow(img >= local_otsu, cmap=plt.cm.gray)
    # ax3.set_title('Original >= Local Otsu' % threshold_global_otsu)
    # ax3.axis('off')
    #
    # ax4.imshow(global_otsu, cmap=plt.cm.gray)
    # ax4.set_title('Global Otsu (threshold = %d)' % threshold_global_otsu)
    # ax4.axis('off')
    #
    # plt.show()
    return local_otsu
Exemple #15
0
def threshold(data, process_param):
    if process_param["threshold"] == "otsu":
        thresh = threshold_otsu(data)
    if process_param["threshold"] == "mean":
        thresh = threshold_mean(data)
    if process_param["threshold"] == "minimum":
        thresh = threshold_minimum(data)
    if process_param["threshold"] == "yen":
        thresh = threshold_yen(data)
    if process_param["threshold"] == "isodata":
        thresh = threshold_isodata(data)
    if process_param["threshold"] == "li":
        thresh = threshold_li(data)
    if process_param["threshold"] == "local":
        thresh = threshold_local(data, process_param["local_size"])
    if process_param["threshold"] == "local_otsu":
        selem = disk(process_param["local_size"])
        data = data.astype(np.float64)
        data = data - np.min(data)
        data = np.uint8(255 * data / np.max(data))
        thresh = rank.otsu(data, selem)
    if process_param["threshold"] == "lg_otsu":
        selem = disk(process_param["local_size"])
        data = data.astype(np.float64)
        data = data - np.min(data)
        data = np.uint8(255 * data / np.max(data))
        threshl = rank.otsu(data, selem)
        threshg = threshold_otsu(data)
    if process_param["threshold"] == "niblack":
        thresh = threshold_niblack(data, process_param["local_size"])
        mask = data > thresh
    if process_param["threshold"] == "sauvola":
        thresh = threshold_sauvola(data, process_param["local_size"])
        mask = data > thresh
    if process_param["threshold"] == "lg_otsu":
        mask1 = data >= threshl
        mask2 = data > threshg
        mask = mask1 * mask2
    elif process_param["threshold"] == "local_otsu":
        mask = data >= thresh
    else:
        mask = data > thresh

    labels = label(mask)

    return (labels)
def test_otsu_edge_case():
    # This is an edge case that causes OTSU to appear to misbehave
    # Pixel [1, 1] may take a value of of 41 or 81. Both should be considered
    # valid. The value will change depending on the particular implementation
    # of OTSU.
    # To better understand, see
    # https://mybinder.org/v2/gist/hmaarrfk/4afae1cfded1d78e44c9e4f58285d552/master

    selem = np.array([[0, 1, 0], [1, 1, 1], [0, 1, 0]], dtype=np.uint8)

    img = np.array([[0, 41, 0], [30, 81, 106], [0, 147, 0]], dtype=np.uint8)

    result = rank.otsu(img, selem)
    assert result[1, 1] in [41, 81]

    img = np.array([[0, 214, 0], [229, 104, 141], [0, 172, 0]], dtype=np.uint8)
    result = rank.otsu(img, selem)
    assert result[1, 1] in [141, 172]
Exemple #17
0
def _binarize_and_apply_background(image):
    """Performs plain Otsu binarization to get threshold,
    but only sets the background to 0, retains all the foreground
    intensities."""
    selem = numpy.ones((80, 80), dtype='uint8')
    local_otsu = rank.otsu(image, selem)
    # thr = threshold_otsu(image, nbins=256)
    output = image * 1
    output[output < local_otsu] = 0
    return output
Exemple #18
0
def robust_binarize(base_image,
                    _dilation=0,
                    heterogeity_size=10,
                    feature_size=50):

    if np.percentile(base_image, 99) < 0.20:
        if np.percentile(base_image, 99) > 0:
            mult = 0.20 / np.percentile(
                base_image, 99)  # poissonean background assumptions
        else:
            mult = 1000. / np.sum(base_image)
        base_image = base_image * mult
        base_image[base_image > 1] = 1

    clustering_markers = np.zeros(base_image.shape, dtype=np.uint8)

    selem = disk(heterogeity_size)
    smooth = gaussian_filter(base_image, heterogeity_size, mode='constant')
    smooth_median = median(smooth, selem)
    uniform_median = median(base_image, selem)

    selem2 = disk(feature_size)
    local_otsu = rank.otsu(smooth_median, selem2)
    uniform_median_otsu = rank.otsu(uniform_median, selem2)

    clustering_markers[smooth_median < local_otsu * 0.9] = 1
    clustering_markers[smooth_median > local_otsu * 1.1] = 2

    # dbg.random_walker_debug(smooth_median, clustering_markers)
    # dbg.robust_binarize_debug(base_image, smooth_median, smooth_median, local_otsu, clustering_markers,
    #                           0, uniform_median, uniform_median_otsu)
    binary_labels = random_walker(
        smooth_median, clustering_markers, beta=10, mode='bf') - 1

    if _dilation:
        selem = disk(_dilation)
        binary_labels = dilation(binary_labels, selem)

    # dbg.robust_binarize_debug(binary_labels, base_image)

    # dbg.voronoi_debug(binary_labels, local_maxi, dist, segmented_cells_labels)
    # dbg.Kristen_robust_binarize(binary_labels, base_image)
    return binary_labels
Exemple #19
0
def test_otsu():
    # test the local Otsu segmentation on a synthetic image
    # (left to right ramp * sinus)

    test = np.tile([128, 145, 103, 127, 165, 83, 127, 185, 63, 127, 205, 43, 127, 225, 23, 127], (16, 1))
    test = test.astype(np.uint8)
    res = np.tile([1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1], (16, 1))
    selem = np.ones((6, 6), dtype=np.uint8)
    th = 1 * (test >= rank.otsu(test, selem))
    assert_equal(th, res)
Exemple #20
0
def test_otsu_edge_case():
    # This is an edge case that causes OTSU to appear to misbehave
    # Pixel [1, 1] may take a value of of 41 or 81. Both should be considered
    # valid. The value will change depending on the particular implementation
    # of OTSU. It also may depend on how the compiler chooses to optimize
    # the order of the operations.
    img = np.array([[0, 41, 0], [30, 81, 106], [0, 147, 0]], dtype=np.uint8)
    selem = np.array([[0, 1, 0], [1, 1, 1], [0, 1, 0]], dtype=np.uint8)
    otsu = rank.otsu(img, selem)
    assert otsu[1, 1] in [41, 81]
        def check_all():
            selem = morphology.disk(1)
            refs = np.load(
                os.path.join(skimage.data_dir, "rank_filter_tests.npz"))

            assert_equal(refs["autolevel"], rank.autolevel(self.image, selem))
            assert_equal(refs["autolevel_percentile"],
                         rank.autolevel_percentile(self.image, selem))
            assert_equal(refs["bottomhat"], rank.bottomhat(self.image, selem))
            assert_equal(refs["equalize"], rank.equalize(self.image, selem))
            assert_equal(refs["gradient"], rank.gradient(self.image, selem))
            assert_equal(refs["gradient_percentile"],
                         rank.gradient_percentile(self.image, selem))
            assert_equal(refs["maximum"], rank.maximum(self.image, selem))
            assert_equal(refs["mean"], rank.mean(self.image, selem))
            assert_equal(refs["geometric_mean"],
                         rank.geometric_mean(self.image, selem)),
            assert_equal(refs["mean_percentile"],
                         rank.mean_percentile(self.image, selem))
            assert_equal(refs["mean_bilateral"],
                         rank.mean_bilateral(self.image, selem))
            assert_equal(refs["subtract_mean"],
                         rank.subtract_mean(self.image, selem))
            assert_equal(refs["subtract_mean_percentile"],
                         rank.subtract_mean_percentile(self.image, selem))
            assert_equal(refs["median"], rank.median(self.image, selem))
            assert_equal(refs["minimum"], rank.minimum(self.image, selem))
            assert_equal(refs["modal"], rank.modal(self.image, selem))
            assert_equal(refs["enhance_contrast"],
                         rank.enhance_contrast(self.image, selem))
            assert_equal(refs["enhance_contrast_percentile"],
                         rank.enhance_contrast_percentile(self.image, selem))
            assert_equal(refs["pop"], rank.pop(self.image, selem))
            assert_equal(refs["pop_percentile"],
                         rank.pop_percentile(self.image, selem))
            assert_equal(refs["pop_bilateral"],
                         rank.pop_bilateral(self.image, selem))
            assert_equal(refs["sum"], rank.sum(self.image, selem))
            assert_equal(refs["sum_bilateral"],
                         rank.sum_bilateral(self.image, selem))
            assert_equal(refs["sum_percentile"],
                         rank.sum_percentile(self.image, selem))
            assert_equal(refs["threshold"], rank.threshold(self.image, selem))
            assert_equal(refs["threshold_percentile"],
                         rank.threshold_percentile(self.image, selem))
            assert_equal(refs["tophat"], rank.tophat(self.image, selem))
            assert_equal(refs["noise_filter"],
                         rank.noise_filter(self.image, selem))
            assert_equal(refs["entropy"], rank.entropy(self.image, selem))
            assert_equal(refs["otsu"], rank.otsu(self.image, selem))
            assert_equal(refs["percentile"],
                         rank.percentile(self.image, selem))
            assert_equal(refs["windowed_histogram"],
                         rank.windowed_histogram(self.image, selem))
Exemple #22
0
    def test_otsu(self):
        # test the local Otsu segmentation on a synthetic image
        # (left to right ramp * sinus)

        test = np.tile([128, 145, 103, 127, 165, 83, 127, 185, 63, 127, 205, 43,
                        127, 225, 23, 127],
                       (16, 1))
        test = test.astype(np.uint8)
        res = np.tile([1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1], (16, 1))
        selem = np.ones((6, 6), dtype=np.uint8)
        th = 1 * (test >= rank.otsu(test, selem))
        assert_equal(th, res)
Exemple #23
0
def img_tesseract_detect(c_rect, im):
    # 由于使用minAreaRect获得的图像有-90~0的角度,所以给出的坐标顺序也不一定是
    # 转换时候给的,这里需要判断出图像的左上、左下、右上、右下的坐标,便于后面的变换
    pts = c_rect.reshape(4, 2)
    rect = np.zeros((4, 2), dtype = "float32")
    
    # the top-left point has the smallest sum whereas the
    # bottom-right has the largest sum
    s = pts.sum(axis = 1)
    rect[0] = pts[np.argmin(s)]
    rect[3] = pts[np.argmax(s)]
    
    # compute the difference between the points -- the top-right
    # will have the minumum difference and the bottom-left will
    # have the maximum difference
    diff = np.diff(pts, axis = 1)
    rect[2] = pts[np.argmin(diff)]
    rect[1] = pts[np.argmax(diff)]    

    width = rect[3][0] - rect[0][0]
    height = rect[3][1] - rect[0][1]
    
    width = (int)((50.0 / height) * width)
    height = 50
    
    dst = np.float32([[0,0],[0,height],[width,0],[width,height]])
    
    M = cv2.getPerspectiveTransform(rect, dst)
    warp = cv2.warpPerspective(im, M, (width, height))
    
    img_show_hook("剪裁识别图像", warp) 
    
    warp = np.array(warp, dtype=np.uint8)
    radius = 13
    selem = disk(radius)
    
    # 使用局部自适应OTSU阈值处理
    local_otsu = rank.otsu(warp, selem)
    l_otsu = np.uint8(warp >= local_otsu)
    l_otsu *= 255
    
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(2,2))
    l_otsu = cv2.morphologyEx(l_otsu, cv2.MORPH_CLOSE, kernel)    
    
    img_show_hook("局部自适应OTSU图像", l_otsu) 
    
    print("识别结果:")
    print(pytesseract.image_to_string(Image.fromarray(l_otsu), lang="chi-sim"))
    
    cv2.waitKey(0)
    return 
Exemple #24
0
def img_tesseract_detect(c_rect, im):
    # 由于使用minAreaRect获得的图像有-90~0的角度,所以给出的坐标顺序也不一定是
    # 转换时候给的,这里需要判断出图像的左上、左下、右上、右下的坐标,便于后面的变换
    pts = c_rect.reshape(4, 2)
    rect = np.zeros((4, 2), dtype="float32")

    # the top-left point has the smallest sum whereas the
    # bottom-right has the largest sum
    s = pts.sum(axis=1)
    rect[0] = pts[np.argmin(s)]
    rect[3] = pts[np.argmax(s)]

    # compute the difference between the points -- the top-right
    # will have the minumum difference and the bottom-left will
    # have the maximum difference
    diff = np.diff(pts, axis=1)
    rect[2] = pts[np.argmin(diff)]
    rect[1] = pts[np.argmax(diff)]

    width = rect[3][0] - rect[0][0]
    height = rect[3][1] - rect[0][1]

    width = (int)((50.0 / height) * width)
    height = 50

    dst = np.float32([[0, 0], [0, height], [width, 0], [width, height]])

    M = cv2.getPerspectiveTransform(rect, dst)
    warp = cv2.warpPerspective(im, M, (width, height))

    img_show_hook("剪裁识别图像", warp)

    warp = np.array(warp, dtype=np.uint8)
    radius = 13
    selem = disk(radius)

    # 使用局部自适应OTSU阈值处理
    local_otsu = rank.otsu(warp, selem)
    l_otsu = np.uint8(warp >= local_otsu)
    l_otsu *= 255

    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (2, 2))
    l_otsu = cv2.morphologyEx(l_otsu, cv2.MORPH_CLOSE, kernel)

    img_show_hook("局部自适应OTSU图像", l_otsu)

    print("识别结果:")
    print(pytesseract.image_to_string(Image.fromarray(l_otsu), lang="chi-sim"))

    cv2.waitKey(0)
    return
Exemple #25
0
def test_otsu_edge_case():
    # This is an edge case that causes OTSU to appear to misbehave
    # Pixel [1, 1] may take a value of of 41 or 81. Both should be considered
    # valid. The value will change depending on the particular implementation
    # of OTSU.
    # To better understand, see
    # https://mybinder.org/v2/gist/hmaarrfk/4afae1cfded1d78e44c9e4f58285d552/master

    selem = np.array([[0, 1, 0],
                      [1, 1, 1],
                      [0, 1, 0]], dtype=np.uint8)

    img = np.array([[  0,  41,   0],
                    [ 30,  81, 106],
                    [  0, 147,   0]], dtype=np.uint8)

    result = rank.otsu(img, selem)
    assert result[1, 1] in [41, 81]

    img = np.array([[  0, 214,   0],
                    [229, 104, 141],
                    [  0, 172,   0]], dtype=np.uint8)
    result = rank.otsu(img, selem)
    assert result[1, 1] in [141, 172]
Exemple #26
0
def t2():
    """
        uses local/global thresholding, local doesn't seem to work well because the image is already
        pretty binary
    """
    from skimage.morphology import disk
    from skimage.filters import threshold_otsu, rank
    from skimage.util import img_as_ubyte

    img = misc.imread('zones/0.png')

    radius = 15
    selem = disk(radius)

    local_otsu = rank.otsu(img, selem)
    threshold_global_otsu = threshold_otsu(img)
    global_otsu = img >= threshold_global_otsu

    fig, axes = plt.subplots(2,
                             2,
                             figsize=(8, 5),
                             sharex=True,
                             sharey=True,
                             subplot_kw={'adjustable': 'box-forced'})
    ax = axes.ravel()
    plt.tight_layout()

    fig.colorbar(ax[0].imshow(img, cmap=plt.cm.gray),
                 ax=ax[0],
                 orientation='horizontal')
    ax[0].set_title('Original')
    ax[0].axis('off')

    fig.colorbar(ax[1].imshow(local_otsu, cmap=plt.cm.gray),
                 ax=ax[1],
                 orientation='horizontal')
    ax[1].set_title('Local Otsu (radius=%d)' % radius)
    ax[1].axis('off')

    ax[2].imshow(img >= local_otsu, cmap=plt.cm.gray)
    ax[2].set_title('Original >= Local Otsu' % threshold_global_otsu)
    ax[2].axis('off')

    ax[3].imshow(global_otsu, cmap=plt.cm.gray)
    ax[3].set_title('Global Otsu (threshold = %d)' % threshold_global_otsu)
    ax[3].axis('off')

    plt.show()
Exemple #27
0
def thr_conn(img,fname,stfolder,sfn,thrtyp,bs,mp,kv,rv,inv,ext,prev):
    ofs=-5
    if thrtyp=='Gauss':
        tmp=cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, bs, ofs)
        thrconnimg=Image.fromarray(tmp,mode='L')
    if thrtyp=='Mean':
        tmp=cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, bs, ofs)
        thrconnimg=Image.fromarray(tmp,mode='L')
    if thrtyp=='Gauss Sk':
        ad_thr = threshold_local(img, bs,method='gaussian', offset=ofs)
        tmp = 255*(img > ad_thr).astype('uint8')
        thrconnimg=Image.fromarray(tmp,mode='L')
    if thrtyp=='Mean Sk':
        ad_thr = threshold_local(img, bs,method='mean', offset=ofs)
        tmp = 255*(img > ad_thr).astype('uint8')
        thrconnimg=Image.fromarray(tmp,mode='L')
    if thrtyp=='Median Sk':
        ad_thr = threshold_local(img, bs,method='median', offset=ofs)
        tmp = 255*(img > ad_thr).astype('uint8')
        thrconnimg=Image.fromarray(tmp,mode='L')
    if thrtyp=='Otsu':
        ret,tmp=cv2.threshold(img, 0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
        thrconnimg=Image.fromarray(tmp,mode='L')
    if thrtyp=='Otsu Loc':
        radius = bs
        selem = disk(radius)
        local_otsu = rank.otsu(img, selem)
        tmp = 255*(img >= local_otsu).astype('uint8')
        thrconnimg=Image.fromarray(tmp,mode='L')
    if thrtyp=='Niblack':
        ad_thr = threshold_niblack(img, window_size=bs, k=kv)
        tmp = 255*(img > ad_thr).astype('uint8')
        thrconnimg=Image.fromarray(tmp,mode='L')
    if thrtyp=='Sauvola':
        ad_thr = threshold_sauvola(img,  window_size=bs, k=kv, r=rv)
        tmp = 255*(img > ad_thr).astype('uint8')
        thrconnimg=Image.fromarray(tmp,mode='L')
        
    kernel1 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(4,4))
    openimg = Image.fromarray(cv2.morphologyEx(tmp,cv2.MORPH_OPEN,kernel1),mode='L')
#    openimg2 = Image.fromarray(remove_small_objects((tmp/255).astype('uint8'),mp),mode='L')
    opimg=255*remove_small_objects((tmp/255).astype('uint8').astype('bool'),mp).astype('uint8')
    openimg2 = Image.fromarray(opimg,mode='L')
#    skel=255*skeletonize((opimg/255).astype('uint8'))
#    skelimg=Image.fromarray(skel,mode='L')
    if prev=='N':
        save_tif(stfolder,sfn,fname,openimg2,thrtyp,ext)
    return openimg2#thrconnimg
Exemple #28
0
def getIntensityThresholdOtsu(s, params):
    logging.info(
        f"{s['filename']} - \tLightDarkModule.getIntensityThresholdOtsu")
    name = "otsu"

    local = strtobool(params.get("local", "False"))

    radius = float(params.get("radius", 15))
    selem = disk(radius)

    img = s.getImgThumb(s["image_work_size"])

    img = color.rgb2gray(img)

    if local:
        thresh = rank.otsu(img, selem)
        name += "local"
    else:
        thresh = threshold_otsu(img)

    map = img < thresh

    s["img_mask_" + name] = map > 0
    if strtobool(params.get("invert", "False")):
        s["img_mask_" + name] = ~s["img_mask_" + name]

    io.imsave(s["outdir"] + os.sep + s["filename"] + "_" + name + ".png",
              img_as_ubyte(s["img_mask_" + name]))

    prev_mask = s["img_mask_use"]
    s["img_mask_use"] = s["img_mask_use"] & s["img_mask_" + name]

    s.addToPrintList(
        name,
        printMaskHelper(params.get("mask_statistics", s["mask_statistics"]),
                        prev_mask, s["img_mask_use"]))

    if len(s["img_mask_use"].nonzero()
           [0]) == 0:  # add warning in case the final tissue is empty
        logging.warning(
            f"{s['filename']} - After LightDarkModule.getIntensityThresholdOtsu:{name} NO tissue remains "
            f"detectable! Downstream modules likely to be incorrect/fail")
        s["warnings"].append(
            f"After LightDarkModule.getIntensityThresholdOtsu:{name} NO tissue remains detectable! "
            f"Downstream modules likely to be incorrect/fail")

    return
Exemple #29
0
def transform():
    files = []
    with open('list.txt', r) as f:
        files = f.readlines()
    f.close()

    for file in files:
        print("Processing " + file + "...")
        # Import file
        data = tifffile.imread(file)
        # Convert 3-band RGB to 1-band grayscale
        grayscale = rgb2gray(data)

        # Calculate standard deviation
        mult_1 = np.multiply(grayscale, grayscale)
        blur_1 = gaussian(mult_1, sigma=(9, 9), truncate=3.5, multichannel=False)
        blur_2 = gaussian(grayscale, sigma=(9, 9), truncate=3.5, multichannel=False)
        mult_2 = np.multiply(blur_2, blur_2)
        std_hat = np.sqrt(blur_1 - mult_2)

        # Calculate entropy
        sigma_hat = entropy(std_hat, square(9))

        # Phase symmetry
        psym = phasesym(sigma_hat)

        # Threshold
        selem = square(9)
        local_otsu = rank.otsu(psym, selem)
        threshold_global_otsu = threshold_otsu(psym)
        global_otsu = (psym >= threshold_global_otsu)

        # Skeletonize and invert colors
        skeleton = skeletonize(global_otsu, method='lee')

        skeleton[skeleton == 255] = 1
        skeleton[skeleton == 0] = 255
        skeleton[skeleton == 1] = 0

        # Save intermediate files as png
        plt.imsave(alignedname, skeleton, cmap=plt.cm.gray, dpi=300)
        print("File " + file + " done!")
def nick_binarize(img_list):
    '''Binarize linecut images using two differently sized local threshold kernels

    Args:
        img_list: list of grayscale linecut images
    Returns:
        results: binarized images in the same order as the input'''

    results = []

    for img in img_list:
        try:
            # img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

            height = img.shape[0]
            width = img.shape[1]

            # Resize the images to 200 pixel height
            scaling_factor = 100/img.shape[0]
            new_w = int(scaling_factor*img.shape[1])
            new_h = int(scaling_factor*img.shape[0])
            # img = cv2.resize(img, (new_w, new_h))
            img = np.array(Image.fromarray(img).resize((new_w, new_h), Image.ANTIALIAS))

            # First pass thresholding
            th1 = threshold_niblack(img, 13, 0.00)

            # Second pass thresholding
            radius = 101
            structured_elem = disk(radius)
            th2 =  rank.otsu(img, structured_elem)

            # Masking
            img = (img > th1) | (img > th2)
            img = img.astype('uint8')*255

            img = np.array(Image.fromarray(img).resize((width, height), Image.ANTIALIAS))
            results.append(img)
        except Exception as e:
            continue

    return results
Exemple #31
0
def local_otsu_denoising(img):
    N = img.shape[0]
    radius = np.arange(10, N/4, 10)
    stds = []
    out_images = []
    for radii in radius:
        selem = square(radii)

        out = img.copy()
        # Improve the contrast of the image

        local_otsu = rank.otsu(img, selem)
        stds.append(out[out <= local_otsu].std())
        out[out >= local_otsu] = 255
        out_images.append(out)
    stds = np.array(stds)
    arg = stds.argmin()
    out = out_images[arg]

    return out
Exemple #32
0
def local_otsu_denoising(img):
    N = img.shape[0]
    radius = np.arange(10, N / 4, 10)
    stds = []
    out_images = []
    for radii in radius:
        selem = square(radii)

        out = img.copy()
        # Improve the contrast of the image

        local_otsu = rank.otsu(img, selem)
        stds.append(out[out <= local_otsu].std())
        out[out >= local_otsu] = 255
        out_images.append(out)
    stds = np.array(stds)
    arg = stds.argmin()
    out = out_images[arg]

    return out
Exemple #33
0
def run_otsu(image_path):
    # img = color.rgb2gray(io.imread(image_path))
    img = io.imread(image_path, as_grey=True)
    radius = 15
    selem = disk(radius)
    local_otsu = rank.otsu(img, selem)
    threshold_global_otsu = threshold_otsu(img)
    global_otsu = img >= threshold_global_otsu

    x = global_otsu.shape[1]
    y = global_otsu.shape[0]
    global_otsu = global_otsu.tolist()
    for i in xrange(y):
        for j in xrange(x):
            if global_otsu[i][j] == False:
                global_otsu[i][j] = 1
            else:
                global_otsu[i][j] = 0
    global_otsu = np.array(global_otsu)

    return global_otsu
    def __calc_SNR(self,
                   img,
                   gaus_sd=1,
                   local_rad=15,
                   offset=70,
                   show_imgs=False):
        '''
        This function calculates the Signal to noise ration for a single image. Signal to noise is usually measured by: (i0 - ib) / sqrt(i0) where i0 is signal intensity, and ib is background intensity. To approximate this, we use otsu threshholding to separate background and signal peaks. We then use the mean value of the signal mask as i0 and the mean signal of the background mask as ib.

        inputs
            img <np.array> : image to prefore SNR analysis on
            gaus_sd <int> : standard deviation in the gaussian filter applied before otsu threshold
            local_rad <int> : otsu neighborhood
            offset <int> : pixel intensity offset, higher value will decrease the area of the signal mask.
            show_imgs <boolean> : if true, will plot the mask images, for use in diagnostics and parameter tuning

        outputs
            SNR <float> : Signal to noise ratio; (i0-ib) / sqrt(i0)

        '''
        img2 = gaussian_filter(img, gaus_sd)

        selem = disk(local_rad)

        local_otsu = rank.otsu(img2, selem)

        if (show_imgs):
            fig, axes = plt.subplots(2, 2)
            axes = axes.flatten()
            axes[0].imshow(img)
            axes[1].imshow(img2)
            axes[2].imshow(img2 >= local_otsu + offset)
            plt.show()

        i0 = np.average(img2[img2 >= (local_otsu + offset)])
        ib = np.average(img2[img2 < (local_otsu + offset)])

        SNR = (i0 - ib) / np.sqrt(i0)

        return SNR
Exemple #35
0
def local_otsu(img):
	radius = 100
	selem = disk(radius)
	local_otsu = rank.otsu(img, selem)
	threshold_global_otsu = threshold_otsu(img)
	global_otsu = img >= threshold_global_otsu
	fig, ax = plt.subplots(2, 2, figsize=(8, 5), sharex=True, sharey=True, subplot_kw={'adjustable':'box-forced'})
	ax1, ax2, ax3, ax4 = ax.ravel()
	fig.colorbar(ax1.imshow(img, cmap=plt.cm.gray),
				 ax=ax1, orientation='horizontal')
	ax1.set_title('Original')
	ax1.axis('off')
	fig.colorbar(ax2.imshow(local_otsu, cmap=plt.cm.gray),
				 ax=ax2, orientation='horizontal')
	ax2.set_title('Local Otsu (radius=%d)' % radius)
	ax2.axis('off')
	ax3.imshow(img >= local_otsu, cmap=plt.cm.gray)
	ax3.set_title('Original >= Local Otsu' % threshold_global_otsu)
	ax3.axis('off')
	ax4.imshow(global_otsu, cmap=plt.cm.gray)
	ax4.set_title('Global Otsu (threshold = %d)' % threshold_global_otsu)
	ax4.axis('off')
	plt.show()
Exemple #36
0
def check_all():
    np.random.seed(0)
    image = np.random.rand(25, 25)
    selem = morphology.disk(1)
    refs = np.load(os.path.join(skimage.data_dir, "rank_filter_tests.npz"))

    assert_equal(refs["autolevel"], rank.autolevel(image, selem))
    assert_equal(refs["autolevel_percentile"], rank.autolevel_percentile(image, selem))
    assert_equal(refs["bottomhat"], rank.bottomhat(image, selem))
    assert_equal(refs["equalize"], rank.equalize(image, selem))
    assert_equal(refs["gradient"], rank.gradient(image, selem))
    assert_equal(refs["gradient_percentile"], rank.gradient_percentile(image, selem))
    assert_equal(refs["maximum"], rank.maximum(image, selem))
    assert_equal(refs["mean"], rank.mean(image, selem))
    assert_equal(refs["mean_percentile"], rank.mean_percentile(image, selem))
    assert_equal(refs["mean_bilateral"], rank.mean_bilateral(image, selem))
    assert_equal(refs["subtract_mean"], rank.subtract_mean(image, selem))
    assert_equal(refs["subtract_mean_percentile"], rank.subtract_mean_percentile(image, selem))
    assert_equal(refs["median"], rank.median(image, selem))
    assert_equal(refs["minimum"], rank.minimum(image, selem))
    assert_equal(refs["modal"], rank.modal(image, selem))
    assert_equal(refs["enhance_contrast"], rank.enhance_contrast(image, selem))
    assert_equal(refs["enhance_contrast_percentile"], rank.enhance_contrast_percentile(image, selem))
    assert_equal(refs["pop"], rank.pop(image, selem))
    assert_equal(refs["pop_percentile"], rank.pop_percentile(image, selem))
    assert_equal(refs["pop_bilateral"], rank.pop_bilateral(image, selem))
    assert_equal(refs["sum"], rank.sum(image, selem))
    assert_equal(refs["sum_bilateral"], rank.sum_bilateral(image, selem))
    assert_equal(refs["sum_percentile"], rank.sum_percentile(image, selem))
    assert_equal(refs["threshold"], rank.threshold(image, selem))
    assert_equal(refs["threshold_percentile"], rank.threshold_percentile(image, selem))
    assert_equal(refs["tophat"], rank.tophat(image, selem))
    assert_equal(refs["noise_filter"], rank.noise_filter(image, selem))
    assert_equal(refs["entropy"], rank.entropy(image, selem))
    assert_equal(refs["otsu"], rank.otsu(image, selem))
    assert_equal(refs["percentile"], rank.percentile(image, selem))
    assert_equal(refs["windowed_histogram"], rank.windowed_histogram(image, selem))
from skimage import data
from skimage.morphology import disk
from skimage.filters import threshold_otsu, rank
from skimage.util import img_as_ubyte


matplotlib.rcParams['font.size'] = 9


img = img_as_ubyte(data.page())

radius = 15
selem = disk(radius)

local_otsu = rank.otsu(img, selem)
threshold_global_otsu = threshold_otsu(img)
global_otsu = img >= threshold_global_otsu


fig, ax = plt.subplots(2, 2, figsize=(8, 5))
ax1, ax2, ax3, ax4 = ax.ravel()

fig.colorbar(ax1.imshow(img, cmap=plt.cm.gray),
           ax=ax1, orientation='horizontal')
ax1.set_title('Original')
ax1.axis('off')

fig.colorbar(ax2.imshow(local_otsu, cmap=plt.cm.gray),
           ax=ax2, orientation='horizontal')
ax2.set_title('Local Otsu (radius=%d)' % radius)
Exemple #38
0
def pp_lotsu_eqhist(image, otsu_rad=5):
    byte_img = img_as_ubyte(image)
    selem = disk(otsu_rad)
    local_otsu = rank.otsu(byte_img, selem)
    eq_hist_img = equalize_hist(local_otsu)
    return eq_hist_img
def otsuThresholdLocal(img, radius = 15):
    selem = disk(radius)
    local_otsu = rank.otsu(img, selem)
    local_otsu = img >= local_otsu

    return local_otsu.astype(int)
#
#     Local is much slower than global thresholding. A function for global
#     Otsu thresholding can be found in : `skimage.filters.threshold_otsu`.
#
# .. [4] http://en.wikipedia.org/wiki/Otsu's_method

from skimage.filters.rank import otsu
from skimage.filters import threshold_otsu

p8 = data.page()

radius = 10
selem = disk(radius)

# t_loc_otsu is an image
t_loc_otsu = otsu(p8, selem)
loc_otsu = p8 >= t_loc_otsu

# t_glob_otsu is a scalar
t_glob_otsu = threshold_otsu(p8)
glob_otsu = p8 >= t_glob_otsu

fig, ax = plt.subplots(2, 2, sharex=True, sharey=True)
ax1, ax2, ax3, ax4 = ax.ravel()

fig.colorbar(ax1.imshow(p8, cmap=plt.cm.gray), ax=ax1)
ax1.set_title('Original')

fig.colorbar(ax2.imshow(t_loc_otsu, cmap=plt.cm.gray), ax=ax2)
ax2.set_title('Local Otsu ($r=%d$)' % radius)
Exemple #41
0
def local_otsu(image):
    radius = 12
    s_elem = disk(radius)
    local = rank.otsu(image, s_elem)
    return local
Exemple #42
0
def lotsu(image, otsu_rad=5):
	byte_img = img_as_ubyte(image)
	selem = disk(otsu_rad)
	return rank.otsu(byte_img, selem)
Exemple #43
0
    rect[2] = pts[np.argmin(diff)]
    rect[1] = pts[np.argmax(diff)]    

    dst = np.float32([[0,0],[0,100],[200,0],[200,100]])
    
    M = cv2.getPerspectiveTransform(rect, dst)
    warp = cv2.warpPerspective(img_org, M, (200, 100))
    
    cv2.imshow("cropped image", warp)
    cv2.waitKey(0)
    
    warp = np.array(warp, dtype=np.uint8)
    radius = 10
    selem = disk(radius)
    
    local_otsu = rank.otsu(warp, selem)
    l_otsu = np.uint8(warp >= local_otsu)
    l_otsu *= 255
    
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(6,6))
    l_otsu = cv2.morphologyEx(l_otsu, cv2.MORPH_CLOSE, kernel)    
    cv2.imshow("binary image to be detected", l_otsu)
    cv2.waitKey(0)
    
    print("识别结果:")
    print(pytesseract.image_to_string(Image.fromarray(l_otsu)))
    
    cv2.waitKey(0)

# http://www.pyimagesearch.com/2014/03/10/building-pokedex-python-getting-started-step-1-6/