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_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) > 0.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, 0.1, 2000).astype(float) / 40.0 x1 = np.random.binomial(40, 0.5, 2000).astype(float) / 40.0 x2 = np.random.binomial(40, 0.9, 10000).astype(float) / 40.0 x = np.concatenate((x0, x1, x2)) self.assertTrue(otsu(x) > 0.5) self.assertTrue(otsu(x) < 0.9) self.assertTrue(otsu(x, max_threshold=0.5) >= 0.1) self.assertTrue(otsu(x, max_threshold=0.5) <= 0.5)
def test_03_min_threshold(self): """Test Otsu with a min_threshold""" numpy.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 = numpy.random.binomial(40,.1,10000).astype(float)/40.0 x1 = numpy.random.binomial(40,.5,2000).astype(float)/40.0 x2 = numpy.random.binomial(40,.9,2000).astype(float)/40.0 x = numpy.concatenate((x0,x1,x2)) self.assertTrue(otsu(x) >=.1) self.assertTrue(otsu(x) <=.5) self.assertTrue(otsu(x,min_threshold=.5) >= .5) self.assertTrue(otsu(x,min_threshold=.5) < .9)
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 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 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, .1, 10000).astype(float) / 40.0 x1 = np.random.binomial(40, .5, 2000).astype(float) / 40.0 x2 = np.random.binomial(40, .9, 2000).astype(float) / 40.0 x = np.concatenate((x0, x1, x2)) self.assertTrue(otsu(x) >= .1) self.assertTrue(otsu(x) <= .5) self.assertTrue(otsu(x, min_threshold=.5) >= .5) self.assertTrue(otsu(x, min_threshold=.5) < .9)
def test_04_max_threshold(self): """Test Otsu with a max_threshold""" numpy.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 = numpy.random.binomial(40, .1, 2000).astype(float) / 40.0 x1 = numpy.random.binomial(40, .5, 2000).astype(float) / 40.0 x2 = numpy.random.binomial(40, .9, 10000).astype(float) / 40.0 x = numpy.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 run(self, workspace): labeled_nuclei = workspace.object_set.get_objects(self.primary_objects.value).get_segmented() cell_image = workspace.image_set.get_image(self.image_name.value).pixel_data[:,:] image_collection = [] cell_treshold = otsu(cell_image, min_threshold=0, max_threshold=1) cell_binary = (cell_image >= cell_treshold) cell_distance = scipym.distance_transform_edt(cell_binary).astype(np.uint16) cell_labeled = skm.watershed(-cell_distance, labeled_nuclei, mask=cell_binary) # #fil hall and filter on syze the object in cell_labeled # cell_labeled = self.filter_on_border(cell_labeled) cell_labeled = fill_labeled_holes(cell_labeled) objects = cellprofiler.objects.Objects() objects.segmented = cell_labeled objects.parent_image = cell_image workspace.object_set.add_objects(objects, self.object_name.value) image_collection.append((cell_image, "Original")) image_collection.append((cell_labeled, "Labelized image")) workspace.display_data.image_collection = image_collection
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_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(0.1, 0.4, size=1000) x1 = np.random.uniform(0.6, 1.0, size=1000) x = np.append(x0, x1) np.random.shuffle(x) threshold = otsu(x) self.assertTrue(threshold >= 0.4) self.assertTrue(threshold <= 0.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 """ numpy.random.seed(0) x = numpy.zeros((10, )) self.assertTrue(otsu(x, min_threshold=.1) >= .1)
def test_02_TwoDistributions(self): """Test Otsu of two distributions with no points in between is between the two distributions""" numpy.random.seed(0) x0 = numpy.random.uniform(.1, .4, size=1000) x1 = numpy.random.uniform(.6, 1.0, size=1000) x = numpy.append(x0, x1) numpy.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=0.1) >= 0.1)
def run(self, workspace): image = workspace.image_set.get_image(self.image_name.value) nuclei_image = image.pixel_data[:,:] image_collection = [] # #Get the global Threshold with Otsu algorithm and smooth nuclei image # # nuclei_smoothed = self.smooth_image(image_collection[3][0], image.mask, 1) global_threshold_nuclei = otsu(nuclei_image, min_threshold=0, max_threshold=1) print "the threshold compute by the Otsu algorythm is %f" % global_threshold_nuclei # #Binary thee "DAPI" Image (Nuclei) and labelelize the nuclei # binary_nuclei = (nuclei_image >= global_threshold_nuclei) labeled_nuclei, object_count = scipy.ndimage.label(binary_nuclei, np.ones((3,3), bool)) print "the image got %d detected" % object_count # #Fill the hole and delete object witch touch the border. #labeled_nuclei is modify after the function #Filter small object and split object # labeled_nuclei = fill_labeled_holes(labeled_nuclei) labeled_nuclei = self.filter_on_border(labeled_nuclei) labeled_nuclei = self.filter_on_size(labeled_nuclei, object_count) labeled_nuclei = self.split_object(labeled_nuclei) # #Edge detection of nuclei image and object are more separated # labeled_nuclei_canny = skf.sobel(labeled_nuclei) labeled_nuclei[labeled_nuclei_canny > 0] = 0 labeled_nuclei = skr.minimum(labeled_nuclei.astype(np.uint16), skm.disk(3)) image_collection.append((nuclei_image, "Original")) image_collection.append((labeled_nuclei, "Labelized image")) workspace.display_data.image_collection = image_collection # #Create a new object which will be add to the workspace # objects = cellprofiler.objects.Objects() objects.segmented = labeled_nuclei objects.parent_image = nuclei_image workspace.object_set.add_objects(objects, self.object_name.value)
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_method.value = T.TM_OTSU_GLOBAL 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 cellprofiler.cpmath.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)
def test_01_TwoValues(self): """Test Otsu of two values is between the two""" x = otsu([0.2, 0.8]) self.assertTrue(x >= 0.2) self.assertTrue(x <= 0.8)