Пример #1
0
def get_kapur_threshold(image, mask=None):
    """The Kapur, Sahoo, & Wong method of thresholding, adapted to log-space."""
    cropped_image = np.array(image.flat) if mask is None else image[mask]
    if np.product(cropped_image.shape) < 3:
        return 0
    if np.min(cropped_image) == np.max(cropped_image):
        return cropped_image[0]
    log_image = np.log2(smooth_with_noise(cropped_image, 8))
    min_log_image = np.min(log_image)
    max_log_image = np.max(log_image)
    histogram = scipy.ndimage.histogram(log_image, min_log_image, max_log_image, 256)
    histogram_values = min_log_image + (max_log_image - min_log_image) * np.array(range(256), float) / 255
    # drop any zero bins
    keep = histogram != 0
    histogram = histogram[keep]
    histogram_values = histogram_values[keep]
    # check for corner cases
    if np.product(histogram_values) == 1:
        return 2 ** histogram_values[0]
    # Normalize to probabilities
    p = histogram.astype(float) / float(np.sum(histogram))
    # Find the probabilities totals up to and above each possible threshold.
    lo_sum = np.cumsum(p)
    hi_sum = lo_sum[-1] - lo_sum
    lo_e = np.cumsum(p * np.log2(p))
    hi_e = lo_e[-1] - lo_e

    # compute the entropies
    lo_entropy = lo_e / lo_sum - np.log2(lo_sum)
    hi_entropy = hi_e / hi_sum - np.log2(hi_sum)

    sum_entropy = lo_entropy[:-1] + hi_entropy[:-1]
    sum_entropy[np.logical_not(np.isfinite(sum_entropy))] = np.Inf
    entry = np.argmin(sum_entropy)
    return 2 ** ((histogram_values[entry] + histogram_values[entry + 1]) / 2)
Пример #2
0
 def test_02_smooth_half(self):
     out = cpms.smooth_with_noise(np.ones((100,100))*.5, 5)
     # Roughly 1/2 (5000) should be above .5 and half below
     # Over 1/2 should be within 1/32 of .5
     self.assertTrue(out.ndim == 2)
     self.assertTrue(out.shape[0] == 100)
     self.assertTrue(out.shape[1] == 100)
     self.assertTrue(abs(np.sum(out > .5)-5000) < 300) # unless we are 3sd unlucky
     self.assertTrue(np.sum(np.abs(out-.5)< 1.0 / 32.0) > 4700) # unless we are > 3sd unlucky 
Пример #3
0
 def test_02_smooth_half(self):
     out = cpms.smooth_with_noise(np.ones((100,100))*.5, 5)
     # Roughly 1/2 (5000) should be above .5 and half below
     # Over 1/2 should be within 1/32 of .5
     self.assertTrue(out.ndim == 2)
     self.assertTrue(out.shape[0] == 100)
     self.assertTrue(out.shape[1] == 100)
     self.assertTrue(abs(np.sum(out > .5)-5000) < 300) # unless we are 3sd unlucky
     self.assertTrue(np.sum(np.abs(out-.5)< 1.0 / 32.0) > 4700) # unless we are > 3sd unlucky 
Пример #4
0
 def test_03_img_1201(self):
     '''Regression test of img-1201'''
     #
     # Using internal knowledge: smooth_with_noise always seeds with 0
     #
     np.random.seed(0)
     r = np.random.normal(size=(10, 20))
     img = np.random.uniform(size=(10, 20))
     for bits in range(8, 17):
         result = cpms.smooth_with_noise(img, bits)
         im = img.copy()
         delta = 1.0 / float(2**bits)
         im[im < delta] = delta
         expected = np.exp2(
             np.log2(im) + (np.log2(im + 2.0**-bits) - np.log2(im)) * r)
         expected = np.clip(expected, 0, 1)
         np.testing.assert_almost_equal(result, expected)
Пример #5
0
 def test_03_img_1201(self):
     '''Regression test of img-1201'''
     #
     # Using internal knowledge: smooth_with_noise always seeds with 0
     #
     np.random.seed(0)
     r = np.random.normal(size=(10,20))
     img = np.random.uniform(size=(10,20))
     for bits in range(8,17):
         result = cpms.smooth_with_noise(img, bits)
         im = img.copy()
         delta = 1.0 / float(2**bits)
         im[im < delta] = delta
         expected = np.exp2(np.log2(im) + 
                            (np.log2(im + 2.0 ** -bits) - np.log2(im)) * r)
         expected = np.clip(expected, 0, 1)
         np.testing.assert_almost_equal(result, expected)
Пример #6
0
def get_kapur_threshold(image, mask=None):
    """The Kapur, Sahoo, & Wong method of thresholding, adapted to log-space."""
    cropped_image = np.array(image.flat) if mask is None else image[mask]
    if np.product(cropped_image.shape)<3:
        return 0
    if np.min(cropped_image) == np.max(cropped_image):
        return cropped_image[0]
    log_image = np.log2(smooth_with_noise(cropped_image, 8))
    min_log_image = np.min(log_image)
    max_log_image = np.max(log_image)
    histogram = scipy.ndimage.histogram(log_image,
                                        min_log_image,
                                        max_log_image,
                                        256)
    histogram_values = (min_log_image + (max_log_image - min_log_image)*
                        np.array(range(256),float) / 255)
    # drop any zero bins
    keep = histogram != 0
    histogram = histogram[keep]
    histogram_values = histogram_values[keep]
    # check for corner cases
    if np.product(histogram_values)==1:
        return 2**histogram_values[0] 
    # Normalize to probabilities
    p = histogram.astype(float) / float(np.sum(histogram))
    # Find the probabilities totals up to and above each possible threshold.
    lo_sum = np.cumsum(p);
    hi_sum = lo_sum[-1] - lo_sum;
    lo_e = np.cumsum(p * np.log2(p));
    hi_e = lo_e[-1] - lo_e;

    # compute the entropies
    lo_entropy = lo_e / lo_sum - np.log2(lo_sum);
    hi_entropy = hi_e / hi_sum - np.log2(hi_sum);

    sum_entropy = lo_entropy[:-1] + hi_entropy[:-1];
    sum_entropy[np.logical_not(np.isfinite(sum_entropy))] = np.Inf
    entry = np.argmin(sum_entropy);
    return 2**((histogram_values[entry] + histogram_values[entry+1]) / 2);
Пример #7
0
def sum_of_entropies(image, mask, binary_image):
    """Bin the foreground and background pixels and compute the entropy 
    of the distribution of points among the bins
    """
    mask = mask.copy()
    mask[np.isnan(image)] = False
    if not np.any(mask):
        return 0
    #
    # Clamp the dynamic range of the foreground
    #
    minval = np.max(image[mask]) / 256
    if minval == 0:
        return 0
    clamped_image = image.copy()
    clamped_image[clamped_image < minval] = minval
    #
    # Smooth image with -8 bits of noise
    #
    image = smooth_with_noise(clamped_image, 8)
    im_min = np.min(image)
    im_max = np.max(image)
    #
    # Figure out the bounds for the histogram
    #
    upper = np.log2(im_max)
    lower = np.log2(im_min)
    if upper == lower:
        # All values are the same, answer is log2 of # of pixels
        return math.log(np.sum(mask), 2)
    #
    # Create log-transformed lists of points in the foreground and background
    #
    fg = image[binary_image & mask]
    bg = image[(~binary_image) & mask]
    if len(fg) == 0 or len(bg) == 0:
        return 0
    log_fg = np.log2(fg)
    log_bg = np.log2(bg)
    #
    # Make these into histograms
    hfg = numpy_histogram(log_fg, 256, range=(lower, upper))[0]
    hbg = numpy_histogram(log_bg, 256, range=(lower, upper))[0]
    #hfg = scipy.ndimage.histogram(log_fg,lower,upper,256)
    #hbg = scipy.ndimage.histogram(log_bg,lower,upper,256)
    #
    # Drop empty bins
    #
    hfg = hfg[hfg > 0]
    hbg = hbg[hbg > 0]
    if np.product(hfg.shape) == 0:
        hfg = np.ones((1, ), int)
    if np.product(hbg.shape) == 0:
        hbg = np.ones((1, ), int)
    #
    # Normalize
    #
    hfg = hfg.astype(float) / float(np.sum(hfg))
    hbg = hbg.astype(float) / float(np.sum(hbg))
    #
    # Compute sum of entropies
    #
    return np.sum(hfg * np.log2(hfg)) + np.sum(hbg * np.log2(hbg))
Пример #8
0
 def test_01_smooth_zero(self):
     """Make sure smooth doesn't crash on all zeros"""
     out = cpms.smooth_with_noise(np.zeros((3, 3)), 5)
     self.assertTrue(np.all(out >= 0))
     self.assertTrue(np.all(out <= 1))
Пример #9
0
def sum_of_entropies(image, mask, threshold):
    """Bin the foreground and background pixels and compute the entropy 
    of the distribution of points among the bins
    """
    mask=mask.copy()
    mask[np.isnan(image)] = False
    if not np.any(mask):
        return 0
    #
    # Clamp the dynamic range of the foreground
    #
    minval = np.max(image[mask])/256
    if minval == 0:
        return 0
    clamped_image = image.copy()
    clamped_image[clamped_image < minval] = minval
    #
    # Smooth image with -8 bits of noise
    #
    image = smooth_with_noise(clamped_image, 8)
    im_min = np.min(image)
    im_max = np.max(image)
    #
    # Figure out the bounds for the histogram
    #
    upper = np.log2(im_max)
    lower = np.log2(im_min)
    if upper == lower:
        # All values are the same, answer is log2 of # of pixels
        return math.log(np.sum(mask),2) 
    #
    # Create log-transformed lists of points in the foreground and background
    # 
    fg = image[np.logical_and(mask, image >= threshold)]
    bg = image[np.logical_and(mask, image < threshold)]
    if len(fg) == 0 or len(bg) == 0:
        return 0
    log_fg = np.log2(fg)
    log_bg = np.log2(bg)
    #
    # Make these into histograms
    hfg = numpy_histogram(log_fg, 256, range=(lower,upper))[0]
    hbg = numpy_histogram(log_bg, 256, range=(lower,upper))[0]
    #hfg = scipy.ndimage.histogram(log_fg,lower,upper,256)
    #hbg = scipy.ndimage.histogram(log_bg,lower,upper,256)
    #
    # Drop empty bins
    #
    hfg = hfg[hfg>0]
    hbg = hbg[hbg>0]
    if np.product(hfg.shape) == 0:
        hfg = np.ones((1,),int)
    if np.product(hbg.shape) == 0:
        hbg = np.ones((1,),int)
    #
    # Normalize
    #
    hfg = hfg.astype(float) / float(np.sum(hfg))
    hbg = hbg.astype(float) / float(np.sum(hbg))
    #
    # Compute sum of entropies
    #
    return np.sum(hfg * np.log2(hfg)) + np.sum(hbg*np.log2(hbg))
Пример #10
0
 def test_01_smooth_zero(self):
     """Make sure smooth doesn't crash on all zeros"""
     out = cpms.smooth_with_noise(np.zeros((3,3)), 5)
     self.assertTrue(np.all(out >=0))
     self.assertTrue(np.all(out <=1))