def test_06_NaN(self): """Regression test of Otsu with NaN in input (issue #624)""" r = np.random.RandomState() r.seed(6) data = r.uniform(size = 100) data[r.uniform(size = 100) > .8] = np.NaN self.assertEqual(otsu(data), otsu(data[~ np.isnan(data)])) self.assertEqual(entropy(data), entropy(data[~ np.isnan(data)])) self.assertEqual(otsu3(data), otsu3(data[~ np.isnan(data)])) self.assertEqual(entropy3(data), entropy3(data[~ np.isnan(data)]))
def test_04_max_threshold(self): """Test Otsu with a max_threshold""" np.random.seed(0) # # There should be three peaks with the otsu # between the second and third # With a fixed max threshold, the otsu # should be between the first two peaks. x0 = np.random.binomial(40,.1,2000).astype(float)/40.0 x1 = np.random.binomial(40,.5,2000).astype(float)/40.0 x2 = np.random.binomial(40,.9,10000).astype(float)/40.0 x = np.concatenate((x0,x1,x2)) self.assertTrue(otsu(x) > .5) self.assertTrue(otsu(x) < .9) self.assertTrue(otsu(x,max_threshold=.5) >=.1) self.assertTrue(otsu(x,max_threshold=.5) <=.5)
def get_otsu_threshold(image, mask = None, two_class_otsu = True, use_weighted_variance = True, assign_middle_to_foreground = True): if not mask is None: image = image[mask] else: image = np.array(image.flat) image = image[image >= 0] if len(image) == 0: return 1 image, d = log_transform(image) if two_class_otsu: if use_weighted_variance: threshold = otsu(image) else: threshold = entropy(image) else: if use_weighted_variance: t1, t2 = otsu3(image) else: t1,t2 = entropy3(image) threshold = t1 if assign_middle_to_foreground else t2 threshold = inverse_log_transform(threshold, d) return threshold
def get_ridler_calvard_threshold(image, mask = None): """Find a threshold using the method of Ridler and Calvard The reference for this method is: "Picture Thresholding Using an Iterative Selection Method" by T. Ridler and S. Calvard, in IEEE Transactions on Systems, Man and Cybernetics, vol. 8, no. 8, August 1978. """ 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] # We want to limit the dynamic range of the image to 256. Otherwise, # an image with almost all values near zero can give a bad result. min_val = np.max(cropped_image)/256; cropped_image[cropped_image < min_val] = min_val; im = np.log(cropped_image); min_val = np.min(im); max_val = np.max(im); im = (im - min_val)/(max_val - min_val); pre_thresh = 0; # This method needs an initial value to start iterating. Using # graythresh (Otsu's method) is probably not the best, because the # Ridler Calvard threshold ends up being too close to this one and in # most cases has the same exact value. new_thresh = otsu(im) delta = 0.00001; while abs(pre_thresh - new_thresh)>delta: pre_thresh = new_thresh; mean1 = np.mean(im[im<pre_thresh]); mean2 = np.mean(im[im>=pre_thresh]); new_thresh = np.mean([mean1,mean2]); return math.exp(min_val + (max_val-min_val)*new_thresh);
def test_03_min_threshold(self): """Test Otsu with a min_threshold""" np.random.seed(0) # # There should be three peaks with the otsu # between the first and second peaks. # With a fixed min threshold, the otsu # should be between the second two peaks. x0 = np.random.binomial(40, 0.1, 10000).astype(float) / 40.0 x1 = np.random.binomial(40, 0.5, 2000).astype(float) / 40.0 x2 = np.random.binomial(40, 0.9, 2000).astype(float) / 40.0 x = np.concatenate((x0, x1, x2)) self.assertTrue(otsu(x) >= 0.1) self.assertTrue(otsu(x) <= 0.5) self.assertTrue(otsu(x, min_threshold=0.5) >= 0.5) self.assertTrue(otsu(x, min_threshold=0.5) < 0.9)
def test_02_TwoDistributions(self): """Test Otsu of two distributions with no points in between is between the two distributions""" np.random.seed(0) x0 = np.random.uniform(.1,.4,size=1000) x1 = np.random.uniform(.6,1.0,size=1000) x = np.append(x0,x1) np.random.shuffle(x) threshold = otsu(x) self.assertTrue(threshold >= .4) self.assertTrue(threshold <= .6)
def test_05_threshold_of_flat(self): """Test Otsu with a threshold and all input values the same This is a regression test of an apparent bug where the Otsu of an all-zero image has a threshold of zero even though the min_threshold was .1 """ np.random.seed(0) x = np.zeros((10,)) self.assertTrue(otsu(x,min_threshold=.1)>=.1)
def test_05_01_otsu_wv(self): '''Test the weighted variance version of Otsu''' np.random.seed(0) image = np.hstack((np.random.exponential(1.5, size=600), np.random.poisson(15, size=300))) image.shape = (30, 30) image = stretch(image) limage, d = T.log_transform(image) threshold = otsu(limage) threshold = T.inverse_log_transform(threshold, d) expected = image > threshold workspace, module = self.make_workspace(image) module.binary.value = A.BINARY module.threshold_scope.value = I.TS_GLOBAL module.threshold_method.value = T.TM_OTSU module.use_weighted_variance.value = I.O_WEIGHTED_VARIANCE module.two_class_otsu.value = I.O_TWO_CLASS module.run(workspace) output = workspace.image_set.get_image(OUTPUT_IMAGE_NAME) self.assertTrue(np.all(output.pixel_data == expected))
def test_05_01_otsu_wv(self): '''Test the weighted variance version of Otsu''' np.random.seed(0) image = np.hstack((np.random.exponential(1.5,size=600), np.random.poisson(15,size=300))) image.shape=(30,30) image = stretch(image) limage, d = T.log_transform(image) threshold = otsu(limage) threshold = T.inverse_log_transform(threshold, d) expected = image > threshold workspace, module = self.make_workspace(image) module.binary.value = A.BINARY module.threshold_scope.value = I.TS_GLOBAL module.threshold_method.value = T.TM_OTSU module.use_weighted_variance.value = I.O_WEIGHTED_VARIANCE module.two_class_otsu.value = I.O_TWO_CLASS module.run(workspace) output = workspace.image_set.get_image(OUTPUT_IMAGE_NAME) self.assertTrue(np.all(output.pixel_data == expected))
from centrosome.otsu import otsu javabridge.start_vm(class_path=bioformats.JARS) try: app = wx.PySimpleApp() figure = matplotlib.figure.Figure() images = [] objects = [] masks = [] for i, arg in enumerate(sys.argv[1:]): img = bioformats.load_image(arg) images.append( ImageData("Image %d" % (i+1), img, alpha = 1.0 / (len(sys.argv) - 1), mode = MODE_COLORIZE)) thresh = otsu(img) l, _ = label(img >= thresh, np.ones((3,3), bool)) outline_color = tuple([int(idx == i) for idx in range(3)]) objects.append(ObjectsData( "Objects %d" % (i+1), [l], outline_color = outline_color, mode = MODE_LINES)) ii = np.linspace(-1, 1, num = img.shape[0])[:, np.newaxis] jj = np.linspace(-1, 1, num = img.shape[1])[np.newaxis, :] mask = (ii ** (2*i+2) + jj ** (2*i+2)) ** (1.0 / (2*i+2)) < .75 masks.append(MaskData("Mask %d" % (i+1), mask, mode = MODE_LINES, color = outline_color)) artist = CPImageArtist(images = images, objects=objects, masks = masks)
def test_01_TwoValues(self): """Test Otsu of two values is between the two""" x = otsu([.2,.8]) self.assertTrue(x >= .2) self.assertTrue(x <= .8)
javabridge.start_vm(class_path=bioformats.JARS) try: app = wx.PySimpleApp() figure = matplotlib.figure.Figure() images = [] objects = [] masks = [] for i, arg in enumerate(sys.argv[1:]): img = bioformats.load_image(arg) images.append( ImageData("Image %d" % (i + 1), img, alpha=1.0 / (len(sys.argv) - 1), mode=MODE_COLORIZE)) thresh = otsu(img) l, _ = label(img >= thresh, np.ones((3, 3), bool)) outline_color = tuple([int(idx == i) for idx in range(3)]) objects.append( ObjectsData("Objects %d" % (i + 1), [l], outline_color=outline_color, mode=MODE_LINES)) ii = np.linspace(-1, 1, num=img.shape[0])[:, np.newaxis] jj = np.linspace(-1, 1, num=img.shape[1])[np.newaxis, :] mask = (ii**(2 * i + 2) + jj**(2 * i + 2))**(1.0 / (2 * i + 2)) < .75 masks.append( MaskData("Mask %d" % (i + 1), mask, mode=MODE_LINES, color=outline_color))