def NumpyDetectEdge(fname, color_filter=(1, 1, 1), radius=510, center=(582, 791), show=False): plate_circle = GetCircle(center, radius) im = misc.imread(fname) im_gray = np.dot(im, color_filter) / sum(color_filter) imf = ndimage.gaussian_filter(im_gray, sigma=2) imf = 256 - imf # invert color imc = np.zeros(imf.shape, dtype=np.int32) imc[plate_circle] = imf[plate_circle] imc = imc[center[0]-radius:center[0]+radius, center[1]-radius:center[1]+radius] T = 100 imc[np.where(imc < T)] = 0 rmax = pymorph.regmax(imc) seeds, n_colonies = ndimage.label(rmax) # gives a unique integer number to each region and fills it with that number count = 0 for i in xrange(n_colonies): seed = np.where(seeds==i) l = len(seed[0]) # filter seeds which are touching the perimeter (or 5 pixel away from it) perimeter = False for j in xrange(l): if np.sqrt((radius-seed[0][j])**2 + (radius-seed[1][j])**2) > radius-5: perimeter = True if perimeter: continue seedx = [(x + center[0] - radius) for x in seed[0]] seedy = [(y + center[1] - radius) for y in seed[1]] meanx = np.mean(seedx) meany = np.mean(seedy) colony_circle = GetCircle((meanx, meany), 3) colony_color = np.min(imf[colony_circle]) if colony_color >= 110: count += 1 if colony_color < 100: im[meanx, meany, :] = (255, 0, 0) # red elif 100 < colony_color < 110: im[meanx, meany, :] = (255, 255, 0) # yellow elif 110 < colony_color < 120: im[meanx, meany, :] = (0, 255, 0) # green elif 120 < colony_color < 130: im[meanx, meany, :] = (0, 255, 255) # cyan elif 130 < colony_color < 140: im[meanx, meany, :] = (0, 0, 255) # blue elif 140 < colony_color < 150: im[meanx, meany, :] = (255, 0, 255) # magenta elif 150 < colony_color: im[meanx, meany, :] = (255, 255, 255) # white if show: plt.imshow(im) plt.show() return count
def segment(img, T): binimg = (img > T) binimg = ndimage.median_filter(binimg, size=5) dist = mahotas.distance(binimg) dist = dist.astype(np.int32) maxima = pymorph.regmax(dist) maxima,_ = ndimage.label(maxima) return mahotas.cwatershed(dist.max() - dist, maxima)
def labelimage(self, threshold=None): """Label regions in image corresponding to regional maxima""" if threshold is None: threshold = self.threshold self.seeds = pymorph.regmax(self.filtered) * threshold self.labels, self.nlabels = ndimage.label(self.seeds, structure=numpy.ones((3,3)))
def pymorph_objects(flnm, sigma): raw_img = misc.imread('data/circles.png') img = ndimage.gaussian_filter(raw_img, sigma) thres = img > img.mean() #find objects peaks = pymorph.regmax(img) found, n_found = ndimage.label(peaks) com = ndimage.measurements.center_of_mass(peaks, found, xrange(1, n_found+1)) coords = com_text(com, n_found) return '%d objects were found in %s.\nTheir centers of mass are located at \n %s' %(n_found, basename(flnm), coords)
def sobel_segment(img): vsobel = np.array([ [1,2,1], [0,0,0], [-1,-2,-1]]) sobel = ndimage.convolve(img.astype(float),vsobel)**2 hsobel = vsobel.T sobel += ndimage.convolve(img.astype(float), hsobel)**2 imgf = ndimage.gaussian_filter(img,2) maxima,nmaxima = ndimage.label(pymorph.regmax(imgf)) overseg = mahotas.cwatershed(sobel.astype(np.uint32), maxima) return overseg
def count_nuclei(filename): full = filename #nome immagine da analizzare empty = '/home/luca/isac/black-cut.bmp' #immagine vuota di riferimento img = '/home/luca/isac/tmp/'+filename+'.jpg' #nome del file da creare con imagemagick imagemagick= "compare -metric AE -fuzz 8% " +empty+" "+full+" "+ " -highlight-color White -lowlight-color Black " + img #good values 5-6-7-8% os.system(imagemagick) #esegue il comando di imagemagick creando il file ccnx.jpg per l'immagine corrente ccn = mahotas.imread(img) #carica l'immagine creata con imagemagick ccnf = ndimage.gaussian_filter(ccn, 10) #applica un filtro gaussiano con SD=10 all'immagine rmax = pymorph.regmax(ccnf) #trova i massimi locali nell'immagine seeds,nr_nuclei=ndimage.label(rmax) #conta i massimi locali dell'immagine filtrata return nr_nuclei
def GradBasedSegmentation(im): blur = nd.gaussian_filter(im, 16) rmax = pymorph.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=nd.binary_opening(bImg01,iterations=3) b = pymorph.edgeoff(bImg) d = distanceTranform(b) seeds, nr_nuclei = nd.label(rmax) lab = mahotas.cwatershed(d, seeds) return lab
def GradBasedSegmentation(im): blur=nd.gaussian_filter(im, 16) rmax = pymorph.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=nd.binary_opening(bImg01,iterations=3) b=pymorph.edgeoff(bImg) d=distanceTranform(b) seeds,nr_nuclei = nd.label(rmax) lab=mahotas.cwatershed(d,seeds) return lab
def colorscheme(url): im=image_read(url) pylab.imshow(im) dnaf = ndimage.gaussian_filter(im, 1) rmax = pymorph.regmax(dnaf) seeds,nr_nuclei = ndimage.label(rmax) T = mahotas.thresholding.otsu(dnaf) dist = ndimage.distance_transform_edt(dnaf > T) dist = dist.max() - dist dist -= dist.min() dist = dist/float(dist.ptp()) * 255 dist = dist.astype(np.uint8) nuclei = pymorph.cwatershed(dist, seeds) whole = mahotas.segmentation.gvoronoi(nuclei) im0=pylab.imshow(whole) pylab.show()
def maxima(img): """ Return image local maxima """ import pymorph from image import Transf # Image has to be 'int' [0:255] to use in 'pymorph' img = Transf.float2uint(img) # Search for image maxima maxs = pymorph.regmax(img) # A closing step is used "clue" near maxima elem_strct = ndi.generate_binary_structure(2,2) maxs = ndi.binary_closing(maxs,elem_strct) return maxs
def watershed(img): # Diminui ruidos imgf = ndimage.gaussian_filter(img, 16) mahotas.imsave("dnaf.jpeg", imgf) rmax = pymorph.regmax(imgf) T = mahotas.thresholding.otsu(imgf) dist = ndimage.distance_transform_edt(imgf > T) dist = dist.max() - dist dist -= dist.min() dist = dist / float(dist.ptp()) * 255 dist = dist.astype(np.uint8) mahotas.imsave("dist.jpeg", dist) seeds, nr_nuclei = ndimage.label(rmax) nuclei = pymorph.cwatershed(dist, seeds) mahotas.imsave("watershed.jpeg", nuclei)
def start(self): """Segment frame. The returned value is a labeled uint16 image. """ # Preprocessing: subtract minimum pixel value. I = self._image - self._image.min() # 'Bandpass' filtering. I_s = ndimage.filters.gaussian_filter(I, self._sigma_s) # Foreground. I_b = ndimage.filters.gaussian_filter(I, self._sigma_b) # Background. I_bp = I_s - self._alpha * I_b # Thresholding: create binary image. I_bin = (I_bp > self._tau) # Hole filling. I_bin = ndimage.binary_fill_holes(I_bin > 0) I_cells = ndimage.label(I_bin)[0] # Avoid merging nearby cells using watershed. if self._watershed: # Distance transfrom on which to apply the watershed algorithm. I_dist = ndimage.distance_transform_edt(I_bin) I_dist = I_dist/float(I_dist.max()) * 255 I_dist = I_dist.astype(np.uint8) # Find markers for the watershed algorithm. # Reduce false positive using Gaussian smoothing. I_mask = ndimage.filters.gaussian_filter(I_dist, 8)*I_bin rmax = pymorph.regmax(I_mask) I_markers, num_markers = ndimage.label(rmax) I_dist = I_dist.max() - I_dist # Cells are now the basins. I_cells = pymorph.cwatershed(I_dist, I_markers) # Remove cells with area less than threshold. if self._a_min: for label in np.unique(I_cells)[1:]: if (I_cells == label).sum() < self._a_min: I_cells[I_cells == label] = 0 # Remove cells with summed intensity less than threshold. if self._s_min: for label in np.nditer(np.unique(I_cells)[1:]): if I_bp[I_cells == label].sum() < self._s_min: I_cells[I_cells == label] = 0 return I_cells.astype('uint16') # This data type is used by ISBI.
def watershed_segment(img, mode='direct', thresholding=None, min_obj_size=None, **kwargs): ''' segment_watershed(img, mode='direct', thresholding=None, min_obj_size=None, **kwargs) Segment using traditional watershed Parameters ---------- * img: a pyslic.Image. The algorithm operates on the dna channel. * mode: 'direct' or 'gradient': whether to use the image or the gradient of the image * thresholding: how to threshold the smoothed image (default: None, no thresholding) * min_obj_size: minimum object size. This is slightly different than post-filtering for minimum object size as it fill those holes with a second watershed pass as opposed to having an image with holes * smoothing: whether to smooth (default: True) * smooth_gamma: Size of Gaussian for blurring, in pixels (default: 12) ''' assert mode in ('direct','gradient'), "segment_watershed: mode '%s' not understood" % mode with loadedimage(img): dna = img.get('dna') if kwargs.get('smoothing',True): dnaf = ndimage.gaussian_filter(dna, kwargs.get('smooth_gamma',12)) else: dnaf = dna rmax = pymorph.regmax(dnaf) rmax_L,_ = ndimage.label(rmax) if mode == 'direct': watershed_img = dna.max()-dna elif mode == 'gradient': dnag = pymorph.gradm(dna) watershed_img = dnag.max()-dnag water = mahotas.cwatershed(watershed_img,rmax_L) if thresholding is not None: T = threshold(dnaf,thresholding) water *= (dnaf >= T) if min_obj_size is not None: oid = 1 while oid <= water.max(): if (water == oid).sum() < min_obj_size: water[water == oid] =0 water[water > oid] -= 1 else: oid += 1 return water
def effect(url): im=image_read(url) pylab.imshow(im) dnaf = ndimage.gaussian_filter(im, 1) rmax = pymorph.regmax(dnaf) T = mahotas.thresholding.otsu(dnaf) seeds,nr_nuclei = ndimage.label(rmax) T = mahotas.thresholding.otsu(dnaf) T = mahotas.thresholding.otsu(dnaf) dist = ndimage.distance_transform_edt(dnaf > T) dist = dist.max() - dist dist -= dist.min() dist = dist/float(dist.ptp()) * 255 dist = dist.astype(np.uint8) nuclei = pymorph.cwatershed(dist, seeds) pylab.imshow(nuclei) # pylab.save("out.png") pylab.show()
def MNUC(datatype, maxrange, outputfile, outputfiletype): h = open(outputfile, outputfiletype) TC = 0 for i in range(0, maxrange + 1): A = datatype[i][0] rmax = pymorph.regmax(A) seeds, nr_nuclei = ndimage.label(rmax) T = mahotas.thresholding.otsu(A) C = A.copy() if T < 1: C[ C <= T ] = 0 C[ C > T ] = 1 else: C[ C < T ] = 0 C[ C >= T ] = 1 filled = scipy.ndimage.morphology.binary_fill_holes(C) filled = filled.astype(np.uint8) dist = ndimage.distance_transform_edt(filled > T) dist = dist.max() - dist dist -= dist.min() dist = dist/float(dist.ptp()) * 255 dist = dist.astype(np.uint8) nuclei = pymorph.cwatershed(dist, seeds) find = mahotas.label(nuclei) for n in range(0, find[1] + 1): CD = np.where(find[0] == n) XY1 = np.vstack((CD[0], CD[1])) edges = filter.canny(XY1, sigma=1) edges = edges.astype(np.uint8) edges = np.where(edges == 1) TC += len(CD[0]) XY1 = np.vstack((CD[0], CD[1], [i*5]*len(CD[0]), [n]*len(CD[0]))) for p in range(0, len(XY1[0])): for yel in range(0, len(XY1)): h.write(str(XY1[yel][p]) + '\t') h.write('\n') h.write(str(TC) + '\n') h.write('.' + '\n') h.close()
# # # Predictions with regmax method blur_imgH = scipy.ndimage.gaussian_filter(mito_prob, 16) mito_pred3 = blur_imgH<90 blur_imgH = blur_imgH.astype(np.uint8) mito_pred3 = mahotas.erode(mito_pred3, disc) mito_pred3 = mito_pred3.astype(np.uint8) # labeled, nr_objects = scipy.ndimage.label(mito_pred3) # print nr_objects # labeled = labeled.astype(np.uint8) rmax = pymorph.regmax(blur_imgH) pylab.imshow(pymorph.overlay(mito_prob, rmax)) pylab.gray() pylab.show() seeds,nr_nuclei = scipy.ndimage.label(rmax) print nr_nuclei pylab.imshow(mito_pred3) pylab.show() dist = scipy.ndimage.distance_transform_edt(mito_pred3) dist = dist.max() - dist dist-=dist.min() dist = dist/float(dist.ptp())*255 dist = dist.astype(np.uint8) pylab.imshow(dist) pylab.gray() pylab.show()
def SearchMarker(In, image_filtree, marker_param, mask): """Algorithme principale de recherche de marqueur et segmentation :In: image d'entree :image_filtree: image filtree par MeanShift :marker_param: choix de la methode de recherche (1,2 ou 3) :mask: masque de non interet :returns: image label, image pour affichee """ if image_filtree.nChannels == 1: tmp = cv.CreateImage(cv.GetSize(image_filtree), cv.IPL_DEPTH_8U, 3) cv.CvtColor(image_filtree, tmp, cv.CV_GRAY2BGR) image_filtree = cv.CloneImage(tmp) del tmp fg = cv.CloneImage(In) objets = None # Image distance entre de watershed markers = cv.CreateImage(cv.GetSize(In), cv.IPL_DEPTH_32S, 1) img = cv.CloneImage(image_filtree) cv.Zero(img) edge = Detection_contour(In) cont = cv2array(edge)[:, :, 0] cv.Not(edge, edge) dist_map = cv.CreateImage(cv.GetSize(In), cv.IPL_DEPTH_32F, 1) cv.DistTransform(edge, dist_map, cv.CV_DIST_L2, cv.CV_DIST_MASK_5) dist_map_8bit = cv.CloneImage(edge) cv.Zero(dist_map_8bit) cv.ConvertScale(dist_map, dist_map, 3000.0, 0.0) cv.Pow(dist_map, dist_map, 0.3) cv.ConvertScale(dist_map, dist_map_8bit) cv.CvtColor(dist_map_8bit, img, cv.CV_GRAY2BGR) # cv.AddWeighted(image_filtree, 0.3, img, 0.7, 1, img) # cv.CvtColor(img, dist_map_8bit, cv.CV_BGR2GRAY) # # Foreground by regional maxima: detection marqueurs if marker_param == "1" or marker_param == "3": print("Recherche max. regionaux...") I = cv2array(dist_map_8bit)[:, :, 0] If = ndimage.gaussian_filter(I, 5) rmax = pymorph.regmax(If) rmax = pymorph.close_holes(rmax) * 255 #import ipdb;ipdb.set_trace() bool_fg = array2cv(rmax.astype(np.uint8)) cv.ConvertScale(bool_fg, fg) if marker_param == "1": print("Recherche squelette...") from mamba import * from mambaComposed import * from MambaTools import * percent_edge = np.sum(cont) / (edge.width * edge.height) initial_shape = (In.height, In.width) im1 = fillImageWithIplimage(In) imWrk1 = imageMb(im1) blobsMarkers = imageMb(im1, 1) imWrk3 = imageMb(im1, 32) #backgroundMarker = imageMb(im1, 1) #finalMarkers = imageMb(im1, 1) print("taille se %s" % int(15.0 * 6 / percent_edge + 1)) if In.height < 700: alternateFilter(im1, imWrk1, int(15.0 * 6 / percent_edge) + 1, True) elif In.height < 1400: alternateFilter(im1, imWrk1, int(30.0 * 6 / percent_edge) + 1, True) else: alternateFilter(im1, imWrk1, int(60.0 * 6 / percent_edge) + 1, True) minima(imWrk1, blobsMarkers) thinD(blobsMarkers, blobsMarkers) nbStones = label(blobsMarkers, imWrk3) bg_array = getArrayFromImage(imWrk3)[ 0: initial_shape[0], 0: initial_shape[1]] tmp_array = (bg_array > 0) * 255 bg_ = array2cv(tmp_array.astype(np.uint8)) bg = cv.CloneImage(dist_map_8bit) cv.ConvertScale(bg_, bg) cv.Or(fg, bg, fg) cv.ConvertScale(fg, markers) # Watershed print("Watershed...") storage = cv.CreateMemStorage(0) contours = cv.FindContours(fg, storage, cv.CV_RETR_CCOMP, cv.CV_CHAIN_APPROX_SIMPLE) def contour_iterator(contour): while contour: yield contour contour = contour.h_next() cv.Zero(markers) comp_count = 0 for c in contour_iterator(contours): cv.DrawContours(markers, c, cv.ScalarAll(comp_count + 1), cv.ScalarAll(comp_count + 1), -1, -1, 8) comp_count += 1 cv.Watershed(img, markers) if img.nChannels == 3: cv.CvtColor(In, img, cv.CV_GRAY2BGR) elif img.nChannels == 1: img = cv.CloneImage(image_filtree) cv.CvtColor(In, img, cv.CV_GRAY2BGR) else: print("nChannels >< 3 or 1") cv.CvtColor(fg, img, cv.CV_GRAY2BGR) cv.CvtColor(In, img, cv.CV_GRAY2BGR) #bug wshed = Affichage_watershed(markers, img, fg) wshed_lbl = cv2array(markers)[:, :, 0] if marker_param == "1" or marker_param == "2": objets = cv2array(bg)[:, :, 0] objets = objets > 1 print("Keep objects not in background ...") cmpt = 0 label_map = wshed_lbl * 0 for label in np.unique(wshed_lbl): if np.sum(objets * (wshed_lbl == label)) > 0: label_map[wshed_lbl == label] = 0 else: cmpt += 1 label_map[wshed_lbl == label] = cmpt else: label_map = wshed_lbl label_map = Enleve_bord(label_map, mask) return label_map, wshed
import numpy import copy import skimage.filter as skif import skimage.morphology as morph import matplotlib.pyplot as mpl import skimage.feature as feature import pylab import mahotas import pymorph from skimage.filter import canny ### Circles ### raw_circle = misc.imread('circles.png') img_circle = ndimage.gaussian_filter(raw_circle, 15) rmax_circle = pymorph.regmax(img_circle) pylab.imshow(pymorph.overlay(img_circle, rmax_circle)) pylab.show() seeds_circle, nr_circles = ndimage.label(rmax_circle) print "Number of objects: " + str(nr_circles) centers_circles = ndimage.center_of_mass(rmax_circle, seeds_circle, range(1, nr_circles + 1, 1)) print "Centers of gravity: " + str(centers_circles) ### Objects ### raw_objects = misc.imread('objects.png') img_objects = ndimage.gaussian_filter(raw_objects, 3) thres_objects = img_objects > img_objects.mean() pylab.imshow(thres_objects) pylab.show()
pass def writeimg(img, name): pass else: def savejet(img, name): img = (img - img.min()) / float(img.ptp()) * 255 img = img.astype(np.uint8) readmagick.writeimg((cm.jet(img)[:, :, :3] * 255).astype(np.uint8), name) writeimg = readmagick.writeimg dnaf = ndimage.gaussian_filter(dna, 8) rmax = pymorph.regmax(dnaf) pylab.imshow(pymorph.overlay(dna, rmax)) pylab.show() writeimg(pymorph.overlay(dna, rmax), 'dnaf-rmax-overlay.jpeg') savejet(dnaf, 'dnaf-8.jpeg') dnaf = ndimage.gaussian_filter(dna, 16) rmax = pymorph.regmax(dnaf) pylab.imshow(pymorph.overlay(dna, rmax)) pylab.show() writeimg(pymorph.overlay(dna, rmax), 'dnaf-16-rmax-overlay.jpeg') seeds, nr_nuclei = ndimage.label(rmax) print nr_nuclei T = pit.thresholding.otsu(dnaf)
def _segment(self, I, first): """Return the segmented frame 'I'. If 'first is True, then this is the first segmentation iteration, otherwise the second. The returned value is a labeled image of type uint16, in order to be compatible with ISBI's tool. """ # Compute global threshold. otsu_thresh = mh.thresholding.otsu(I.astype('uint16')) # Threshold using global and local thresholds. fnc = fnc_class(I.shape) I_bin = ndimage.filters.generic_filter(I, fnc.filter, size=self._r, extra_arguments=(I, self._min_var, otsu_thresh)) I_med = ndimage.filters.median_filter(I_bin, size=self._r_med) # Remove cells which are too small (leftovers). labeled = mh.label(I_med)[0] sizes = mh.labeled.labeled_size(labeled) too_small = np.where(sizes < self._a_min) I_cleanup = mh.labeled.remove_regions(labeled, too_small) I_cleanup = mh.labeled.relabel(I_cleanup)[0] # Fill holes. I_holes = ndimage.morphology.binary_fill_holes(I_cleanup > 0) # Binary closing. if first and self._r1: # First iteration. I_morph = morph.binary_closing(I_holes, morph.disk(self._r1)) elif not first and self._r2: # Second iteration. I_morph = morph.binary_closing(I_holes, morph.disk(self._r2)) else: # No binary closing. I_morph = I_holes # Fill yet to be filled holes. labels = measure.label(I_morph) labelCount = np.bincount(labels.ravel()) background = np.argmax(labelCount) I_morph[labels != background] = True # Separate touching cells using watershed. # Distance transfrom on which to apply the watershed algorithm. I_dist = ndimage.distance_transform_edt(I_morph) I_dist = I_dist/float(I_dist.max()) * 255 I_dist = I_dist.astype(np.uint8) # Find markers for the watershed algorithm. # Reduce false positive using Gaussian smoothing. I_mask = ndimage.filters.gaussian_filter(I_dist, 8)*I_morph rmax = pymorph.regmax(I_mask) I_markers, _ = ndimage.label(rmax) I_dist = I_dist.max() - I_dist # Cells are now the basins. I_label = pymorph.cwatershed(I_dist, I_markers) if self._debug: plt.subplot(2, 4, 1) plt.imshow(I) plt.title('Original Image') plt.subplot(2, 4, 2) plt.imshow(I_bin) plt.title('After Thresholding') plt.subplot(2, 4, 3) plt.imshow(I_med) plt.title('After Median Filter') plt.subplot(2, 4, 4) plt.imshow(I_cleanup) plt.title('After Cleanup') plt.subplot(2, 4, 5) plt.imshow(I_holes) plt.title('After Hole Filling') plt.subplot(2, 4, 6) plt.imshow(I_morph) plt.title('After Closing') plt.subplot(2, 4, 7) plt.imshow(I_label) plt.title('Labeled Image') plt.show() return I_label.astype('uint16')
def main(): # Load and show original images pylab.gray() # set gray scale mode print print "0. Reading and formatting images..." images = {f: loadAndFormat(f) for f in IMAGE_FILES} for f in IMAGE_FILES: mShow(images[f]) ########################### # -----> Thresholding print print "1. Thresholding images..." thresholdedImages = {f: getThresholdedImage(images[f]) for f in IMAGE_FILES} for name in IMAGE_FILES: mShow(thresholdedImages[name]) ########################### # -----> Count objects # 1st attempt: label the thresholded image from task 1 print print "2. Object counting" pylab.jet() # back to color mode print "\t1st approach: Label thresholded images" for name in IMAGE_FILES: labeled, nrRegions = ndimage.label(thresholdedImages[name]) print "\t" + name + ": " + str(nrRegions) mShow(labeled) # 2nd attempt: Changing threshold level print print "\t2nd approach: Tuned thresholds" # For 'objects.png' some objects are very small (e.g.: screw) or # have many shades (e.g.: spoon) which makes them disappear or appear # fragmented after thresholding. # The advantage of this image is that the background is very dark, # so we can try using a lower threshold to make all shapes more definite objImage = images['objects.png'] T = mahotas.thresholding.otsu(objImage) thresholdedImage = objImage > T * 0.7 # Looks better, but... labeled, nrRegions = ndimage.label(thresholdedImage) print '\tobjects.png' + ": " + str(nrRegions) # it returns 18! # 3rd attempt: Smoothing before thresholding print print "\t3rd approach: Smoothing + Tuned threshold" # Let's apply some Gaussian smoothing AND a lower threshold smoothImage = ndimage.gaussian_filter(objImage, 3) T = mahotas.thresholding.otsu(smoothImage) thresholdedImage = smoothImage > T * 0.7 labeled, nrRegions = ndimage.label(thresholdedImage) print '\tobjects.png' + ": " + str(nrRegions) # it worked! Let's save the labeled images for later # (we will use them for center calculation) labeledImages = {} labeledImages['objects.png'] = (labeled, nrRegions) mShow(labeled) # Let's see if this approach works on the other images for name in ['circles.png', 'peppers.png']: img = images[name] smoothImage = ndimage.gaussian_filter(img, 3) T = mahotas.thresholding.otsu(smoothImage) thresholdedImage = smoothImage > T * 0.7 labeled, nrRegions = ndimage.label(thresholdedImage) print '\t' + name + ": " + str(nrRegions) # Again no luck with the circles! # (We will take a closer look at the peppers later) # 4th attempt: # 'circles.png': The problem is that some circles appear "glued together". # Let's try another technique: # - smoothing the picture with a Gaussian filter # - then searching for local maxima and counting regions # (smoothing avoids having many scatter maxima and a higher level # must be used than in the previous attempt) # - use watershed with the maxima as seeds over the thresholded image # to complete the labelling of circles print print "\t4th approach: Smoothing + Local maxima + Watershed" smoothImage = ndimage.gaussian_filter(images['circles.png'], 10) localmaxImage = pymorph.regmax(smoothImage) # A distance transform must be applied before doing the watershed dist = ndimage.distance_transform_edt(thresholdedImages['circles.png']) dist = dist.max() - dist dist -= dist.min() dist = dist / float(dist.ptp()) * 255 dist = dist.astype(np.uint8) seeds, nrRegions = ndimage.label(localmaxImage) labeled = pymorph.cwatershed(dist, seeds) print "\t" + 'circles.png' + ": " + str(nrRegions) # worked right only for 'circles.png' ! labeledImages['circles.png'] = (labeled, nrRegions) mShow(labeled) print print "\t5th approach: Smoothing + Multi-threshold +" +\ " Morphology labeling + Size filtering" # 5th approach (only peppers left!) imagePeppers = images['peppers.png'] # Problems with peppers are: # - very different colours, they cause thresholding to work poorly # - each pepper has some brighter parts which are detected as local maxima # We propose to address those issues as follows: # - gaussian filter to smooth regions of light or shadow within each pepper smoothImage = ndimage.gaussian_filter(imagePeppers, 2) # - instead of thresholding to create a binary image, # create multiple thresholds to separate the most frequent colors. # In this case, 3 thresholds will be enough mthrImagePeppers = multiThreshold(smoothImage, 3) # - ndimage.label didn't give good results, we try another # labelling algorithm from skimage import morphology labeled = morphology.label(mthrImagePeppers) nrRegions = np.max(labeled) + 1 print "\t\tTotal number of regions" print "\t\t\t" + 'peppers.png' + ": " + str(nrRegions) # - after counting regions, filter to keep only the sufficiently big ones filtered, nrRegions = filterRegions(labeled, 0.05) print "\t\tBig enough regions" print "\t\t\t" + 'peppers.png' + ": " + str(nrRegions) labeledImages['peppers.png'] = (filtered, nrRegions) mShow(filtered) ########################### # -----> Find center points print print "3. Centers for objects" for img in IMAGE_FILES: labeledImage, nr_objects = labeledImages[img] CenterOfMass = ndimage.measurements.center_of_mass labels = range(1, nr_objects + 1) centers = CenterOfMass(labeledImage, labeledImage, labels) centers = [(int(round(x)), int(round(y))) for (x, y) in centers] print '\t' + img + ": " + str(centers)
# Isa = np.rollaxis(np.dstack(tiffile.imread(i)), 2, 0) Is = np.rollaxis(np.dstack([tiffile.imread(i) for i in img_files]), 2, 0) movie = Is Is = Is[:,::2,::2].astype('float64') # Calculate the maximum across all frames accum = np.log(Is.max(axis=0)) import skimage.segmentation, skimage.feature, skimage.morphology.watershed import mahotas, pymorph I_show = accum.copy() #increase contrast import ImageEnhance I_contrast = pow(I_show.astype("uint16"), 3) #find regional maxima regionalMax = pymorph.regmax((I_contrast).astype("uint16")) #find seeds and cell number seeds,numCells = ndimage.label(regionalMax) print numCells #edge detection T = mahotas.thresholding.otsu(I_contrast.astype("uint16")) dist = ndimage.distance_transform_edt(I_contrast.astype("uint16") > T) dist = dist.max() - dist dist -= dist.min() dist = dist/float(dist.ptp()) * 255 dist = dist.astype(np.uint8) #watershed I_mask = pymorph.cwatershed(dist, seeds) frames, x, y = Is.shape
import numpy import copy import skimage.filter as skif import skimage.morphology as morph import matplotlib.pyplot as mpl import skimage.feature as feature import pylab import mahotas import pymorph from skimage.filter import canny ### Circles ### raw_circle = misc.imread('circles.png') img_circle = ndimage.gaussian_filter(raw_circle, 15) rmax_circle = pymorph.regmax(img_circle) pylab.imshow(pymorph.overlay(img_circle, rmax_circle)) pylab.show() seeds_circle, nr_circles = ndimage.label(rmax_circle) print "Number of objects: " + str(nr_circles) centers_circles = ndimage.center_of_mass(rmax_circle, seeds_circle, range(1, nr_circles + 1, 1)) print "Centers of gravity: " + str(centers_circles) ### Objects ### raw_objects = misc.imread('objects.png') img_objects = ndimage.gaussian_filter(raw_objects, 3) thres_objects = img_objects > img_objects.mean() pylab.imshow(thres_objects) pylab.show() # regmax is resulting in an error. Looks like this is working
pylab.imshow(dnaf > T) pylab.show() # Deal with merged/touching nuclei labeled,nr_objects = ndimage.label(dnaf > T) print nr_objects # prints 18 pylab.imshow(labeled) pylab.jet() # resets to jet from gray-scale pylab.show() ############ STEP TWO -- Segmenting Image/Finding seeds # Smooth image->find regional maxima->use maxima as seeds for watershed # First try: dnaf = ndimage.gaussian_filter(dna, 8) rmax = pymorph.regmax(dnaf) pylab.imshow(pymorph.overlay(dna, rmax)) # Overlay returns a color image with gray level component in first argument, second arg is red pylab.show() # Second try - Increase sigma: dnaf = ndimage.gaussian_filter(dna, 16) rmax = pymorph.regmax(dnaf) pylab.imshow(pymorph.overlay(dna, rmax)) seeds,nr_nuclei = ndimage.label(rmax) print nr_nuclei # prints 22 # Watershed to distance transform of threshold T = mahotas.thresholding.otsu(dnaf) dist = ndimage.distance_transform_edt(dnaf > T) dist = dist.max() - dist
def NumpyDetectEdge(fname, color_filter=(1, 1, 1), radius=510, center=(582, 791), show=False): plate_circle = GetCircle(center, radius) im = misc.imread(fname) im_gray = np.dot(im, color_filter) / sum(color_filter) imf = ndimage.gaussian_filter(im_gray, sigma=2) imf = 256 - imf # invert color imc = np.zeros(imf.shape, dtype=np.int32) imc[plate_circle] = imf[plate_circle] imc = imc[center[0] - radius:center[0] + radius, center[1] - radius:center[1] + radius] T = 100 imc[np.where(imc < T)] = 0 rmax = pymorph.regmax(imc) seeds, n_colonies = ndimage.label( rmax ) # gives a unique integer number to each region and fills it with that number count = 0 for i in xrange(n_colonies): seed = np.where(seeds == i) l = len(seed[0]) # filter seeds which are touching the perimeter (or 5 pixel away from it) perimeter = False for j in xrange(l): if np.sqrt((radius - seed[0][j])**2 + (radius - seed[1][j])**2) > radius - 5: perimeter = True if perimeter: continue seedx = [(x + center[0] - radius) for x in seed[0]] seedy = [(y + center[1] - radius) for y in seed[1]] meanx = np.mean(seedx) meany = np.mean(seedy) colony_circle = GetCircle((meanx, meany), 3) colony_color = np.min(imf[colony_circle]) if colony_color >= 110: count += 1 if colony_color < 100: im[meanx, meany, :] = (255, 0, 0) # red elif 100 < colony_color < 110: im[meanx, meany, :] = (255, 255, 0) # yellow elif 110 < colony_color < 120: im[meanx, meany, :] = (0, 255, 0) # green elif 120 < colony_color < 130: im[meanx, meany, :] = (0, 255, 255) # cyan elif 130 < colony_color < 140: im[meanx, meany, :] = (0, 0, 255) # blue elif 140 < colony_color < 150: im[meanx, meany, :] = (255, 0, 255) # magenta elif 150 < colony_color: im[meanx, meany, :] = (255, 255, 255) # white if show: plt.imshow(im) plt.show() return count