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 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 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_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 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 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 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 _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(self, img): thresh = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) dist_transform = cv2.distanceTransform(thresh, cv2.cv.CV_DIST_L2, 3) maxima = mh.regmax(dist_transform, np.ones((3, 3))) (markers, ret3) = ndi.label(maxima) return random_walker(img, markers, beta=self.tolerance, mode='cg', tol=self.tolerance)
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 GradBasedSegmentation(im): blur = nd.gaussian_filter(im, 16) rmax = mahotas.regmax(blur) T = mahotas.thresholding.otsu(blur) bImg0 = im > T #bImg01=nd.binary_closing(bImg0,iterations=2) #bImg01=pymorph.close(bImg0, pymorph.sedisk(3)) #bImg=pymorph.open(bImg01, pymorph.sedisk(4)) bImg = pymorph.close(bImg0) b = pymorph.edgeoff(bImg) d = distanceTranform(b) seeds, nr_nuclei = nd.label(rmax) lab = mahotas.cwatershed(d, seeds) return BorderKill(lab)
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 get_com(self, scan_filter=(10, 10)): """ Calculates center of mass of particle using regional maxima calculated over the entire matrix Parameters ----------- scan_filter : int size of a weighted square region for regional maxima identification """ self.maxes = mh.regmax(self.image, Bc=np.ones(scan_filter)).astype(int) self.spots, n_spots = mh.label(self.maxes, Bc=np.ones(scan_filter)) com = mh.center_of_mass(self.image, self.spots) plt.imshow(self.spots) self.com = com return
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 sobel(img, just_filter=False): ''' edges = sobel(img, just_filter=False) Compute edges using Sobel's algorithm `edges` is a binary image of edges computed according to Sobel's algorithm. This implementation is tuned to match MATLAB's implementation. Parameters ---------- img : Any 2D-ndarray just_filter : boolean, optional If true, then return the result of filtering the image with the sobel filters, but do not threashold (default is False). Returns ------- edges : ndarray Binary image of edges, unless `just_filter`, in which case it will be an array of floating point values. ''' # This is based on Octave's implementation, # but with some reverse engineering to match Matlab exactly img = np.array(img, dtype=np.float) if img.ndim != 2: raise ValueError( 'mahotas.sobel: Only available for 2-dimensional images') img -= img.min() ptp = img.ptp() if ptp == 0: return img img /= ptp # Using 'nearest' seems to be MATLAB's implementation vfiltered = convolve(img, _vsobel_filter, mode='nearest') hfiltered = convolve(img, _hsobel_filter, mode='nearest') vfiltered **= 2 hfiltered **= 2 filtered = vfiltered filtered += hfiltered if just_filter: return filtered thresh = 2 * np.sqrt(filtered.mean()) return mh.regmax(filtered) * (np.sqrt(filtered) > thresh)
def sobel(img, just_filter=False): ''' edges = sobel(img, just_filter=False) Compute edges using Sobel's algorithm `edges` is a binary image of edges computed according to Sobel's algorithm. This implementation is tuned to match MATLAB's implementation. Parameters ---------- img : Any 2D-ndarray just_filter : boolean, optional If true, then return the result of filtering the image with the sobel filters, but do not threashold (default is False). Returns ------- edges : ndarray Binary image of edges, unless `just_filter`, in which case it will be an array of floating point values. ''' # This is based on Octave's implementation, # but with some reverse engineering to match Matlab exactly img = np.array(img, dtype=np.float) if img.ndim != 2: raise ValueError('mahotas.sobel: Only available for 2-dimensional images') img -= img.min() ptp = img.ptp() if ptp == 0: return img img /= ptp # Using 'nearest' seems to be MATLAB's implementation vfiltered = convolve(img, _vsobel_filter, mode='nearest') hfiltered = convolve(img, _hsobel_filter, mode='nearest') vfiltered **= 2 hfiltered **= 2 filtered = vfiltered filtered += hfiltered if just_filter: return filtered thresh = 2*np.sqrt(filtered.mean()) return mh.regmax(filtered) * (np.sqrt(filtered) > thresh)
def Particle_Separation_Analysis(self, cutoff=3): """Applys a gaussian filter to image to smooth edges.""" Bc_ = np.ones((self.n_pix, self.n_pix)) rmaxg = mh.regmax(self.image, Bc_) xsg, ysg = rmaxg.shape x = xsg * self.pix_to_micron # x image length | um y = ysg * self.pix_to_micron # y image length | um rho = self.n_seeds / (y * x) # Particle Density # l, w = np.shape(xloc) # mask = np.ones((l, w), dtype=bool) # mask[0:int((l + 1) / 2), 2:w] = False # xloc = (np.reshape(xloc[mask, ...], (-1, 2))) # xloc = xloc[int(l / 2), :] # da_mean = np.mean(da) * self.pix_to_micron # da_std = np.std(da) * self.pix_to_micron # plt.matshow(d) # plt.jet() return rho # , da_mean, da_std
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 circles(): # Image 1 is the circles.png file my_image = mh.imread(filename) # Threshold using the Riddler-Calvard method # More on Riddler-Calvard: http://mahotas.readthedocs.org/en/latest/thresholding.html thres = mh.rc(my_image) #use the value to form a binary image b_image = (my_image > thres) #use gaussian filter g_image = mh.gaussian_filter(b_image, 33) #separate objects stuck together rmax = mh.regmax(g_image) #count the number of objects in the picture labeled, nr_objects = mh.label(rmax) #find center point for each object centers = mh.center_of_mass(my_image, labeled)[1:] print "The circles.png file contains ", nr_objects, " objects." o = 1 for center in centers: print "Object %s center: %s" %(o, center) o = o + 1
def circles(): # Image 1 is the circles.png file my_image = mh.imread(filename) # Threshold using the Riddler-Calvard method # More on Riddler-Calvard: http://mahotas.readthedocs.org/en/latest/thresholding.html thres = mh.rc(my_image) #use the value to form a binary image b_image = (my_image > thres) #use gaussian filter g_image = mh.gaussian_filter(b_image, 33) #separate objects stuck together rmax = mh.regmax(g_image) #count the number of objects in the picture labeled, nr_objects = mh.label(rmax) #find center point for each object centers = mh.center_of_mass(my_image, labeled)[1:] print "The circles.png file contains ", nr_objects, " objects." o = 1 for center in centers: print "Object %s center: %s" % (o, center) o = o + 1
def identify_primary_objects(image, footprint=(16, 16), sigma=1): """ Identifies primary components in an image. """ response = skimage.filters.gaussian(image, sigma) mask = response > skimage.filters.threshold_li(response) image = mahotas.distance(mask) image = skimage.exposure.rescale_intensity(image) footprint = numpy.ones(footprint) markers = mahotas.regmax(image, footprint) markers, _ = mahotas.label(markers, footprint) image = numpy.max(image) - image return skimage.segmentation.watershed(image, markers, mask=mask)
def UpdateImage(self): sigma = self.Slider_Sigma.value()/2; dilate = self.Slider_Dilate.value() if self.Combo_ImageType.currentText() == 'DAPI': if self.Check_NoisyMode.isChecked(): self.DAPI_mask = mh.dilate(self.img_array > self.T_mean, np.ones((dilate, dilate))); self.gaussian_f = mh.gaussian_filter(self.img_array.astype('int'), sigma) else: self.gaussian_f = mh.gaussian_filter(self.img_array.astype('float'), sigma) self.DAPI_mask = mh.dilate(self.gaussian_f > self.gaussian_f.mean(), np.ones((dilate, dilate))); if self.Check_SingleColor.isChecked(): self.im_axes.imshow(mh.as_rgb(0, 0, self.DAPI_mask)); else: plt.imshow(mh.as_rgb(np.maximum(self.img_array,self.gaussian_f), self.gaussian_f, self.gaussian_f > self.T_otsu)) self.ClusterMap.setupUi(figure=self.im_figure, title='Image Display', xlabel='pixels (x)', ylabel='pixels(y)') self.Button_SNR.setEnabled(False); self.Check_TissueMaxima.setEnabled(False); self.DAPI_set_bool = True self.Text_Log.append('>Updated image; DAPI; sigma=%.1f,dilate=%d\n' % (sigma, dilate)) elif self.Combo_ImageType.currentText() == 'Fluorescence (Signal)': self.gaussian_f = mh.gaussian_filter(self.img_array.astype('float'), sigma) self.gT_mean = self.gaussian_f.mean() all_maximas = mh.regmax(self.gaussian_f) self.all_maximas = mh.dilate(all_maximas, np.ones((dilate, dilate))) if self.Check_TissueMaxima.isChecked(): self.tissue_maxima = self.all_maximas*self.Tissue_Mask self.im_axes.imshow(mh.as_rgb( np.maximum(255*self.tissue_maxima, self.gaussian_f), self.gaussian_f, self.img_array > self.gT_mean)) else: self.im_axes.imshow(mh.as_rgb( np.maximum(255*self.all_maximas, self.gaussian_f), self.gaussian_f, self.img_array > self.gT_mean)) self.ClusterMap.setupUi(figure=self.im_figure, title='Image Display', xlabel='pixels (x)', ylabel='pixels(y)') self.Text_Log.append('>Updated image; Mode: Fluor; sigma=%.1f,dilate=%d\n' % (sigma, dilate)) if self.DAPI_set_bool: self.Button_SNR.setEnabled(True); self.Check_TissueMaxima.setEnabled(True)
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 segment_nuc(im): T = mh.thresholding.otsu(im) # calculate a threshold value # Apply a gaussian filter to smooth the image smoothed = mh.gaussian_filter(im, 8) thresholded= smoothed > T # do threshold # Watershed smoothed = mh.gaussian_filter(im, 10) regional_max = mh.regmax(smoothed) dist_im = mh.distance(thresholded) seeds,count = mh.label(regional_max) # nuclei count watershedded = mh.cwatershed(dist_im, seeds) # Remove areas that aren't nuclei watershedded[np.logical_not(thresholded)] = 0 cell_id = ['abc', 'def', 'ghi'] # cell_centroid = [(1,2),(3,4)] # return watershedded, cell_id return watershedded
def watershed_from_image(image): bin_image = threshold_niblack(image) bin_image = image > bin_image / 0.8 bin_image = mh.label(bin_image)[0] sizes = mh.labeled.labeled_size(bin_image) bin_image = mh.labeled.remove_regions_where(bin_image, sizes < 50) bin_image = (bin_image > 0) * 1 distance = ndi.distance_transform_edt(bin_image) imagef = mh.gaussian_filter(image.astype(float), 2) maxima = mh.regmax(mh.stretch(imagef)) maxima, _ = mh.label(maxima) markers = erode(bin_image, 1) markers = mh.label(markers + 1)[0] labels = sk_watershed(-distance, maxima, watershed_line=1) watershed = labels * bin_image return watershed
def segment(self, img): ret, thresh = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) # Distance transform on the thresholded image # 2 possible distances (L1 and L2) and 2 possible masks (3,5) # Fixed L1 due to better experiment results. For L1, mask 3 and 5 have # same result (as stated in documentation) dist_transform = cv2.distanceTransform(thresh, CV_DIST, 5) # Obtain local maximas given a ms x ms mask maxima = mh.regmax(dist_transform, np.ones((self.mask_size, self.mask_size))) # Connect areas and identify seeds. Better results using full # connectivity (seeds, num_seeds) = ndi.label(maxima, structure=np.ones((3, 3))) # Uses watershed algorithm for segmentation (fills basins) # Regions with adjacent catchment basins are constructed. # Usually produces oversegmentation of the image. Works on the # gradient image membrane_watersheds = mh.gaussian_filter(img, self.sigma_ws) return mh.cwatershed(membrane_watersheds, seeds)
def get_seeds(boundary, method='grid', next_id=1, seed_distance=10, boundary_thres=0.5, label_nb=None): 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 in ['minima', 'maxima_distance']: if method == 'minima': peak = mahotas.regmin(boundary) elif method == 'maxima_distance': # distance = mahotas.distance(boundary < boundary_thres) distance = ndimage.morphology.distance_transform_cdt( boundary < boundary_thres) peak = mahotas.regmax(distance) if label_nb is None: seeds, num_seeds = mahotas.label(peak) else: seeds, num_seeds = mahotas.label(peak, label_nb) seeds[seeds > 0] += next_id return seeds, num_seeds
def _patch_ms(patch, args): histogram = np.histogram(patch,bins=256,range=(0,256))[0] # np.set_printoptions(precision=2,threshold=256) # print(histogram) thresholds = threshold.multi_kapur(histogram, 2) tee.log('Maximum entropy discretization (Kapur et al. 1985, 3 bins):', thresholds) minint = thresholds[0] if minint != thresholds[0]: tee.log('Warning: minint was lowered') if minint <= 1: tee.log('minint threshold too low (%d) - I believe there are no cells in this substack' % minint) return None if thresholds[1] < args.min_second_threshold: tee.log('thresholds[1] threshold too low (%d) - I believe there are no cells in this substack' % thresholds[1]) return None (Lx,Ly,Lz) = np.where(patch > minint) intensities = patch[(Lx,Ly,Lz)] L = np.array(zip(Lx,Ly,Lz), dtype=np.uint16) tee.log('Found', len(L), 'voxels above the threshold', minint) if len(L) < 10: tee.log('Too few points (%d) - I believe there are no cells in this substack' % len(L)) return None bandwidth = args.mean_shift_bandwidth radius = args.hi_local_max_radius reg_maxima = mh.regmax(patch.astype(np.int)) if args.seeds_filtering_mode == 'hard': xx, yy, zz = np.mgrid[:2*radius+1, :2*radius+1, :2*radius+1] sphere = (xx - radius) ** 2 + (yy - radius) ** 2 + (zz - radius) ** 2 se = sphere <= radius*radius f = se.astype(np.float64) elif args.seeds_filtering_mode == 'soft': f=np.zeros((int(radius+1)*2+1,int(radius+1)*2+1,int(radius+1)*2+1), dtype=np.float64);f[int(radius+1),int(radius+1),int(radius+1)]=1 f=gaussian_filter(f, radius/2.,mode='constant', cval=0.0);f=f/np.amax(f) else: raise ValueError("Invalid seeds filtering mode", args.seeds_filtering_mode) min_mass = np.sum(f)*minint local_mass = mh.convolve(patch, weights=f, mode='constant', cval=0.0) above = local_mass > min_mass himaxima = np.logical_and(reg_maxima,above) if np.sum(himaxima) > args.max_expected_cells: tee.log('Too many candidates,', np.sum(himaxima), 'I believe this substack is messy and give up') return None C = [volume.Center(x,y,z) for (x,y,z) in zip(*np.where(himaxima))] if len(C) == 0: tee.log('No maxima above. #himaxima=', np.sum(himaxima), '#above=', np.sum(above), '. Giving up') return None seeds = np.array([[c.x, c.y, c.z] for c in C]) # Save seeds with some info for debugging purposes for c in C: c.name = 'seed' c.mass = patch[c.x,c.y,c.z] c.volume = thresholds[0] cluster_centers, labels, volumes, masses, trajectories = mean_shift(L, intensities=intensities, bandwidth=bandwidth, seeds=seeds) if cluster_centers is None: return None masses = np.zeros(len(cluster_centers)) for i,c in enumerate(cluster_centers): masses[i] = local_mass[int(c[0]+0.5),int(c[1]+0.5),int(c[2]+0.5)] PatchMSRet = namedtuple('PatchMSRet', ['cluster_centers','labels','masses','L','seeds']) r = PatchMSRet(cluster_centers=cluster_centers, labels=labels, masses=masses, L=L, seeds=C) return r
def run(self, workspace): x_name = self.x_name.value y_name = self.y_name.value images = workspace.image_set x = images.get_image(x_name) dimensions = x.dimensions x_data = x.pixel_data if self.operation.value == "Distance": original_shape = x_data.shape if x.volumetric: x_data = skimage.transform.resize(x_data, (original_shape[0], 256, 256), order=0, mode="edge") distance = scipy.ndimage.distance_transform_edt(x_data) distance = mahotas.stretch(distance) surface = distance.max() - distance if x.volumetric: footprint = numpy.ones((self.connectivity.value, self.connectivity.value, self.connectivity.value)) else: footprint = numpy.ones((self.connectivity.value, self.connectivity.value)) peaks = mahotas.regmax(distance, footprint) if x.volumetric: markers, _ = mahotas.label(peaks, numpy.ones((16, 16, 16))) else: markers, _ = mahotas.label(peaks, numpy.ones((16, 16))) y_data = mahotas.cwatershed(surface, markers) y_data = y_data * x_data if x.volumetric: y_data = skimage.transform.resize(y_data, original_shape, order=0, mode="edge") else: markers_name = self.markers_name.value markers = images.get_image(markers_name) data = x_data markers_data = markers.pixel_data mask_data = None if not self.mask_name.is_blank: mask_name = self.mask_name.value mask = images.get_image(mask_name) mask_data = mask.pixel_data y_data = skimage.morphology.watershed( image=data, markers=markers_data, mask=mask_data ) y_data = skimage.measure.label(y_data) objects = cellprofiler.object.Objects() objects.segmented = y_data objects.parent_image = x workspace.object_set.add_objects(objects, y_name) self.add_measurements(workspace.measurements, y_data) if self.show_window: workspace.display_data.x_data = x.pixel_data workspace.display_data.y_data = y_data workspace.display_data.dimensions = dimensions
import numpy as np import pylab # Dio od matplotlib. import mahotas as mh import cv2 image = cv2.imread('pictures/sky.png', 0) # Ucitavamo sliku u grayscale prikazu. filtered = mh.gaussian_filter( image, 10) # Koristimo gauss filter za izostravanje slike. result = filtered.astype( 'uint8' ) # Funckija mh.gaussian_filter() postavlja vrijednost varijable u float64. rmax = mh.regmax(result) # Trazi maksimalne vrijednosti. print rmax pylab.imshow(mh.overlay(image, rmax)) pylab.show() labeled, nr_objects = mh.label(rmax) # mh.overlay() funckija postavlja img kao pozadinu a preko nje postavlja vrijednosti variable rmax u crvenom kanalu. print('Broj pronadenih objekata je {}.'.format(nr_objects)) pylab.imshow(labeled) # pylab.gray() pylab.show() dist = mh.distance(result) dist = dist.max() - dist dist -= dist.min() dist = dist / float(dist.ptp()) * 255
# continue # obtains image data DAPI = skimage.io.imread(filenamesDAPI[imageNumber]) SE = skimage.io.imread(filenamesSE[imageNumber]) # applys gaussina filter DAPIf = mh.gaussian_filter(DAPI, 13) SEf = mh.gaussian_filter(SE, 3) # finds threshold T = mh.thresholding.otsu(np.uint16(SEf)) SEt= SEf > T/2 # Finds seeds on the nuclear image rmax = mh.regmax(DAPIf) pylab.imshow(rmax) rmax[np.logical_not(SEt)] = 0 # Watershed on the cytoplasm image seeds,nr_nuclei = mh.label(rmax) # nuclei count imagew = mh.cwatershed(-SEf, seeds) # Remove areas that aren't nuclei SEn=np.logical_not(SEt) imagew[SEn] = 0 #pylab.imshow(imagew.astype(np.int16)) # convert datatype from int64 to int16 to display labelled value in [] #prepare names for cropped cells filenamesDAPI[idx]= filenamesDAPI[idx][14:38] filenames=range(nr_nuclei)
bin_image = dnaf > T_mean plt.imshow(bin_image) labeled, nr_objects = mh.label(bin_image) print(nr_objects) plt.imshow(labeled) plt.jet() @interact(sigma=(1.,16.)) def check_sigma(sigma): dnaf = mh.gaussian_filter(dna.astype(float), sigma) maxima = mh.regmax(mh.stretch(dnaf)) maxima = mh.dilate(maxima, np.ones((5,5))) plt.imshow(mh.as_rgb(np.maximum(255*maxima, dnaf), dnaf, dna > T_mean)) sigma = 12.0 dnaf = mh.gaussian_filter(dna.astype(float),sigma) maxima = mh.regmax(mh.stretch(dnaf)) maxima,_= mh.label(maxima) plt.imshow(maxima) dist = mh.distance(bin_image) plt.imshow(dist) dist = 255 - mh.stretch(dist) watershed = mh.cwatershed(dist,maxima) plt.imshow(watershed) watershed *= bin_image plt.imshow(watershed) watershed = mh.labeled.remove_bordering(watershed) plt.imshow(watershed) sizes = mh.labeled.labeled_size(watershed) # The conversion below is not necessary in newer versions of mahotas: watershed = watershed.astype(np.intc) @interact(min_size=(100,4000,20)) def do_plot(min_size):
def run(self, workspace): x_name = self.x_name.value y_name = self.y_name.value images = workspace.image_set x = images.get_image(x_name) dimensions = x.dimensions x_data = x.pixel_data if self.operation.value == O_DISTANCE: original_shape = x_data.shape factor = self.downsample.value if factor > 1: if x.volumetric: factors = (1, factor, factor) else: factors = (factor, factor) x_data = skimage.transform.downscale_local_mean( x_data, factors ) threshold = skimage.filters.threshold_otsu(x_data) x_data = x_data > threshold distance = scipy.ndimage.distance_transform_edt(x_data) distance = mahotas.stretch(distance) surface = distance.max() - distance if x.volumetric: footprint = numpy.ones( ( self.footprint.value, self.footprint.value, self.footprint.value ) ) else: footprint = numpy.ones( ( self.footprint.value, self.footprint.value ) ) peaks = mahotas.regmax(distance, footprint) if x.volumetric: markers, _ = mahotas.label(peaks, numpy.ones((16, 16, 16))) else: markers, _ = mahotas.label(peaks, numpy.ones((16, 16))) y_data = mahotas.cwatershed(surface, markers) y_data = y_data * x_data if factor > 1: y_data = skimage.transform.resize( y_data, original_shape, mode="edge", order=0, preserve_range=True ) y_data = numpy.rint(y_data).astype(numpy.uint16) else: markers_name = self.markers_name.value markers = images.get_image(markers_name) markers_data = markers.pixel_data if x.multichannel: x_data = skimage.color.rgb2gray(x_data) if markers.multichannel: markers_data = skimage.color.rgb2gray(markers_data) mask_data = None if not self.mask_name.is_blank: mask_name = self.mask_name.value mask = images.get_image(mask_name) mask_data = mask.pixel_data y_data = skimage.morphology.watershed( image=x_data, markers=markers_data, mask=mask_data, connectivity=self.connectivity.value, compactness=self.compactness.value, watershed_line=self.watershed_line.value ) y_data = skimage.measure.label(y_data) objects = cellprofiler.object.Objects() objects.segmented = y_data objects.parent_image = x workspace.object_set.add_objects(objects, y_name) self.add_measurements(workspace) if self.show_window: workspace.display_data.x_data = x.pixel_data workspace.display_data.y_data = y_data workspace.display_data.dimensions = dimensions
def run(self, workspace): x_name = self.x_name.value y_name = self.y_name.value images = workspace.image_set x = images.get_image(x_name) dimensions = x.dimensions x_data = x.pixel_data if self.operation.value == "Distance": original_shape = x_data.shape factor = self.downsample.value if factor > 1: if x.volumetric: factors = (1, factor, factor) else: factors = (factor, factor) x_data = skimage.transform.downscale_local_mean( x_data, factors) threshold = skimage.filters.threshold_otsu(x_data) x_data = x_data > threshold distance = scipy.ndimage.distance_transform_edt(x_data) distance = mahotas.stretch(distance) surface = distance.max() - distance if x.volumetric: footprint = numpy.ones( (self.connectivity.value, self.connectivity.value, self.connectivity.value)) else: footprint = numpy.ones( (self.connectivity.value, self.connectivity.value)) peaks = mahotas.regmax(distance, footprint) if x.volumetric: markers, _ = mahotas.label(peaks, numpy.ones((16, 16, 16))) else: markers, _ = mahotas.label(peaks, numpy.ones((16, 16))) y_data = mahotas.cwatershed(surface, markers) y_data = y_data * x_data if factor > 1: y_data = skimage.transform.resize(y_data, original_shape, mode="edge", order=0, preserve_range=True) y_data = numpy.rint(y_data).astype(numpy.uint16) else: markers_name = self.markers_name.value markers = images.get_image(markers_name) markers_data = markers.pixel_data if x.multichannel: x_data = skimage.color.rgb2gray(x_data) if markers.multichannel: markers_data = skimage.color.rgb2gray(markers_data) mask_data = None if not self.mask_name.is_blank: mask_name = self.mask_name.value mask = images.get_image(mask_name) mask_data = mask.pixel_data y_data = skimage.morphology.watershed(image=x_data, markers=markers_data, mask=mask_data) y_data = skimage.measure.label(y_data) objects = cellprofiler.object.Objects() objects.segmented = y_data objects.parent_image = x workspace.object_set.add_objects(objects, y_name) self.add_measurements(workspace) if self.show_window: workspace.display_data.x_data = x.pixel_data workspace.display_data.y_data = y_data workspace.display_data.dimensions = dimensions
def watershed_clustering(f, thresh, dradius=3, ctype=4, marker_field='dist', filter_method='curve', numberOfIterations=5, cluster_masking=True, exclude_border=False, marker_method='mahotas_regmax', siggauss=1., marker_shrinkage_Niter=3, marker_shrinkage_dmin=0.1, **kwargs): ''' Applies watershed clustering to a field. Parameters ---------- f : np.array field to be segmented thresh : float threshold for masking, set foreground to f > thresh dradius : int, optional minimal distance for neighboring maxima ctype: {4, 8}, optional set either 4- or 8-connectivity (edge vs. edges+corners) marker_field : str, optional switch if input field `f` or a distance transform as used to set the watershed markers if 'dist', then max. in Euclidean distance to background is used to set initial markers, else the max. in field f are taken filter_method : {'gauss', 'curve'}, optional filter method used to smooth the input field * 'gauss' for 2d-Gaussian * 'curve' for curvature flow filter numberOfIterations : int, optional number of repeated application of curvature flow filter the larger then smoother if selected cluster_masking : {True, False}, optional if original (True) or smoothed (False) threshold mask is used. exclude_border : {True, False}, optional if clusters that touch domain borders are excluded (set to zero) marker_method : str, optional defines a method for marker assignment * 'brute_force_local_max' : just uses scipy.ndimage.maximum_filter * 'skimage_peak_local_max' : uses skimage local maximum routine * 'mahotas_regmax' : uses mahotas regional maximum detection * 'iterative_shrinking' : uses iterative object shrinking depending on relative distance-to-background siggauss : float, optional sigma for Gaussian filter if selected marker_shrinkage_Niter : int, optional option for marker creation, how often shrinking is applied marker_shrinkage_dmin : float, optional option for marker creation How much of the edge is taken away. Distance is measured relative to the maximum distance, thus 0 < dmin < 1. Returns ------- c : np.array categorial cluster field ''' # apply filtering ------------------------------------------------ ndim = np.ndim(f) if filter_method == 'curve': f_sm = gi.curve_flow_filter(f, numberOfIterations=numberOfIterations) elif filter_method == 'gauss': f_sm = scipy.ndimage.gaussian_filter(f, siggauss) # ================================================================ # do masking ----------------------------------------------------- ma = f > thresh ma_sm = f_sm > thresh # ================================================================ # apply distance transform --------------------------------------- if marker_field == 'dist': mfield = scipy.ndimage.distance_transform_edt(ma_sm) else: mfield = np.where(f_sm < thresh, 0, f_sm - thresh) # ================================================================ # find local maximaand set markers ------------------------------- if type(marker_field) == type(np.array([])): markers = marker_field print('...take predefined marker field') elif marker_method == 'brute_force_local_max': mfield_max = scipy.ndimage.maximum_filter(mfield, 2 * dradius + 1) local_maxi = (mfield_max == mfield) & ma_sm markers, nclust = scipy.ndimage.label(local_maxi) elif marker_method == 'skimage_peak_local_max': local_maxi = skimage.feature.peak_local_max( mfield, indices=False, exclude_border=exclude_border, min_distance=dradius) markers, nclust = scipy.ndimage.label(local_maxi) elif marker_method == 'mahotas_regmax': local_maxi = mh.regmax(mfield, Bc=2 * dradius + 1) markers, nclust = scipy.ndimage.label(local_maxi) elif marker_method == 'iterative_shrinking': # all segmentation / filter keywords are needed for marker determination marker_kwargs = kwargs.copy() marker_kwargs['ctype'] = ctype marker_kwargs['filter_method'] = filter_method marker_kwargs['numberOfIterations'] = numberOfIterations marker_kwargs['cluster_masking'] = cluster_masking marker_kwargs['siggauss'] = siggauss markers = markers_from_iterative_shrinking( ma_sm, marker_shrinkage_Niter=marker_shrinkage_Niter, marker_shrinkage_dmin=marker_shrinkage_dmin, **marker_kwargs) # ================================================================ # watersheding ---------------------------------------------------- connect = set_connectivity_footprint(ctype, ndim) c = skimage.morphology.watershed(-mfield, markers, mask=ma_sm, connectivity=connect) # ================================================================ # use original mask ---------------------------------------------- if cluster_masking: c = np.where(ma, c, 0) # ================================================================ return c
def test_run_distance_declump_intensity( image, module, image_set, workspace, connectivity, compactness, watershed_line ): module.use_advanced.value = True module.operation.value = "Distance" module.x_name.value = "binary" module.y_name.value = "watershed" module.connectivity.value = connectivity 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.declump_method.value = "Intensity" module.reference_name.value = "gradient" module.gaussian_sigma.value = 1 # must pass pixel data into image set for intensity declumping gradient = image.pixel_data image_set.add( "gradient", cellprofiler_core.image.Image( image=gradient, convert=False, dimensions=image.dimensions ), ) # set the structuring element, used for declumping if image.dimensions == 3: module.structuring_element.value = "Ball,1" selem = skimage.morphology.ball(1) else: module.structuring_element.value = "Disk,1" selem = skimage.morphology.disk(1) # run the module module.run(workspace) # distance-based watershed 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))) watershed_distance = mahotas.cwatershed(surface, markers) watershed_distance = watershed_distance * binary # intensity-based declumping peak_image = scipy.ndimage.distance_transform_edt(watershed_distance > 0) # Set the image as a float and rescale to full bit depth watershed_image = skimage.img_as_float(gradient, force_copy=True) watershed_image -= watershed_image.min() watershed_image = 1 - watershed_image if image.multichannel: watershed_image = skimage.color.rgb2gray(watershed_image) watershed_image = skimage.filters.gaussian(watershed_image, sigma=module.gaussian_sigma.value) seed_coords = skimage.feature.peak_local_max(peak_image, min_distance=module.min_dist.value, threshold_rel=module.min_intensity.value, exclude_border=module.exclude_border.value, num_peaks=module.max_seeds.value if module.max_seeds.value != -1 else numpy.inf) seeds = numpy.zeros_like(peak_image, dtype=bool) seeds[tuple(seed_coords.T)] = True seeds = skimage.morphology.binary_dilation(seeds, selem) number_objects = skimage.measure.label(watershed_distance, return_num=True)[1] seeds_dtype = (numpy.uint16 if number_objects < numpy.iinfo(numpy.uint16).max else numpy.uint32) seeds = scipy.ndimage.label(seeds)[0] markers = numpy.zeros_like(seeds, dtype=seeds_dtype) markers[seeds > 0] = -seeds[seeds > 0] expected = skimage.segmentation.watershed( connectivity=connectivity, image=watershed_image, markers=markers, mask=binary !=0 ) zeros = numpy.where(expected==0) expected += numpy.abs(numpy.min(expected)) + 1 expected[zeros] = 0 expected = skimage.measure.label(expected) actual = workspace.get_objects("watershed") numpy.testing.assert_array_equal(expected, actual.segmented)
# Luis Pedro Coelho Mahotas: Open source software for scriptable computer vision in Journal of Open Research Software, vol 1, 2013. [DOI] # mahotas.citation() #### MAIN #### # Laden der Bilder dna = mh.imread("dna.jpeg") # dna = mh.imread("nicolic_1.tif") nuc = mh.demos.nuclear_image() # Gaussfiltern und Tresholding dnaf = mh.gaussian_filter(dna, 16) # mahotas.thresholding() braucht "uint8" dnaf = dnaf.astype("uint8") T = mh.thresholding.otsu(dnaf) # Zählen der Objekte, Ausgabe in int und Plottbaren Array mit nummerierten Flecken labeled, nr_objects = mh.label(dnaf > T) print nr_objects, labeled.shape, labeled.max() # Seeds finden rmax=mh.regmax(dnaf) # pylab.imshow(rmax) pylab.imshow(mh.overlay(dna, rmax)) # pylab.imshow(labeled) # pylab.imshow(dnaf > T) # pylab.imshow(nuc) pylab.jet() pylab.show()
def watershedSegment(image, diskSize=20): """This routine implements the watershed example from http://www.mathworks.com/help/images/examples/marker-controlled-watershed-segmentation.html, but using pymorph and mahotas. :param image: an image (2d numpy array) to be segemented :param diskSize: an integer used as a size for a structuring element used for morphological preprocessing. :returns: tuple of binarized and labeled segmention masks """ def gradientMagnitudue(image): sobel_x = nd.sobel(image.astype('double'), 0) sobel_y = nd.sobel(image.astype('double'), 1) return np.sqrt((sobel_x * sobel_x) + (sobel_y * sobel_y)) def imimposemin(image, mask, connectivity): fm = image.copy() fm[mask] = -9223372036854775800 fm[np.logical_not(mask)] = 9223372036854775800 fp1 = image + 1 g = np.minimum(fp1, fm) j = infrec(fm, g) return j def infrec(f, g, Bc=None): if Bc is None: Bc = pymorph.secross() n = f.size return fast_conditional_dilate(f, g, Bc, n) def fast_conditional_dilate(f, g, Bc=None, n=1): if Bc is None: Bc = pymorph.secross() f = pymorph.intersec(f, g) for i in xrange(n): prev = f f = pymorph.intersec(mahotas.dilate(f, Bc), g) if pymorph.isequal(f, prev): break return f 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_dist_wshed_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) segmented_cells -= 1 # seperate watershed regions segmented_cells[gradientMagnitudue(segmented_cells) > 0] = 0 return segmented_cells > 0, segmented_cells
dnaf = mh.gaussian_filter(dna, 8) dnat = dnaf > T pylab.gray() nuclei1 = dnat pylab.imshow(dnat) pylab.show() #labelling thereshold image labeled, nr_objects = mh.label(dnat) print nr_objects # output number of objects pylab.imshow(labeled) pylab.jet() # makes image colourful pylab.show() dnaf = mh.gaussian_filter(dnaf, 8) rmax = mh.regmax(dnaf) pylab.imshow(mh.overlay( dna, rmax)) # print dna and rmax (with second channel in red) pylab.show() # seeds only show when image is zoomed in dnaf = mh.gaussian_filter(dnaf, 16) # apply different filter to yield better result rmax = mh.regmax(dnaf) pylab.imshow(mh.overlay(dna, rmax)) pylab.show() seeds, nr_nuclei = mh.label(rmax) # nuclei count print nr_nuclei # unlike the example, the result is 36 compared to 22 dist = mh.distance(dnat) dist = dist.max() - dist
def check_sigma(sigma): dnaf = mh.gaussian_filter(dna.astype(float), sigma) maxima = mh.regmax(mh.stretch(dnaf)) maxima = mh.dilate(maxima, np.ones((5,5))) plt.imshow(mh.as_rgb(np.maximum(255*maxima, dnaf), dnaf, dna > T_mean))
def process_image(im, d, test=False, remove_bordering=False): plt.figure(1, frameon=False) sigma = 75 blurred = mh.gaussian_filter(im.astype(float), sigma) T_mean = blurred.mean() bin_image = im > T_mean maxima = mh.regmax(mh.stretch(blurred)) maxima, _ = mh.label(maxima) dist = mh.distance(bin_image) dist = 255 - mh.stretch(dist) watershed = mh.cwatershed(dist, maxima) _, old_nr_objects = mh.labeled.relabel(watershed) sizes = mh.labeled.labeled_size(watershed) min_size = 100000 filtered = mh.labeled.remove_regions_where( watershed * bin_image, sizes < min_size) _, nr_objects = mh.labeled.relabel(filtered) print('Removed', old_nr_objects - nr_objects, 'small regions') old_nr_objects = nr_objects if (remove_bordering): filtered = mh.labeled.remove_bordering(filtered) labeled, nr_objects = mh.labeled.relabel(filtered) print('Removed', old_nr_objects - nr_objects, 'bordering cells') print("Number of cells: {}".format(nr_objects)) fin_weights = mh.labeled_sum(im.astype(np.uint32), labeled) fin_sizes = mh.labeled.labeled_size(labeled) fin_result = fin_weights / fin_sizes if (test): f, axarr = plt.subplots(2, 2) for i in range(2): for j in range(2): axarr[i][j].axis('off') axarr[0, 0].imshow(im) axarr[0, 0].set_title('Source') axarr[0, 1].imshow(labeled) axarr[0, 1].set_title('Labeled') axarr[1, 0].imshow(watershed) axarr[1, 0].set_title('Watershed') axarr[1, 1].imshow(blurred) axarr[1, 1].set_title('Blurred') for i in range(1, nr_objects + 1): print("Cell {} average luminescence is {}".format( i, fin_result[i])) bbox = mh.bbox((labeled == i)) plt.text((bbox[2] + bbox[3]) / 2, (bbox[0] + bbox[1] ) / 2, str(i), fontsize=20, color='black') # plt.show() plt.savefig("test" + str(nr_objects) + ".svg", format='svg', bbox_inches='tight', dpi=1200) else: for i in range(1, nr_objects + 1): bbox = mh.bbox((labeled == i)) cell = (im * (labeled == i))[bbox[0]:bbox[1], bbox[2]:bbox[3]] hashed = hashlib.sha1(im).hexdigest() imsave(d + data_dir + hashed + '-' + str(i) + '.png', imresize(cell, (img_rows, img_cols)))
def watershedSegment(image, diskSize=20): def gradientMagnitudue(image): sobel_x = nd.sobel(image.astype('double'), 0) sobel_y = nd.sobel(image.astype('double'), 1) return np.sqrt((sobel_x * sobel_x) + (sobel_y * sobel_y)) def imimposemin(image, mask, connectivity): fm = image.copy() fm[mask] = -9223372036854775800 fm[np.logical_not(mask)] = 9223372036854775800 fp1 = image + 1 g = np.minimum(fp1, fm) j = infrec(fm, g) return j def infrec(f, g, Bc=None): if Bc is None: Bc = pymorph.secross() n = f.size return fast_conditional_dilate(f, g, Bc, n); def fast_conditional_dilate(f, g, Bc=None, n=1): if Bc is None: Bc = pymorph.secross() f = pymorph.intersec(f,g) for i in xrange(n): prev = f f = pymorph.intersec(mahotas.dilate(f, Bc), g) if pymorph.isequal(f, prev): break return f 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_dist_wshed_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) segmented_cells -= 1 # seperate watershed regions segmented_cells[gradientMagnitudue(segmented_cells) > 0] = 0 return segmented_cells > 0, segmented_cells
import numpy as np import pylab # Dio od matplotlib. import mahotas as mh import cv2 image = cv2.imread('pictures/sky.png', 0) # Ucitavamo sliku u grayscale prikazu. filtered = mh.gaussian_filter(image, 10) # Koristimo gauss filter za izostravanje slike. result = filtered.astype('uint8') # Funckija mh.gaussian_filter() postavlja vrijednost varijable u float64. rmax = mh.regmax(result) # Trazi maksimalne vrijednosti. print rmax pylab.imshow(mh.overlay(image, rmax)) pylab.show() labeled, nr_objects = mh.label(rmax) # mh.overlay() funckija postavlja img kao pozadinu a preko nje postavlja vrijednosti variable rmax u crvenom kanalu. print ('Broj pronadenih objekata je {}.'.format(nr_objects)) pylab.imshow(labeled) # pylab.gray() pylab.show() dist = mh.distance(result) dist = dist.max() - dist dist -= dist.min() dist = dist/float(dist.ptp()) * 255 dist = dist.astype(np.uint8) objects = mh.cwatershed(dist, labeled) whole = mh.segmentation.gvoronoi(objects) # Voronoi segemtacija, svaki piksel poprima vrijednost najblizeg maksimuma. pylab.imshow(objects)
def _patch_ms(patch, args): histogram = np.histogram(patch,bins=256,range=(0,256))[0] # np.set_printoptions(precision=2,threshold=256) # print(histogram) thresholds = threshold.multi_kapur(histogram, 2) tee.log('Maximum entropy discretization (Kapur et al. 1985, 3 bins):', thresholds) minint = thresholds[0] if minint != thresholds[0]: tee.log('Warning: minint was lowered') if minint <= 1: tee.log('minint threshold too low (%d) - I believe there are no cells in this substack' % minint) return None if thresholds[1] < args.min_second_threshold: tee.log('thresholds[1] threshold too low (%d) - I believe there are no cells in this substack' % thresholds[1]) return None (Lx,Ly,Lz) = np.where(patch > minint) intensities = patch[(Lx,Ly,Lz)] L = np.array(list(zip(Lx,Ly,Lz)), dtype=np.uint16) tee.log('Found', len(L), 'voxels above the threshold', minint) if len(L) < 10: tee.log('Too few points (%d) - I believe there are no cells in this substack' % len(L)) return None bandwidth = args.mean_shift_bandwidth radius = args.hi_local_max_radius reg_maxima = mh.regmax(patch.astype(np.int)) if args.seeds_filtering_mode == 'hard': xx, yy, zz = np.mgrid[:2*radius+1, :2*radius+1, :2*radius+1] sphere = (xx - radius) ** 2 + (yy - radius) ** 2 + (zz - radius) ** 2 se = sphere <= radius*radius f = se.astype(np.float64) elif args.seeds_filtering_mode == 'soft': f=np.zeros((int(radius+1)*2+1,int(radius+1)*2+1,int(radius+1)*2+1), dtype=np.float64);f[int(radius+1),int(radius+1),int(radius+1)]=1 f=gaussian_filter(f, radius/2.,mode='constant', cval=0.0);f=f/np.amax(f) else: raise ValueError("Invalid seeds filtering mode", args.seeds_filtering_mode) min_mass = np.sum(f)*minint local_mass = mh.convolve(patch, weights=f, mode='constant', cval=0.0) above = local_mass > min_mass himaxima = np.logical_and(reg_maxima,above) if np.sum(himaxima) > args.max_expected_cells: tee.log('Too many candidates,', np.sum(himaxima), 'I believe this substack is messy and give up') return None C = [volume.Center(x,y,z) for (x,y,z) in zip(*np.where(himaxima))] if len(C) == 0: tee.log('No maxima above. #himaxima=', np.sum(himaxima), '#above=', np.sum(above), '. Giving up') return None seeds = np.array([[c.x, c.y, c.z] for c in C]) # Save seeds with some info for debugging purposes for c in C: c.name = 'seed' c.mass = patch[c.x,c.y,c.z] c.volume = thresholds[0] cluster_centers, labels, volumes, masses, trajectories = mean_shift(L, intensities=intensities, bandwidth=bandwidth, seeds=seeds) if cluster_centers is None: return None masses = np.zeros(len(cluster_centers)) for i,c in enumerate(cluster_centers): masses[i] = local_mass[int(c[0]+0.5),int(c[1]+0.5),int(c[2]+0.5)] PatchMSRet = namedtuple('PatchMSRet', ['cluster_centers','labels','masses','L','seeds']) r = PatchMSRet(cluster_centers=cluster_centers, labels=labels, masses=masses, L=L, seeds=C) return r