def roysam_watershed(dna,thresh=None,blur_factor=3): ''' Run watershed on mixed gradient & intensity image as suggested by Lin et al. -Input dna: DNA image thresh: Gray value threshold (default: computed using Murphy's RC) blur_factor: Blur factor (default: 3) REFERENCE Gang Lin, Umesh Adiga, Kathy Olson, John F. Guzowski, Carol A. Barnes, and Badrinath Roysam "A Hybrid 3-D Watershed Algorithm Incorporating Gradient Cues & Object Models for Automatic Segmentation of Nuclei in Confocal Image Stacks" Vol. 56A, No. 1, pp. 23-36 Cytometry Part A, November 2003. ''' if thresh is None: thresh = 'murphy_rc' M = (ndimage.gaussian_filter(dna,4) > thresholding.threshold(dna,thresh)) G = pymorph.gradm(dna) D = ndimage.distance_transform_edt(M) D *= np.exp(1-G/float(G.max())) T = ndimage.gaussian_filter(D.max() - D,blur_factor) if T.max() < 256: T = pymorph.to_uint8(T) else: T = pymorph.to_uint8(T*(256.0/T.max())) T *= M R = pymorph.regmin(T) R *= M R,N = ndimage.label(R) R[(R==0)&(M==0)] = N+1 W,WL = mahotas.cwatershed(T,R,return_lines=True) W *= M return W,WL
def __init__(self,dna,mu,iSigma,thresh=None): ''' M = Merged(dna) ''' self.mu = mu self.iSigma = iSigma self.C = pymorph.gradm(dna) self.W,self.WL = roysam_watershed(dna,thresh) self.B,self.neighbours,self.border_id = border(self.W) self.border_regions=dict((y,x) for x,y in self.border_id.iteritems())
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 indice_circularite(label_map, seuil): """Fait un test de circularite sur chaque objet de l'image :label_map: image des label :seuil: seuil de circularite :returns: image verifiant la circularite C > seuil """ for label in np.unique(label_map): current_label = (label_map == label) A = np.sum(current_label) edge_current_label = pymorph.gradm(current_label) P = np.sum(edge_current_label) if P > 0: C = 4 * np.pi * A / (P ** 2) else: C = 0 if C < seuil: label_map[label_map == label] = 0 return label_map
def colorize_segmentation(self, f_, g, k=0.15, t=3): # 25jan2013 ''' Parameters ---------- f: original image; g: labeled segmentation; k: transparency level; t: thickness ''' # f = uint8(ianormalize(f_, (0, 255)) + 0.5) f = (ianormalize(f_, (0, 255)) + 0.5).astype(np.uint8) # g = g-1 #remove background if watershed was used z = mm.lblshow(g) # z = uint8(ianormalize(z,(0,255))+0.5) # z = (ianormalize(z,(0,255))+0.5).astype(np.uint8) zc = mm.gradm(z, mm.secross(0), mm.secross(t)) # Regions: m = z[0] == 0 z[0] = m * f + k * (1 - m) * z[0] + (1 - k) * (1 - m) * f m = z[1] == 0 z[1] = m * f + k * (1 - m) * z[1] + (1 - k) * (1 - m) * f m = z[2] == 0 z[2] = m * f + k * (1 - m) * z[2] + (1 - k) * (1 - m) * f # Contours: m = zc[0] == 0 z[0] = m * z[0] + (1 - m) * zc[0] m = zc[1] == 0 z[1] = m * z[1] + (1 - m) * zc[1] m = zc[2] == 0 z[2] = m * z[2] + (1 - m) * zc[2] return z
def findEllipse( In, method, disp=0, pick_fig=False): """ Parameters ----------- In : array_like or tuple of array depends on mode Input data. method: string ( 'Box', 'Moment', 'all' ) Returns ------- Out : list of b-axis """ b_axis=[]; pts=[]; cmpt=0; labels=np.unique(In) #Bar progression bar=Tk.Tk(className='Fitting Ellipses...') m = Meter(bar, relief='ridge',fillcolor='grey', bd=2) m.pack(fill='x') m.set(0.0, 'Starting...') M=np.max(labels) if disp==1: fig = pl.figure() ax = fig.add_subplot(221, aspect='auto') # ax.set_title('Image des labels') pl.imshow(In) In=np.fliplr(np.transpose(In)) img_size=np.shape(In) if method=='Box': for label in labels[labels>0]: # Methode 1 curr_object=pymorph.gradm(In==label) pts.append(np.where(curr_object==True)) ax = fig.add_subplot(222, aspect='auto') pl.plot(pts[cmpt][0],pts[cmpt][1],'+', markersize=6) cmpt+=1 m.set(0.5*float(cmpt)/M) cmpt=0 for label in labels[labels>0]: (cm,a,b,tetha) = bounding_ellipse(pts[cmpt]) xcenter, ycenter =cm[0],cm[1] angle = 180*tetha /np.pi b_axis.append(np.min(np.array([b,a]))) # Affichage ax = fig.add_subplot(222, aspect='auto') # ax.set_title('Ellipses englobantes') e = patches.Ellipse((xcenter, ycenter), b, a, angle=angle, linewidth=2, fill=False, zorder=2) ax.add_artist(e) e.set_clip_box(ax.bbox) e.set_alpha(0.8) pl.xlim([0, img_size[0]]) pl.ylim([0, img_size[1]]) cmpt+=1 m.set(0.5+0.5*float(cmpt)/M) elif method=='Moments': for label in labels[labels>0]: # Methode 1 curr_object=In==label #pymorph.gradm(In==label) pts.append(np.where(curr_object==True)) ax = fig.add_subplot(222, aspect='auto') pl.plot(pts[cmpt][0],pts[cmpt][1],'+', markersize=6) cmpt+=1 m.set(0.5*float(cmpt)/(M)) cmpt=0 for label in labels[labels>0]: #Methode 2 (cm,a,b,tetha)=fitEllipseByMoments(In==label) xcenter, ycenter =cm[0],cm[1] angle = 180*tetha /np.pi b_axis.append(np.min(np.array([b,a]))) ## Affichage ax = fig.add_subplot(222, aspect='auto') # ax.set_title('Ellipses de meme moments') e = patches.Ellipse((xcenter, ycenter), b, a, angle=angle, linewidth=2, fill=False, zorder=2) ax.add_artist(e) e.set_clip_box(ax.bbox) e.set_alpha(0.8) pl.xlim([0, img_size[0]]) pl.ylim([0, img_size[1]]) cmpt+=1 m.set(0.5+0.5*float(cmpt)/(M)) ax = fig.add_subplot(223, aspect='auto') # ax.set_title('Fréquence cumulée axes b en pixel') pl.hist(b_axis, cumulative=True) pl.title('Courbe granulometrique cumulee') fig.show() else: if method=='Box': print("Method Box") for label in labels[labels>0]: #Methode 1 contour=pymorph.gradm(In==label) pts=np.where(contour==True) b = bounding_ellipse(pts,0) b_axis.append(b) cmpt+=1 m.set(float(cmpt)/(M)) elif method=='Moments': print("Method Moments") for label in labels[labels>0]: #Methode 2 b=fitEllipseByMoments(In==label,0) b_axis.append(b) m.set(float(cmpt)/(M)) cmpt+=1 bar.destroy() print("->D50, Methode ellipse par "+method+":"+repr(np.median(b_axis))+" pixels") if pick_fig == True & disp==1: return b_axis, fig else: return b_axis, None
print('Filename: {} - Shape: {}'.format('IM ({}).jpg'.format(i + 1), img.shape)) img_out = mm_segmentation.alternative_solution(img, optype, opthickness) cv2.imwrite('{}/lungIM ({}).png'.format(DIR_dest, i + 1), img_out) # tmp = mm.gshow(img, img_out) # tmp = colorize_segmentation(img, img_out) # num = filename[:-4] # adwrite(num + '_out.png', tmp) # adwrite(num + '_out.png', img_out) if optype == 'coronal' and opnmasks == 2: u, i, j = iaunique(ravel(img_out)) tmp1 = mm.gradm(img_out == u[1], mm.sedisk(opthickness), mmsedisk(opthickness)) tmp2 = mm.gradm(img_out == u[2], mm.sedisk(opthickness), mmsedisk(opthickness)) s1 = sum(tmp1, 0) s2 = sum(tmp2, 0) s = mm.subm(s1, s2) meio = len(s) / 2 if sum(s[0:meio]) > sum(s[meio::]): tmpR = tmp1 tmpL = tmp2 else: tmpR = tmp2 tmpL = tmp1 # adwrite(num + '_maskL.png', 255 * tmpL) # adwrite(num + '_maskR.png', 255 * tmpR) adwrite('{}/maskLIM ({}).png'.format(DIR_dest, i + 1), 255 * tmpL)