def test_run_distance(image, module, image_set, workspace): module.operation.value = "Distance" module.x_name.value = "binary" module.y_name.value = "watershed" module.connectivity.value = 3 data = image.pixel_data if image.multichannel: data = skimage.color.rgb2gray(data) threshold = skimage.filters.threshold_otsu(data) binary = data > threshold image_set.add( "binary", cellprofiler.image.Image( image=binary, convert=False, dimensions=image.dimensions ) ) module.run(workspace) original_shape = binary.shape distance = scipy.ndimage.distance_transform_edt(binary) distance = mahotas.stretch(distance) surface = distance.max() - distance if image.volumetric: footprint = numpy.ones((3, 3, 3)) else: footprint = numpy.ones((3, 3)) peaks = mahotas.regmax(distance, footprint) if image.volumetric: markers, _ = mahotas.label(peaks, numpy.ones((16, 16, 16))) else: markers, _ = mahotas.label(peaks, numpy.ones((16, 16))) expected = mahotas.cwatershed(surface, markers) expected = expected * binary expected = skimage.measure.label(expected) actual = workspace.get_objects("watershed") actual = actual.segmented numpy.testing.assert_array_equal(expected, actual)
def get_seeds(boundary, method='grid', next_id=1): if method == 'grid': height = boundary.shape[0] width = boundary.shape[1] seed_positions = np.ogrid[0:height:seed_distance, 0:width:seed_distance] num_seeds_y = seed_positions[0].size num_seeds_x = seed_positions[1].size num_seeds = num_seeds_x * num_seeds_y seeds = np.zeros_like(boundary).astype(np.int32) seeds[seed_positions] = np.arange(next_id, next_id + num_seeds).reshape( (num_seeds_y, num_seeds_x)) if method == 'minima': minima = mahotas.regmin(boundary) seeds, num_seeds = mahotas.label(minima) seeds += next_id seeds[seeds == next_id] = 0 if method == 'maxima_distance': distance = mahotas.distance(boundary < 0.5) maxima = mahotas.regmax(distance) seeds, num_seeds = mahotas.label(maxima) seeds += next_id seeds[seeds == next_id] = 0 return seeds, num_seeds
def label(im, n=4): '''Labels connected components in an image. Parameters ---------- im: numpy.ndarray[numpy.bool] binary image that should be labeled n: int, optional neighbourhood (default: ``4``, choices: ``{4, 8}``) Returns ------- numpy.ndarray[int] labeled image Raises ------ ValueError when `n` is not ``4`` or ``8`` ''' if n not in {4, 8}: raise ValueError('Neighbourhood must be 4 or 8.') if n == 8: strel = np.ones((3, 3), bool) labeled_image, n_objects = mh.label(im>0, strel) else: labeled_image, n_objects = mh.label(im>0) return labeled_image
def label(im, n=4): '''Labels connected components in an image. Parameters ---------- im: numpy.ndarray[numpy.bool] binary image that should be labeled n: int, optional neighbourhood (default: ``4``, choices: ``{4, 8}``) Returns ------- numpy.ndarray[int] labeled image Raises ------ ValueError when `n` is not ``4`` or ``8`` ''' if n not in {4, 8}: raise ValueError('Neighbourhood must be 4 or 8.') if n == 8: strel = np.ones((3, 3), bool) labeled_image, n_objects = mh.label(im > 0, strel) else: labeled_image, n_objects = mh.label(im > 0) return labeled_image
def start(self): """Segment the frame. The returned value is a labeled uint16 image. """ background = np.bincount(self._frame.ravel()).argmax() # Most common value. I_label = measure.label(self._frame, background=background) I_label += 1 # Background is labeled as -1, make it 0. I_bin = I_label > 0 # Remove cells which are too small (leftovers). if self._a_min: I_label = mh.label(I_bin)[0] sizes = mh.labeled.labeled_size(I_label) too_small = np.where(sizes < self._a_min) I_cleanup = mh.labeled.remove_regions(I_label, too_small) I_bin = I_cleanup > 0 # Fill holes. if self._fill: I_bin = ndimage.morphology.binary_fill_holes(I_bin) # Small holes. # Bigger holes. labels = measure.label(I_bin) label_count = np.bincount(labels.ravel()) background = np.argmax(label_count) I_bin[labels != background] = True I_label = mh.label(I_bin)[0].astype('uint16') return I_label
def as_labeled(fname): '''Load the image as a labeled image''' # Read the image im = mh.imread(fname) # borders are saved as red lines borders = (im[:, :, 0] > im[:, :, 1]) # first labeling labeled, N = mh.label(~borders) # with modern mahotas, this would be done with mh.labeled.labeled_size() # but this function did not exist when the paper was written bg = 0 bg_size = (labeled == bg).sum() for i in range(1, N + 1): i_size = (labeled == i).sum() if i_size > bg_size: bg_size = i_size bg = i if i_size < _min_obj_size: labeled[labeled == i] = 0 labeled[labeled == bg] = 0 labeled, _ = mh.label(labeled != 0) assert labeled.max() < 256 return labeled.astype(np.uint8)
def test_run_distance(image, module, image_set, workspace): module.use_advanced.value = False module.operation.value = "Distance" module.x_name.value = "binary" module.y_name.value = "watershed" module.footprint.value = 3 data = image.pixel_data if image.multichannel: data = skimage.color.rgb2gray(data) threshold = skimage.filters.threshold_otsu(data) binary = data > threshold image_set.add( "binary", cellprofiler_core.image.Image( image=binary, convert=False, dimensions=image.dimensions ), ) module.run(workspace) original_shape = binary.shape distance = scipy.ndimage.distance_transform_edt(binary) distance = mahotas.stretch(distance) surface = distance.max() - distance if image.volumetric: footprint = numpy.ones((3, 3, 3)) else: footprint = numpy.ones((3, 3)) peaks = mahotas.regmax(distance, footprint) if image.volumetric: markers, _ = mahotas.label(peaks, numpy.ones((16, 16, 16))) else: markers, _ = mahotas.label(peaks, numpy.ones((16, 16))) expected = mahotas.cwatershed(surface, markers) expected = expected * binary expected = skimage.measure.label(expected) actual = workspace.get_objects("watershed") actual = actual.segmented numpy.testing.assert_array_equal(expected, actual)
def eliminate_vessel_neighbors(self): # first get the regions to be masked drusen = self.get_predicted_region(Labels.Drusen) blood = self.get_predicted_region(Labels.Haemorage) # and the vessel region vessels = self.get_predicted_region(Labels.BloodVessel) combined = drusen + blood + vessels # mark regions of interest combined[combined == Labels.Drusen] = Labels.Masked combined[combined == Labels.Haemorage] = Labels.Masked # label them - we don't care about the labels. Bc = np.ones((9, 9)) regions, n_regions = mh.label(vessels, Bc) vessel_regions, n_vessels = mh.label(vessels, Bc) seeds = [] # find vessel seeds for vessel in range(1, vessel_regions.max() + 1): nonz = np.nonzero(vessel_regions == vessel) # for OpenCV it's (x, y) i.e. (col, row) seeds.append((nonz[1][0], nonz[0][0])) # flood-fill all the regions with the BloodVessel mask for seed in seeds: self._flood_fill(seed, self._prediction, Labels.BloodVessel, deltaHigh = Labels.Masked - Labels.BloodVessel)
def countCones(self): self.ConeCounts.SetRegionalMaxima(mh.regmax(self.params['curImage'])) s,ncones=mh.label(self.ConeCounts.RegionalMaxima) self.ConeCounts.SetSeeds(s) self.ConeCounts.SetNpoints(ncones) if self.params['min_cone_size'] > 0: mask = np.ones((self.params['min_cone_size'],self.params['min_cone_size'])) rm=mh.dilate(self.ConeCounts.RegionalMaxima,mask) self.ConeCounts.SetRegionalMaxima(mh.regmax(rm)) s,ncones = mh.label(self.ConeCounts.RegionalMaxima) self.ConeCounts.SetSeeds(s) self.ConeCounts.SetNpoints(ncones)
def Watershed_MRF(Iin, I_MM): # ------------------------------------------------------------------------------------ # # # # This algorithm is implemented by Oren Kraus on July 2013 # # # # ------------------------------------------------------------------------------------ # Fgm = (I_MM > 0) SdsLab = mh.label(I_MM == 2)[0] SdsSizes = mh.labeled.labeled_size(SdsLab) too_small_Sds = np.where(SdsSizes < 30) SdsLab = mh.labeled.remove_regions(SdsLab, too_small_Sds) Sds = SdsLab > 0 se2 = nd.generate_binary_structure(2, 2).astype(np.int) dilatedNuc = nd.binary_dilation(Sds, se2) Fgm = (dilatedNuc.astype(np.int) + Fgm.astype(np.int)) > 0 FgmLab = mh.label(Fgm)[0] FgmSizes = mh.labeled.labeled_size(FgmLab) too_small_Fgm = np.where(FgmSizes < 30) FgmLab = mh.labeled.remove_regions(FgmLab, too_small_Fgm) Fgm = FgmLab > 0 se3 = nd.generate_binary_structure(2, 1).astype(np.int) Fgm = nd.binary_erosion(Fgm, structure=se3) Fgm_Lab, Fgm_num = nd.measurements.label(Fgm) Nuc_Loc_1d = np.where(np.ravel(Sds == 1))[0] for Lab in range(Fgm_num): Fgm_Loc_1d = np.where(np.ravel(Fgm_Lab == Lab))[0] if not bool((np.intersect1d(Fgm_Loc_1d, Nuc_Loc_1d)).any()): Fgm[Fgm_Lab == Lab] = 0 Im_ad = (np.double(Iin) * 2 ** 16 / Iin.max()).round() Im_ad = nd.filters.gaussian_filter(Im_ad, .5, mode='constant') Im_ad_comp = np.ones(Im_ad.shape) Im_ad_comp = Im_ad_comp * Im_ad.max() Im_ad_comp = Im_ad_comp - Im_ad mask = ((Sds == 1).astype(np.int) + (Fgm == 0).astype(np.int)) mask = nd.label(mask)[0] LabWater = mh.cwatershed(np.uint16(Im_ad_comp), mask) back_loc_1d = np.where(np.ravel(Fgm == 0))[0] for Lab in range(2, LabWater.max()): cell_Loc_1d = np.where(np.ravel(LabWater == Lab))[0] if bool((np.intersect1d(cell_Loc_1d, back_loc_1d)).any()): LabWater[LabWater == Lab] = 1 return LabWater
def test_label(): A = np.zeros((128,128), np.int) L,n = label(A) assert not L.max() assert n == 0 A[2:5, 2:5] = 34 A[10:50, 10:50] = 34 L,n = label(A) assert L.max() == 2 assert L.max() == n assert np.sum(L > 0) == (40*40 + 3*3) assert np.all( (L > 0) == (A > 0) ) assert set(L.ravel()) == set([0,1,2])
def test_label(): A = np.zeros((128, 128), np.int_) L, n = label(A) assert not L.max() assert n == 0 A[2:5, 2:5] = 34 A[10:50, 10:50] = 34 L, n = label(A) assert L.max() == 2 assert L.max() == n assert np.sum(L > 0) == (40 * 40 + 3 * 3) assert np.all((L > 0) == (A > 0)) assert set(L.ravel()) == set([0, 1, 2])
def _minima_seeds(pmap, start_id): minima = mahotas.regmin(pmap) seeds, num_seeds = mahotas.label(minima) seeds += start_id #seeds[seeds==start_id] = 0 # TODO I don't get this return seeds, num_seeds
def get_orientation(image, debug=False): bin_image = (image > threshold_li(image)) * 1 dilated = scipy.ndimage.morphology.binary_dilation(bin_image, iterations=30) labeled, num_regions = mh.label(dilated) sizes = mh.labeled.labeled_size(labeled) mh.labeled.labeled_size(labeled) if len(sizes) > 2: too_small = np.where(sizes < np.flip(np.sort(sizes))[1]) labeled = mh.labeled.remove_regions(labeled, too_small) labeled = (labeled / np.max(np.unique(labeled))).astype(np.int) skeleton = skeletonize(labeled) h, theta, d = hough_line(skeleton) origin = np.array((0, skeleton.shape[1])) for _, angle, dist in zip(*hough_line_peaks(h, theta, d)): y0, y1 = (dist - origin * np.cos(angle)) / np.sin(angle) gradient = (y0 - y1) / origin[1] if debug == False: return math.degrees(np.arctan(gradient)) elif debug == True: f, ax = plt.subplots(figsize=(40, 20)) plt.imshow(bin_image) plt.show() f, ax = plt.subplots(figsize=(40, 20)) plt.imshow(dilated) plt.show() f, ax = plt.subplots(figsize=(40, 20)) plt.imshow(skeleton) plt.show() return math.degrees(np.arctan(gradient))
def label(images): T = mh.thresholding.otsu(images) # calculate a threshold value dnaf = mh.gaussian_filter( images, 8) # apply a gaussian filter that smoothen the image dnat = dnaf > T # do threshold labelled = mh.label(dnat)[0] #labelling thereshold image return labelled
def analyze_edu(self, file): """ Calculates the number of counted cells and their coordinates with Gaussian filter preprocessing. Parameters ---------- file : str The path to the image. Returns ------- int The number of cells counted in the image. list Coordinates of all the cell "centers" in the EdU channel. """ img = mh.imread(file) imgg = mh.colors.rgb2gray(img) imggf = mh.gaussian_filter(imgg,11).astype(np.uint8) rmax = mh.regmax(imggf) edu_seeds, edu_nuclei = mh.label(rmax) edu_coords = mh.center_of_mass(imgg,labels=edu_seeds) return edu_nuclei,edu_coords
def analyze_edu_hist_eps(self, file, dapi_coords, checked): """ Calculates the number of counted cells and their coordinates with histogram equalization and Gaussian filter preprocessing and epsilon quality control. Parameters ---------- file : str The path to the image. dapi_coords : list Coordinates of all the cell "centers" in the DAPI channel. Used as a reference. checked : list Keeps track of which cells have already been counted in other channels. Returns ------- list Coordinates of all the cell "centers" in the EdU channel. int The number of cells counted in the image. list Keeps track of which cells have already been counted in other channels. """ img = mh.imread(file) imgg = mh.colors.rgb2gray(img) imgg = eq.hist_eq(imgg) imggf = mh.gaussian_filter(imgg,15.3).astype(np.uint8) rmax = mh.regmax(imggf) edu_seeds, edu_nuclei = mh.label(rmax) edu_coords = mh.center_of_mass(imgg,labels=edu_seeds) count, checked = self.epsilon(edu_coords,dapi_coords,checked) return edu_coords, count, checked
def check_img_status(image_edge): #after finding edge check the image to see if it is ok to fit the circle labeled, n_nucleus = mh.label(image_edge) if n_nucleus > 10: return 0 else: return 1
def voi(self, prob, label): prob = np.int64(1 - prob) f_image, n_labels = mahotas.label(prob) f_image = np.int64(f_image.flatten()) f_label = np.int64(label.flatten()) return n_labels, partition_comparison.variation_of_information( f_image, f_label)
def _process_image(self, im): thresh = skimage.filters.threshold_otsu(im) labeled, seeds = mahotas.label(im > thresh) labeled = mahotas.labeled.remove_bordering(labeled) features = [] for seed in range(1, seeds): precipitates = (labeled == seed).astype('int') m00 = mahotas.moments(precipitates, 0, 0) m01 = mahotas.moments(precipitates, 0, 1) m10 = mahotas.moments(precipitates, 1, 0) m11 = mahotas.moments(precipitates, 1, 1) m02 = mahotas.moments(precipitates, 0, 2) m20 = mahotas.moments(precipitates, 2, 0) xm = m10 / m00 ym = m01 / m00 u00 = 1.0 u11 = m11 / m00 - xm * ym u20 = m20 / m00 - xm ** 2 u02 = m02 / m00 - ym ** 2 w1 = u00**2 / (2.0 * numpy.pi * (u20 + u02)) w2 = u00**4 / (16.0 * numpy.pi * numpy.pi * (u20 * u02 - u11**2)) if numpy.isnan(w1) or numpy.isnan(w2) or numpy.isinf(w1) or numpy.isinf(w2): continue features.append(((xm, ym), [numpy.sqrt(m00), w1, w2, u20, u02]))# return features
def launchSearch(self): """ Move the cell around to try to cover the most ground """ for move in range(0, self.MAX_MOVES): self.moveCell() # the score is the mean value of the image #score = np.mean(self.canvas) # score is number of pixels with value > 5 T = 5 labeled, objNb = mh.label(self.canvas > T) regions = regionprops(labeled) score = regions[0].area #if self.SHOW_LOOPS and self.currentLoop == 0: if self.SHOW_LOOPS: # draw image fig = plt.figure() plt.imshow(self.canvas, cmap='terrain') plt.title("Score: " + str(score)) loopDir = "results" + os.sep + 'persistance-' + str(self.PERSISTANCE_INDEX) if not os.path.exists(loopDir): os.makedirs(loopDir) fig.savefig(loopDir + os.sep + "loop-" + str(self.currentLoop) + ".png", dpi=200) plt.close() return score
def find_ice(image, sobel_gradient_threshold, size_threshold): #sobel_gradient_threshold=0.05 #size threshold=100 shape = np.shape(image) image1 = preprocessing_for_icefinder(image) image2 = minimum_filter(image1, 4, mode='reflect') sobel1 = sobel(image2) image3 = sobel1 > sobel_gradient_threshold image4 = binary_fill_holes(mh.morph.dilate(image3)) #label and clear the image labeled, n_nucleus = mh.label(image4) sizes = mh.labeled.labeled_size(labeled) too_small = np.where(sizes < size_threshold) labeled = mh.labeled.remove_regions(labeled, too_small) relabeled, n_left = mh.labeled.relabel(labeled) if n_left > 20: print("can not locate ice in the image") else: image5 = relabeled > 0 #make the binary image image6 = resize(image5, shape, order=2, mode='symmetric', preserve_range=True) return image6
def filter_profiles_connected_components(img, min_seg_size): # Find 2D connected components (non-branching profiles) segments = mahotas.labeled.borders(img) == 0 segments[img == 0] = 0 profiles, nprofiles = mahotas.label(segments) profile_sizes = mahotas.labeled.labeled_size(profiles) too_small = np.nonzero(profile_sizes < min_seg_size)[0] too_small_area = np.sum(profile_sizes[too_small]) ok_area = np.sum(profile_sizes) - too_small_area zero_segments = np.unique(profiles[img == 0]) ignore_segments = np.union1d(zero_segments, too_small) if len(ignore_segments > 0): #print "Ignoring {0} zero-segments and {1} small segments.".format(len(zero_segments), len(too_small)) profiles, nprofiles = mahotas.labeled.relabel( mahotas.labeled.remove_regions(profiles, ignore_segments, inplace=True), inplace=True) profile_sizes = mahotas.labeled.labeled_size(profiles) return profiles, nprofiles, len( too_small), profile_sizes, too_small_area, ok_area
def count_holes(dir_name, extension='.tif', plotting = False, dpi = 300, transparent=True): total_holes = [] i = 0 for files in sorted(os.listdir(dir_name)): if files.endswith(extension): scan = os.path.join(dir_name,files) img = tf.imread(scan) img[img > 0] = -1 skel = mh.thin(img) noholes = mh.morph.close_holes(skel) cskel = np.logical_not(skel) choles = np.logical_not(noholes) holes = np.logical_and(cskel,noholes) lab, n = mh.label(holes) total_holes.append(n) if plotting: fig = plt.figure() plt.imshow(img) plt.tight_layout(pad=0) fig.savefig(dir_name + '/binary_{}_{:03d}.png'.format(dir_name,i+1), dpi=dpi, transparent=transparent) plt.close(fig) fig = plt.figure() plt.imshow(skel) plt.tight_layout(pad=0) fig.savefig(dir_name + '/skel_{}_{:03d}.png'.format(dir_name,i+1), dpi=dpi, transparent=transparent) plt.close(fig) fig = plt.figure() plt.imshow(lab) plt.tight_layout(pad=0) fig.savefig(dir_name + '/labels_{}_{:03d}.png'.format(dir_name,i+1), dpi=dpi, transparent=transparent) plt.close(fig) i += 1 return total_holes
def find_concave_regions(mask, max_dist): '''Finds convace regions along the contour of `mask`. Parameters ---------- mask: numpy.ndarray[numpy.bool] mask image max_dist: int maximally tolerated distance between concave point on object contour and the convex hull ''' contour_img = np.zeros(mask.shape, dtype=np.uint8) contour_img[mask] = 255 contour_img, contours, _ = cv2.findContours( contour_img, mode=cv2.RETR_EXTERNAL, method=cv2.CHAIN_APPROX_SIMPLE ) concave_img = np.zeros(mask.shape, dtype=np.bool) for cnt in contours: hull = cv2.convexHull(cnt, returnPoints=False) defects = cv2.convexityDefects(cnt, hull) if defects is not None: defect_pts = np.array([ cnt[defects[j, 0][2]][0] for j in xrange(defects.shape[0]) if defects[j, 0][3]/float(256) > max_dist ]) if defect_pts.size != 0: concave_img[defect_pts[:, 1], defect_pts[:, 0]] = True return mh.label(concave_img)
def _finalize_split_(self, input): #for c in i_js: # s_tile[c[1]-offset_y, c[0]-offset_x] = 0 tmp = np.array(i_js) - np.array([offset_x, offset_y]) s_tile_split = cv2.polylines(s_tile, [tmp], False, 0, 1) # lineType=cv2.LINE_8 label_image, n = mh.label(s_tile_split) # check which label was unselected selected_label = label_image[click[1] - offset_y, click[0] - offset_x] unselected_image = s_tile - (label_image == selected_label) self.__largest_id += 1 new_id = self.__largest_id full_coords = np.where(label_image > 0) full_bb = [ min(full_coords[1]), min(full_coords[0]), max(full_coords[1]), max(full_coords[0]) ] unselected_image = unselected_image * ( new_id - self.lookup_label(self.label_id)) tile = np.add(row_val, unselected_image).astype(np.uint32)
def chromatids_elements(TopHatedChromosome): '''Take a High pass filtered (or top hat) image of a chromosome and label the chromatids elements ''' threshed = TopHatedChromosome > 0 #threshed = mh.open(threshed) labthres, _ = mh.label(threshed) labsz = mh.labeled.labeled_size(labthres) mh.labeled.remove_regions_where(labthres, labsz < 2, inplace=True) threshed = labthres > 0 skel2 = mh.thin(threshed) bp2 = branchedPoints(skel2, showSE=False) > 0 rem = np.logical_and(skel2, np.logical_not(bp2)) labskel, _ = mh.labeled.label(rem) #print labskel.dtype size_sk = mh.labeled.labeled_size(labskel) #print size_sk skelem = mh.labeled.remove_regions_where(labskel, size_sk < 4) distances = mh.stretch(mh.distance(threshed)) surface = (distances.max() - distances) chr_label = mh.cwatershed(surface, skelem) #print chr_label.dtype, type(chr_label) chr_label *= threshed #This convertion is important !! chr_label = chr_label.astype(np.intc) #------------------------------- mh.labeled.relabel(chr_label, inplace=True) labsize2 = mh.labeled.labeled_size(chr_label) cleaned = mh.labeled.remove_regions_where(chr_label, labsize2 < 8) mh.labeled.relabel(cleaned, inplace=True) return cleaned
def perform_watershed(threshed, maxima): distances = mh.stretch(mh.distance(threshed)) spots, n_spots = mh.label(maxima, Bc=np.ones((3, 3))) surface = (distances.max() - distances) return sk.morphology.watershed(surface, spots, mask=threshed)
def run_evaluation_boundary_predictions(network_name): pathPrefix = './AC4_small/' img_gt_search_string = pathPrefix + 'labels/*.tif' img_pred_search_string = pathPrefix + 'boundaryProbabilities/'+network_name+'/*.tif' img_files_gt = sorted( glob.glob( img_gt_search_string ) ) img_files_pred = sorted( glob.glob( img_pred_search_string ) ) allVI = [] allVI_split = [] allVI_merge = [] allRand = [] allRand_split = [] allRand_merge = [] for i in xrange(np.shape(img_files_pred)[0]): print img_files_pred[i] im_gt = mahotas.imread(img_files_gt[i]) im_pred = mahotas.imread(img_files_pred[i]) im_pred = im_pred / 255.0 VI_score = [] VI_score_split = [] VI_score_merge = [] Rand_score = [] Rand_score_split = [] Rand_score_merge = [] start_time = time.clock() for thresh in np.arange(0,1,0.05): # white regions, black boundaries im_seg = im_pred>thresh # connected components seeds, nr_regions = mahotas.label(im_seg) result = segmentation_metrics(im_gt, seeds, seq=False) VI_score.append(result['VI']['F-score']) VI_score_split.append(result['VI']['split']) VI_score_merge.append(result['VI']['merge']) Rand_score.append(result['Rand']['F-score']) Rand_score_split.append(result['Rand']['split']) Rand_score_merge.append(result['Rand']['merge']) print "This took in seconds: ", time.clock() - start_time allVI.append(VI_score) allVI_split.append(VI_score_split) allVI_merge.append(VI_score_merge) allRand.append(Rand_score) allRand_split.append(Rand_score_split) allRand_merge.append(Rand_score_merge) with open(pathPrefix+network_name+'.pkl', 'wb') as file: cPickle.dump((allVI, allVI_split, allVI_merge, allRand, allRand_split, allRand_merge), file)
def analyze_dapi_hist(self, file): """ Calculates the number of counted cells and their coordinates with histogram equalization and Gaussian filter preprocessing. Parameters ---------- file : str The path to the image. Returns ------- list The coordinates of all the cell "centers." int The number of cells counted in the image. """ img = mh.imread(file) imgg = mh.colors.rgb2gray(img) imgg = eq.hist_eq(imgg) imggf = mh.gaussian_filter(imgg, 7.5).astype(np.uint8) rmax = mh.regmax(imggf) dapi_seeds, dapi_nuclei = mh.label(rmax) dapi_coords = mh.center_of_mass(imgg, labels=dapi_seeds) return dapi_coords, dapi_nuclei
def scan(inputfile, verbose, threshold): image = mh.imread(inputfile) labeled, nr_objects = mh.label(image > threshold) #print "%s has %d blobs" % (inputfile, nr_objects) size = mh.labeled.labeled_size(labeled) # keeping track of total pixels and blob count. # and create a list of blob sizes c = 1 total = 0 list = [] while c <= nr_objects: total = total + size[c] list.append(size[c]) c = c + 1 # sort the list of sizes list.sort(key=int) # print out the list of sizes if verbose == 1: i = 1 for item in list: print "[blob %d] %d pixels" % (i, item) i = i + 1 if verbose == 1: print "%s has a total of %d pixels" % (inputfile, total) return (nr_objects, total, threshold);
def method2(image, sigma): image = mh.imread(image)[:, :, 0] image = mh.gaussian_filter(image, sigma) image = mh.stretch(image) binimage = (image > mh.otsu(image)) labeled, _ = mh.label(binimage) return labeled
def method2(image, sigma): image = mh.imread(image)[:, :, 0] image = mh.gaussian_filter(image, sigma) image = mh.stretch(image) binimage = image > mh.otsu(image) labeled, _ = mh.label(binimage) return labeled
def watershed_adjusted_membranes(img_file_name, img_membrane_file_name): print 'reading image ' + img_file_name img = mahotas.imread(img_file_name) label_img = mahotas.imread(img_membrane_file_name) blur_img = scipy.ndimage.gaussian_filter(img, 1) #put boundaries as either extracellular/unlabeled space or gradient between two labeled regions into one image boundaries = label_img==0 boundaries[0:-1,:] = np.logical_or(boundaries[0:-1,:], np.diff(label_img, axis=0)!=0) boundaries[:,0:-1] = np.logical_or(boundaries[:,0:-1], np.diff(label_img, axis=1)!=0) #erode to be sure we include at least one membrane shrink_radius=4 y,x = np.ogrid[-shrink_radius:shrink_radius+1, -shrink_radius:shrink_radius+1] shrink_disc = x*x + y*y <= (shrink_radius ** 2) inside = mahotas.dilate(boundaries ==0, shrink_disc) #use watersheds to find the actual membranes (sort of) seeds = label_img.copy() seeds[np.nonzero(inside==0)] = 0 seeds,_ = mahotas.label(seeds == 0) wsImage = 255-np.uint8(scale_to_unit_interval(blur_img)*255) grow = mahotas.cwatershed(wsImage, seeds) membrane = np.zeros(img.shape, dtype=np.uint8) membrane[0:-1,:] = np.diff(grow, axis=0) != 0 membrane[:,0:-1] = np.logical_or(membrane[:,0:-1], np.diff(grow,axis=1) != 0) return np.uint8(membrane*255)
def rm_smallparts(image, celldiam, pmin): labeled, nr_objects = mh.label(image) sizes = mh.labeled.labeled_size(labeled) too_small = np.where(sizes < (celldiam * celldiam * pmin)) labeled = mh.labeled.remove_regions(labeled, too_small) Image_Current_T = labeled != 0 return Image_Current_T
def watershed(self, Ta=0): """ Identification of particles through inverted slope comparisons Parameters ----------- Ta : int Threshold value in which the particles will be identified by """ self.Ta = Ta dist = mh.distance(self.image > 0.05 * self.Ta) dist1 = dist dist = dist.max() - dist dist -= dist.min() # inverting color dist = dist / float(dist.ptp()) * 255 dist = dist.astype(np.uint8) self.dist = mh.stretch(dist, 0, 255) self.labels, self.n_particles = mh.label(self.image > 0.7 * self.Ta) thr = np.median(dist) # not accurate to particles detected(?) # but matches dist graph well thresh = (dist < thr) areas = 0.9 * mh.cwatershed(dist, self.labels) self.areas = areas * thresh return
def _distance_transform_seeds(pmap, threshold, start_id): distance = mahotas.distance(pmap < threshold) maxima = mahotas.regmax(distance) seeds, num_seeds = mahotas.label(maxima) seeds += start_id #seeds[seeds==start_id] = 0 # TODO I don't get this return seeds, num_seeds
def _segment(histone): markers = np.zeros_like(histone) markers[16::32, 16::32] = 1 markers, _ = mh.label(markers) regions = mh.cwatershed(histone.max() - mh.gaussian_filter(histone, 1.2).astype(int), markers) sizes = mh.labeled.labeled_size(regions.astype(np.intc)) invalid, = np.where(sizes < 512) return mh.labeled.relabel(mh.labeled.remove_regions(regions.astype(np.intc), invalid))
def maskFromROINumber(self, ROI_number=None): if ROI_number is None: ROI_mask = self.lastROI() else: ROI_mask = mahotas.label(self.currentMask)[0] == ROI_number assert np.any(ROI_mask) return ROI_mask
def perfomance_measure(gt_mask, estimated_seed_mask): """ :param gt_mask: ground truth mask :param estimated_seed_mask: seed mask generated using any algorithm :return: precision and recall values """ est = estimated_seed_mask.reshape(-1,) detected_nucleus = collections.Counter(est) gt = gt_mask.reshape(-1,) groundtruth_nucleus = collections.Counter(gt) total_nucleus_pixels = groundtruth_nucleus[50]+groundtruth_nucleus[100]+groundtruth_nucleus[150]+\ groundtruth_nucleus[200]+groundtruth_nucleus[1] correctly_segmented = float(np.sum(np.logical_and(est > 0, gt > 0))) Precision = correctly_segmented/float(detected_nucleus[1]) Recall = correctly_segmented/float(total_nucleus_pixels) est_labeled, est_nr_objects = mh.label(estimated_seed_mask) gt_labeled, gt_nr_objects = mh.label(gt_mask) property_list = regionprops(gt_labeled) for region in property_list: area = region.area perimeter = region.perimeter major_axis_length = region.major_axis_length minor_axis_length = region.minor_axis_length roundness = ((float(major_axis_length)/2)**2 * math.pi)/area solidity = region.solidity elongation = minor_axis_length/major_axis_length euler_number = region.euler_number print '_________________________________' print 'solidity', solidity print 'euler_number', euler_number print 'roundness', roundness print 'area', area print 'perimeter', perimeter print 'major_axis_length', major_axis_length print 'minor_axis_length', minor_axis_length print 'elongation', elongation print 'precision', Precision print '_________________________________' # bbox = region.bbox # temp = estimated_seed_mask[bbox[0]:bbox[2], bbox[1]:bbox[3]] # plt.imshow(temp) # plt.show() return Precision, Recall
def evaluate_classifier_vi_old(imName, imTrueName, thresholds=[0.5], classifier=None, classification=None): if classification == None: classification = classifyImage_MLP(imName, classifier, None, None, doThresh=False) #read the ground truth image imTrue = mahotas.imread(imTrueName) #compute variation of information imTrue = numpy.int32(imTrue.ravel()) vi = [] for thresh in thresholds: membraneLabels = classification > thresh #draw frame to to connect around image border membraneLabels = draw_frame(membraneLabels, 11, 1) #delete false postive detections inside cells membraneLabels, _ = mahotas.label(membraneLabels) membraneLabels = remove_small_regions(membraneLabels, 5000) #shrink membrane label labelImg, nrObjects = mahotas.label(membraneLabels == 0) labelImg = region_growing(labelImg) #delete regions that are too small labelImg = remove_small_regions(labelImg, 30) labelImg = region_growing(labelImg) labelImg = draw_frame(labelImg, 11, 0) if numpy.median(labelImg) == 0: print 'Too bad to be evaluated!' return numpy.inf labelImg = labelImg.ravel() vi.append(variation_of_information(imTrue, labelImg)) return numpy.min(vi)
def watershed(probs, radius): if probs.ndim == 3: shed = np.zeros(probs.shape) for n in xrange(probs.shape[0]): sel = disk(radius) minima = mh.regmin(probs[n], Bc=sel) markers, nr_markers = mh.label(minima) shed[n] = mh.cwatershed(probs[n], markers) else: sel = disk(radius) minima = mh.regmin(probs, Bc=sel) markers, nr_markers = mh.label(minima) shed = mh.cwatershed(probs, markers) return shed
def excludePixels(self, image, size_cutoff=1): labeled_image = mahotas.label(image)[0] for label_id in range(labeled_image.max() + 1): label_id_index = labeled_image == label_id if label_id_index.sum() <= size_cutoff: labeled_image[label_id_index] = 0 return labeled_image > 0
def segment(fname): dna = mh.imread(fname) dna = dna[:,:,0] sigma = 12. dnaf = mh.gaussian_filter(dna, sigma) T_mean = dnaf.mean() bin_image = dnaf > T_mean labeled, nr_objects = mh.label(bin_image) maxima = mh.regmax(mh.stretch(dnaf)) maxima = mh.dilate(maxima, np.ones((5,5))) maxima,_ = mh.label(maxima) dist = mh.distance(bin_image) dist = 255 - mh.stretch(dist) watershed = mh.cwatershed(dist, maxima) watershed *= bin_image return watershed
def test_float_input(): "[watershed]: Compare floating point input with integer input" f = np.random.random((128,64)) f = mh.gaussian_filter(f, 8.) f = mh.gaussian_filter(f, 8.) markers,_ = mh.label(mh.regmin(f)) f = np.round(f * 2**30) wf = mh.cwatershed(f / 2**30., markers) w32 = mh.cwatershed(f.astype(np.int32), markers) assert (wf == w32).mean() > .999
def moment_feats(im): thresh = skimage.filters.threshold_otsu(im) #plt.imshow(im > thresh) #plt.show() labeled, seeds = mahotas.label(im > thresh) labeled = mahotas.labeled.remove_bordering(labeled) features = [] for seed in range(1, seeds): precipitates = (labeled == seed).astype('int') m00 = mahotas.moments(precipitates, 0, 0) m01 = mahotas.moments(precipitates, 0, 1) m10 = mahotas.moments(precipitates, 1, 0) m11 = mahotas.moments(precipitates, 1, 1) m02 = mahotas.moments(precipitates, 0, 2) m20 = mahotas.moments(precipitates, 2, 0) #m12 = mahotas.moments(precipitates, 1, 2) #m21 = mahotas.moments(precipitates, 2, 1) #m22 = mahotas.moments(precipitates, 2, 2) #plt.imshow(precipitates) #plt.show() xm = m10 / m00 ym = m01 / m00 #if m00 < 1e-5: # continue #u00 = m00 u00 = 1.0 u11 = m11 / m00 - xm * ym u20 = m20 / m00 - xm ** 2 u02 = m02 / m00 - ym ** 2 w1 = u00**2 / (2.0 * numpy.pi * (u20 + u02)) w2 = u00**4 / (16.0 * numpy.pi * numpy.pi * (u20 * u02 - u11**2)) if w1 < 0.0 or w1 > 1.0 or w2 < 0.0 or w2 > 1.0 or numpy.isnan(w1) or numpy.isnan(w2): continue print m00, m01, m10, m11, m02, m20 print xm print ym print u00, u11, u20, u02 print w1, w2 1/0 features.append([numpy.sqrt(m00)])#w1, w2, , u20, u02 features = numpy.array(features) return features
def Rand_membrane_prob(im_pred, im_gt): Rand_score = [] for thresh in np.arange(0,1,0.05): # white regions, black boundaries im_seg = im_pred>thresh # connected components seeds, nr_regions = mahotas.label(im_seg) result = quick_Rand(im_gt, seeds) Rand_score.append(result) return np.max(Rand_score)
def get_areal_features(root, features_path, masks_dir, n_bins = 100): prep_out_path(features_path) files = os.listdir(root) df = pd.DataFrame(columns = range(n_bins * 2) + ['name', 'level']) names = pd.read_csv(labels_file) print "Starting extraction: ", time_now_str() for j, f in enumerate(files): label = names.loc[names['image'] == path.splitext(f)[0]] start = time.time() imr = ImageReader(root, f, masks_dir, gray_scale = True) drusen = get_predicted_region(imr.image, Labels.Drusen) blood = get_predicted_region(imr.image, Labels.Haemorage) Bc = np.ones((5, 5)) labels_drusen, n_drusen = mh.label(drusen, Bc) labels_blood, n_blood = mh.label(blood, Bc) area = float(cv2.countNonZero(imr.mask)) outp = np.array([], dtype = np.int) # sizes excluding background sizes_drusen = mhl.labeled_size(labels_drusen)[1:] / area sizes_blood = mhl.labeled_size(labels_blood)[1:] / area hist_druzen, _ = np.histogram(sizes_drusen, n_bins, (0, 1e-3)) hist_blood, _ = np.histogram(sizes_blood, n_bins, (0, 1e-3)) outp = np.r_[outp, hist_druzen] outp = np.r_[outp, hist_blood] outp = np.r_[outp, label.values[0]] df.loc[j] = outp print "Extracted: {0}, took {1:02.2f} sec ".format(f, time.time() - start) # write out the csv df.to_csv(path.join(features_path, prefix + ".csv"), index = False, header=True) print "Extracted: ", prefix, "@", time_now_str()
def test_labeled_bbox(): f = np.random.random((128,128)) f = f > .8 f,n = mh.label(f) result = mh.labeled.bbox(f) result_as = mh.labeled.bbox(f, as_slice=True) for _ in range(32): ix = np.random.randint(n+1) assert np.all(result[ix] == mh.bbox(f == ix)) assert np.all(result_as[ix] == mh.bbox(f == ix, as_slice=True))
def get_largest_component(im): ''' return the largest component of a binary image ''' assert im.dtype==bool, \ 'need to pass a binary image in (received %s)' % str(im.dtype) la = mahotas.label(im)[0] sums = ndimage.measurements.sum(la>0, la, range(1,la.max() + 1)) big_value = np.argmax(sums)+1 largest = la == big_value return largest
def watershedSegment(image, diskSize=20): gradmag = gradientMagnitudue(image) ## compute foreground markers # open image to create flat regions at cell centers se_disk = pymorph.sedisk(diskSize) image_opened = mahotas.open(image, se_disk); # define foreground markers as regional maxes of cells # this step is slow! foreground_markers = mahotas.regmax(image_opened) ## compute background markers # Threshold the image, cast it to the right datatype, and then calculate the distance image image_black_white = image_opened > mahotas.otsu(image_opened) image_black_white = image_black_white.astype('uint16') # note the inversion here- a key difference from the matlab algorithm # matlab distance is to nearest non-zero pixel # python distance is to nearest 0 pixel image_distance = pymorph.to_uint16(nd.distance_transform_edt(np.logical_not(image_black_white))) eight_conn = pymorph.sebox() distance_markers = mahotas.label(mahotas.regmin(image_distance, eight_conn))[0] image_dist_wshed, image_dist_wshed_lines =mahotas.cwatershed(image_distance, distance_markers, eight_conn, return_lines=True) background_markers = image_distance_watershed_lines - image_black_white all_markers = np.logical_or(foreground_markers, background_markers) # impose a min on the gradient image. assumes int64 gradmag2 = imimposemin(gradmag.astype(int), all_markers, eight_conn) # call watershed segmented_cells, segmented_cell_lines = mahotas.cwatershed(gradmag2, mahotas.label(all_markers)[0], eight_conn, return_lines=True) # seperate watershed regions segmented_cells[gradientMagnitudue(segmented_cells) > 0] = 0 return segmented_cells > 0, segmented_cells
def imagepreprocesslabel(pplimg, pplmangaoptype, pplotsuon, pplsamplethreshold, pplshapeinvertpic): #### if whitepores = True, invert the picture if ((pplmangaoptype==1) or (pplshapeinvertpic)): imgneg = pymorph.neg(pplimg) pplimg = imgneg ####conversion to bin via Otsu if (pplotsuon == 1): thresh = threshold_otsu(pplimg) imgotsu = pplimg > thresh imgtosaveotsu = Image.fromarray(np.uint8(imgotsu*255)) ####conversion to bin via threshad if (pplotsuon == 0): imgneg = pymorph.neg(pplimg) imgbinneg = pymorph.threshad(imgneg, pplsamplethreshold, 255) imgbin = pymorph.neg(imgbinneg) imgotsu = imgbin imgtosaveotsu = Image.fromarray(np.uint8(imgotsu*255)) imgotsuneg = imgbinneg ####labeling the Otsu output via mahotas or threshad if (pplotsuon == 1): imgneg = pymorph.neg(pplimg) imgotsuneg = pymorph.neg(imgotsu) imglabel, labelnum = mahotas.label(imgotsuneg) imgbin = imgotsuneg imgbinneg = imgotsu if (pplotsuon == 0): imglabel, labelnum = mahotas.label(imgbinneg) #print imglabel[974], labelnum # print other lines for debugging purposes return imglabel, labelnum, imgbin, imgbinneg, pplimg, imgneg, imgotsu, imgtosaveotsu, imgotsuneg
def nuclei_regions(comp_map): """ NUCLEI_REGIONS: extract "support regions" for nuclei. This function expects as input a "tissue components map" (as returned, for example, by segm.tissue_components) where values of 1 indicate pixels having a color corresponding to nuclei. It returns a set of compact support regions corresponding to the nuclei. :param comp_map: numpy.ndarray A mask identifying different tissue components, as obtained by classification in RGB space. The value 0 See segm.tissue.tissue_components() :return: """ # Deprecated:... # img_hem, _ = rgb2he(img0, normalize=True) # img_hem = denoise_tv_bregman(img_hem, HE_OPTS['bregm']) # Get a mask of nuclei regions by unsupervised clustering: # Vector Quantization: background, mid-intensity Hem and high intensity Hem # -train the quantizer for 3 levels # vq = KMeans(n_clusters=3) # vq.fit(img_hem.reshape((-1,1))) # -the level of interest is the brightest: # k = np.argsort(vq.cluster_centers_.squeeze())[2] # mask_hem = (vq.labels_ == k).reshape(img_hem.shape) # ...end deprecated # Final mask: mask = (comp_map == 1) # use the components classified by color # mask = morph.closing(mask, selem=HE_OPTS['strel1']) # mask = morph.opening(mask, selem=HE_OPTS['strel1']) # morph.remove_small_objects(mask, in_place=True) # mask = (mask > 0) mask = mahotas.close_holes(mask) morph.remove_small_objects(mask, in_place=True) dst = mahotas.stretch(mahotas.distance(mask)) Bc=np.ones((9,9)) lmax = mahotas.regmax(dst, Bc=Bc) spots, _ = mahotas.label(lmax, Bc=Bc) regions = mahotas.cwatershed(lmax.max() - lmax, spots) * mask return regions # end NUCLEI_REGIONS
def evaluate_classifier_vi_old(imName, imTrueName, thresholds=[0.5], classifier=None, classification=None): if classification==None: classification = classifyImage_MLP(imName, classifier, None, None, doThresh=False) #read the ground truth image imTrue = mahotas.imread(imTrueName) #compute variation of information imTrue = numpy.int32(imTrue.ravel()) vi = [] for thresh in thresholds: membraneLabels = classification>thresh #draw frame to to connect around image border membraneLabels = draw_frame(membraneLabels, 11, 1) #delete false postive detections inside cells membraneLabels, _ = mahotas.label(membraneLabels) membraneLabels = remove_small_regions(membraneLabels, 5000) #shrink membrane label labelImg, nrObjects = mahotas.label(membraneLabels==0) labelImg = region_growing(labelImg) #delete regions that are too small labelImg = remove_small_regions(labelImg, 30) labelImg = region_growing(labelImg) labelImg = draw_frame(labelImg,11,0) if numpy.median(labelImg) == 0: print 'Too bad to be evaluated!' return numpy.inf labelImg = labelImg.ravel() vi.append(variation_of_information(imTrue, labelImg)) return numpy.min(vi)
def peppers(): # This last image is the peppers.png file my_image = mh.imread(filename3) T = mh.otsu(my_image) b_image = (my_image > T) g_image = mh.gaussian_filter(b_image, 15) rmax = mh.regmax(g_image) labeled, nr_objects = mh.label(rmax) centers = mh.center_of_mass(my_image, labeled)[1:] print "The peppers.png file contains ", nr_objects, " objects." o = 1 for center in centers: print "Object %s center: [ %s, %s ]" %(o, round(center[1], 0), round(center[0], 0)) o = o + 1
def GetConeCounts(self,region): """returns two values, total number of cones and number of cones in current region region = (xmin,xmax,ymax,ymin)""" if self.ConeCounts.Seeds is None: return (None,None) seeds = self.ConeCounts.Seeds mask = np.ones(self.orgImage.shape,np.bool) mask[region[3]:region[2],region[0]:region[1]] = 0 at_border = np.unique(seeds[mask]) #select seeds falling outside of the borders for obj in at_border: seeds[seeds == obj] = 0 [seeds,ncones] = mh.label(seeds) return (self.ConeCounts.nPoints,ncones)
def find_bright_regions(self, thresh = 0.005): ''' Finds suspicious bright regions, refines the prediction by: - Removing areas of large size: >= image * thresh ''' assert( 0 < thresh < 1), "Threshold is in (0, 1)" if self._prediction.size == 0: self._prediction = self.analyze_image().astype('uint8') # mask off OD - assumed to be the largest bright area self._mask_off_od() drusen = self.get_predicted_region(Labels.Drusen).astype('uint8') drusen [drusen != 0] = 255 # get blood self._blood_vessel_markers = self._blood.detect_vessels(drusen) # need to rescale the mask back to original size # the mask gets scaled down during haar transform of ExtractBloodVessels self._blood_markers = ImageReader.rescale_mask(self.image, self._blood_vessel_markers) # mask off blood vessels self._prediction [self._blood_markers != 0] = Labels.BloodVessel # cutoff area area = cv2.countNonZero(self._mask) * thresh # get bright regions and combine them ods = self.get_predicted_region(Labels.OD) drusen = self.get_predicted_region(Labels.Drusen) blood = self.get_predicted_region(Labels.Haemorage) combined = ods + drusen + blood # relabel the combined regions & calculate large removable regions # this will remove OD and related effects labelled, n = mh.label(combined, Bc = np.ones((5, 5))) sizes = mh.labeled.labeled_size(labelled)[1:] to_remove = np.argwhere(sizes >= area) + 1 # remove large areas from prediction matrix for i in to_remove: self._prediction [labelled == i] = Labels.Masked # morphological opening to remove spurious labels areas kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5)) self._prediction = cv2.morphologyEx(self._prediction, cv2.MORPH_OPEN, kernel) self.display_current(self._prediction) return self._prediction
def split_profiles_connected_components(img, size_mask=None): # Find 2D connected components (non-branching profiles) segments = mahotas.labeled.borders(img)==0 segments[img==0] = 0 profiles, nprofiles = mahotas.label(segments) if size_mask is None: profile_sizes = mahotas.labeled.labeled_size(profiles) else: masked_profiles = profiles masked_profiles[size_mask] = 0 profile_sizes = mahotas.labeled.labeled_size(masked_profiles) return profiles, nprofiles, profile_sizes