def clean_mask(mask): # first erode to get rid of noise mask = erode(mask, sedisk(2)) # then dilate more to capture a slightly larger area mask = dilate(mask, sedisk(16)) return mask
def create_shad(matte, target): """ Creates a shadowed image given target (to be shadowed) and matte. The matte can be smaller that the target in which case it will be used at some random location. """ # first get a bounding box of the shadow matte mask = np.array(matte < 1, dtype=int) mask = dilate(erode(mask, sedisk(3)), sedisk(3)) left, upper, right, lower = PIL.Image.fromarray(mask).getbbox() # now cut it out mh, mw = matte.shape[:2] matte_bbox = matte[upper:lower, left:right] # import pdb; pdb.set_trace() # get new dimensions mh, mw = matte_bbox.shape[:2] th, tw = target.shape[:2] new_matte = np.ones(target.shape) # get random position to insert the matte matte_x = matte_y = 0 if mh < th: matte_y = (th - mh) * np.random.random() if mw < tw: matte_x = (tw - mw) * np.random.random() new_matte[matte_y:matte_y + mh, matte_x:matte_x + mw] = matte_bbox return new_matte * target
def _get_line_filter(segment_size, variation): """Computes the filters that can be used to enhance vertical lines in an Image. Args: segment_size: Size of the segment variatoin: Variation in horizontal axes if user wants not exact vertical lines. Returns: filters saved in 3D matrices, each 3rd dimension includes a filter """ smalldisk = pymorph.sedisk(1); bigdisk = pymorph.sedisk(2); horizontal_filter = numpy.zeros((variation*2+1, variation*2+1, segment_size)) horizontal_surrounding = numpy.zeros((variation*2+1, variation*2+1, segment_size)) index = -1 # Generates the filters for each direction of lines for variation_index in range(-variation, variation + 1): index = index + 1; points = bresenham(variation + variation_index,0, variation - variation_index, segment_size - 1) tmp = numpy.zeros((variation*2+1)*segment_size).reshape((variation*2+1, segment_size)) for point_ind in range(0, len(points)): tup_point = points[point_ind] tmp[tup_point[0], tup_point[1]] = 1 tmp_filter = pymorph.dilate(pymorph.binary(tmp), smalldisk) tmp_surrounding = pymorph.subm(pymorph.dilate(pymorph.binary(tmp), bigdisk) , \ pymorph.dilate(pymorph.binary(tmp), smalldisk)) horizontal_filter[index,:,:] = tmp_filter horizontal_surrounding[index,:,:] = tmp_surrounding return horizontal_filter, horizontal_surrounding
def run_one(fname, outname): N = 1 im = img.open(fname) #im = im.filter(ImageFilter.BLUR) im = im.resize((600, 600), img.ANTIALIAS) im = im.convert('L') im = invert(im) x = np.asarray(im) y = x size = 3 for i in range(N): y = morph.dilate(y, morph.sedisk(size)) y = morph.close(y, morph.sedisk(size)) jm = img.fromarray(y) jm = invert(jm) jm = jm.resize((400, 400), img.ANTIALIAS) jm.save(outname)
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 morph_sharp(im): img = numpy.zeros(im.shape, dtype=numpy.int32) # Choose a disk structuring element (3x3 disk) # Function could be modified to pass structuring element in se = pymorph.sedisk(r=1, dim=2) # Apply grayscale erosion Ie = pymorph.erode(im, se) # Apply grayscale dilation Id = pymorph.dilate(im, se) for i in range(0, im.shape[0]): for j in range(0, im.shape[1]): # Compute differences between original image and processed da = Id[i][j] - im[i][j] db = im[i][j] - Ie[i][j] if da < db: img[i][j] = Id[i][j] elif da > db: img[i][j] = Ie[i][j] else: img[i][j] = im[i][j] return img
def morph_sharp(im): img = numpy.zeros(im.shape,dtype=numpy.int32) # Choose a disk structuring element (3x3 disk) # Function could be modified to pass structuring element in se = pymorph.sedisk(r=1,dim=2) # Apply grayscale erosion Ie = pymorph.erode(im,se) # Apply grayscale dilation Id = pymorph.dilate(im,se) for i in range(0,im.shape[0]): for j in range(0,im.shape[1]): # Compute differences between original image and processed da = Id[i][j] - im[i][j] db = im[i][j] - Ie[i][j] if da < db: img[i][j] = Id[i][j] elif da > db: img[i][j] = Ie[i][j] else: img[i][j] = im[i][j] return img
def test_sedisk(): se = pymorph.sedisk(4) w,h = se.shape assert w == h X,Y = np.where(~se) X -= w//2 Y -= h//2 assert np.all( X**2+Y**2 > (w//2)**2 )
def LowResSegmentation(image): '''Perform a simple threshold after DoG filtering''' noBack=RemoveModalBackground(image) #print "from Segmeta noBack:",noBack.min(),noBack.mean() blurLowRes=nd.filters.gaussian_filter(noBack,13) blurHiRes=nd.filters.gaussian_filter(noBack,1) midPass=pymorph.subm(blurHiRes,0.70*blurLowRes) bin=(midPass>1.5*midPass.mean()) binLowRes=pymorph.open(bin,pymorph.sedisk(4)) return binLowRes
def LowResSegmentation(image): """Perform a simple threshold after DoG filtering""" noBack = RemoveModalBackground(image) # print "from Segmeta noBack:",noBack.min(),noBack.mean() blurLowRes = nd.filters.gaussian_filter(noBack, 13) blurHiRes = nd.filters.gaussian_filter(noBack, 1) midPass = pymorph.subm(blurHiRes, 0.70 * blurLowRes) bin = midPass > 1.5 * midPass.mean() binLowRes = pymorph.open(bin, pymorph.sedisk(4)) return binLowRes
def test_opentransf(): f = np.array([[0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 1, 1, 1, 0, 0], [0, 1, 0, 1, 1, 1, 0, 0], [0, 0, 1, 1, 1, 1, 0, 0], [1, 1, 0, 0, 0, 0, 0, 0]], bool) ot = pymorph.opentransf(f, 'city-block') for y in xrange(ot.shape[0]): for x in xrange(ot.shape[1]): r = ot[y, x] t = f.copy() for k in xrange(1, r + 1): assert t[y, x] t = pymorph.open(f, pymorph.sedisk(k, 2, 'city-block')) assert not t[y, x]
def _get_line_filter(segment_size, variation): """Computes the filters that can be used to enhance vertical lines in an Image. Args: segment_size: Size of the segment variatoin: Variation in horizontal axes if user wants not exact vertical lines. Returns: filters saved in 3D matrices, each 3rd dimension includes a filter """ smalldisk = pymorph.sedisk(1) bigdisk = pymorph.sedisk(2) horizontal_filter = numpy.zeros( (variation * 2 + 1, variation * 2 + 1, segment_size)) horizontal_surrounding = numpy.zeros( (variation * 2 + 1, variation * 2 + 1, segment_size)) index = -1 # Generates the filters for each direction of lines for variation_index in range(-variation, variation + 1): index = index + 1 points = bresenham(variation + variation_index, 0, variation - variation_index, segment_size - 1) tmp = numpy.zeros((variation * 2 + 1) * segment_size).reshape( (variation * 2 + 1, segment_size)) for point_ind in range(0, len(points)): tup_point = points[point_ind] tmp[tup_point[0], tup_point[1]] = 1 tmp_filter = pymorph.dilate(pymorph.binary(tmp), smalldisk) tmp_surrounding = pymorph.subm(pymorph.dilate(pymorph.binary(tmp), bigdisk) , \ pymorph.dilate(pymorph.binary(tmp), smalldisk)) horizontal_filter[index, :, :] = tmp_filter horizontal_surrounding[index, :, :] = tmp_surrounding return horizontal_filter, horizontal_surrounding
def _getLineFilter(self, segmentSize, variation): smallDisk = pymorph.sedisk(1); bigDisk = pymorph.sedisk(2); horizontal_filter = numpy.zeros((variation*2+1,variation*2+1,segmentSize)) horizontal_surrounding = numpy.zeros((variation*2+1,variation*2+1,segmentSize)) index = -1 for i in range(-variation,variation+1): index = index + 1; # find the line between selected points points = bresenham(variation+i,0,variation-i,segmentSize-1) tmp = numpy.zeros((variation*2+1)*segmentSize).reshape((variation*2+1, segmentSize)) for l in range(0, len(points)): tup_point = points[l] tmp[tup_point[0], tup_point[1]] = 1 tmp_filter = pymorph.dilate(pymorph.binary(tmp), smallDisk) tmp_surrounding = pymorph.subm(pymorph.dilate(pymorph.binary(tmp), bigDisk) , pymorph.dilate(pymorph.binary(tmp), smallDisk)) horizontal_filter[index,:,:] = tmp_filter horizontal_surrounding[index,:,:] = tmp_surrounding return horizontal_filter, horizontal_surrounding
def test_opentransf(): f = np.array([ [0,0,0,0,0,0,0,0], [0,0,1,1,1,1,0,0], [0,1,0,1,1,1,0,0], [0,0,1,1,1,1,0,0], [1,1,0,0,0,0,0,0]], bool) ot = pymorph.opentransf( f, 'city-block') for y in xrange(ot.shape[0]): for x in xrange(ot.shape[1]): r = ot[y,x] t = f.copy() for k in xrange(1, r+1): assert t[y,x] t = pymorph.open(f, pymorph.sedisk(k, 2, 'city-block')) assert not t[y,x]
def _getBlobs(im, minsize=10, opendisk=0): """ Find blobs in an image. :param im: input image :type im: numpy array :param minsize: minimal size of detected blobs :type minsize: int :param opendisk: disk size for opening operation (ommitted when opendisk <= 0) :type opendisk: int :return: identifiers for areas with blobs > minsize and labeled image (lac,lab) """ if opendisk > 0: im = m.open(im.astype(np.int), m.sedisk(opendisk)) n = np.array([[0, 1, 0], [1, 1, 1], [0, 1, 0]]) lab, nr = labeled.label(im, n) sizes = np.bincount(np.reshape(lab, (lab.shape[0] * lab.shape[1]))) lac = np.nonzero(sizes > minsize)[0] return lac, lab
def morph_toggleCE(im): img = numpy.zeros(im.shape, dtype=numpy.int32) se = pymorph.sedisk(r=1, dim=2) Ie = pymorph.erode(im, se) Id = pymorph.dilate(im, se) for i in range(0, im.shape[0]): for j in range(0, im.shape[1]): da = Id[i][j] - im[i][j] db = im[i][j] - Ie[i][j] if da < db: img[i][j] = Id[i][j] else: img[i][j] = Ie[i][j] return img
def morph_CE(im): img = numpy.zeros(im.shape, dtype=numpy.int32) se = pymorph.sedisk(r=1, dim=2) # Top-hat by opening THo = pymorph.openth(im, se) # Top-hat by closing THc = pymorph.closeth(im, se) for i in range(0, im.shape[0]): for j in range(0, im.shape[1]): newPixel = im[i][j] + THo[i][j] - THc[i][j] if newPixel > 255: img[i][j] = 255 else: img[i][j] = newPixel return img
def morph_CE(im): img = numpy.zeros(im.shape,dtype=numpy.int32) se = pymorph.sedisk(r=1,dim=2) # Top-hat by opening THo = pymorph.openth(im,se) # Top-hat by closing THc = pymorph.closeth(im,se) for i in range(0,im.shape[0]): for j in range(0,im.shape[1]): newPixel = im[i][j] + THo[i][j] - THc[i][j] if newPixel > 255: img[i][j] = 255 else: img[i][j] = newPixel return img
def morph_toggleCE(im): img = numpy.zeros(im.shape,dtype=numpy.int32) se = pymorph.sedisk(r=1,dim=2) Ie = pymorph.erode(im,se) Id = pymorph.dilate(im,se) for i in range(0,im.shape[0]): for j in range(0,im.shape[1]): da = Id[i][j] - im[i][j] db = im[i][j] - Ie[i][j] if da < db: img[i][j] = Id[i][j] else: img[i][j] = Ie[i][j] return img
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 alternative_solution(self, a, orientation='coronal', linethickness=10, outimg=False): ''' Paramenters ----------- a: original image in graylevel ''' H, W = a.shape if orientation == 'coronal': # UL = mm.limits(a)[1] # upper limit UL = 255 b = 1 - iacircle(a.shape, H / 3, (1.4 * H / 3, W / 2)) # Circle b = b[0:70, W / 2 - 80:W / 2 + 80] # Rectangle # if outimg: # b_ = 0 * a; b_[0:70, W / 2 - 80:W / 2 + 80] = UL * b # b_ only for presentation # b_[:, W / 2 - linethickness / 2:W / 2 + linethickness / 2] = UL # b_ only for presentation c = a + 0 c[:, W / 2 - linethickness / 2:W / 2 + linethickness / 2] = UL c[0:70, W / 2 - 80:W / 2 + 80] = (1 - b) * c[0:70, W / 2 - 80:W / 2 + 80] + b * UL c[0:40, W / 2 - 70:W / 2 + 70] = UL d = mm.open(c, mm.img2se(mm.binary(np.ones((20, 10))))) e = mm.close(d, mm.seline(5)) f = mm.close_holes(e) g = mm.subm(f, d) h = mm.close_holes(g) i = mm.areaopen(h, 1000) j1, j2 = iaotsu(i) # j = i > j1 ret, j = cv2.threshold(cv2.GaussianBlur(i, (7, 7), 0), j1, 255, cv2.THRESH_BINARY) k = mm.open(j, mm.seline(20, 90)) l = mm.areaopen(k, 1000) # m = mm.label(l) res = np.vstack( [np.hstack([c, d, e, f, g]), np.hstack([h, i, j, k, l])]) cv2.imshow('Result', res) cv2.waitKey(0) cv2.destroyAllWindows() ################################ # l_ = mm.blob(k,'AREA','IMAGE') # l = l_ == max(ravel(l_)) # m = mm.open(l, mm.sedisk(3)) # VERIFICAR O MELHOR ELEMENTO ESTRUTURANTE AQUI # n = mm.label(m) if outimg: if not os.path.isdir('outimg'): os.mkdir('outimg') def N(x): # y = uint8(ianormalize(x, (0, 255)) + 0.5) y = (ianormalize(x, (0, 255)) + 0.5).astype(np.uint8) return y adwrite('outimg/a.png', N(a)) adwrite('outimg/b.png', N(b_)) adwrite('outimg/c.png', N(c)) adwrite('outimg/d.png', N(d)) adwrite('outimg/e.png', N(e)) adwrite('outimg/f.png', N(f)) adwrite('outimg/g.png', N(g)) adwrite('outimg/h.png', N(h)) adwrite('outimg/i.png', N(i)) adwrite('outimg/j.png', N(j)) adwrite('outimg/k.png', N(k)) adwrite('outimg/l.png', N(l)) adwrite('outimg/m.png', N(m)) # adwrite('outimg/n.png', N(n)) return m else: b = mm.areaopen(a, 500) c = mm.close(b, mm.sebox(3)) d = mm.close_holes(c) e = mm.subm(d, c) f = mm.areaopen(e, 1000) # g = f > 5 ret, g = cv2.threshold(cv2.GaussianBlur(f, (5, 5), 0), 3, 255, cv2.THRESH_BINARY) # ret, g = cv2.threshold( # cv2.GaussianBlur(f, (7, 7), 0), # 5, 255, # cv2.THRESH_BINARY_INV) h = mm.asf(g, 'CO', mm.sedisk(5)) i = mm.close_holes(h) res = np.vstack( [np.hstack([a, b, c, d, e]), np.hstack([f, g, h, i, a])]) cv2.imshow('Result', res) cv2.waitKey(0) cv2.destroyAllWindows() if outimg: if not os.path.isdir('outimg'): os.mkdir('outimg') def N(x): y = (ianormalize(x, (0, 255)) + 0.5).astype(np.uint8) return y adwrite('outimg/a.png', N(a)) adwrite('outimg/b.png', N(b)) adwrite('outimg/c.png', N(c)) adwrite('outimg/d.png', N(d)) adwrite('outimg/e.png', N(e)) adwrite('outimg/f.png', N(f)) adwrite('outimg/g.png', N(g)) adwrite('outimg/h.png', N(h)) adwrite('outimg/i.png', N(i)) return i
def tentDetection_MM(strInputFile, maxTentArea, strOutputFile, strShape='box', iThresh_coeff=0): # five step to do this # 1. opening-determine the square structure element (6-60 m2/resolution) # 2. opening by reconstruction # 3. top-hat by reconstruction # 4. lower threshold # 5. double threshold import pymorph as pymm objImg = osgeo.gdal.Open(strInputFile, GA_ReadOnly) nRasterCount = objImg.RasterCount poDataset = objImg.ReadAsArray().astype(np.float) geotransform = objImg.GetGeoTransform() pixelWidth = np.fabs(geotransform[1]) pixelHeight = np.fabs(geotransform[5]) resolution = pixelWidth * pixelHeight # NoDataValue = objImg.GetRasterBand(1).GetNoDataValue() # gray scale image if (nRasterCount == 1): objnImg = pymm.to_int32(poDataset) # RGB image elif (nRasterCount == 3): objnImg = pymm.to_gray(poDataset) else: print 'it only supports gray-scale or RGB image' sys.exit(1) # determine the structure element iNum = int(np.sqrt(maxTentArea) / resolution) + 1 if (strShape == 'box'): objStructureElement = pymm.sebox(iNum) elif (strShape == 'cross'): objStructureElement = pymm.secross(iNum) else: objStructureElement = pymm.sedisk(iNum) # opening objOpen = pymm.open(objnImg, objStructureElement) # opening by reconstruction objOpenRec = pymm.openrec(objOpen, objStructureElement, objStructureElement) objtophat = pymm.openrecth(objnImg, objStructureElement, objStructureElement) # objtophat = pymm.subm(objnImg, objOpenRec) # objTent = pymm.threshad(objtophat, 0.25 * objnImg, 0.40 * objnImg) # y = mean + k*std (minValue, maxValue, meanValue, stdValue) = objImg.GetRasterBand(1).GetStatistics(0, 1) if (nRasterCount == 3): (minValue2, maxValue2, meanValue2, stdValue2) = objImg.GetRasterBand(2).GetStatistics(0, 1) (minValue3, maxValue3, meanValue3, stdValue3) = objImg.GetRasterBand(3).GetStatistics(0, 1) meanValue = 0.2989 * meanValue + 0.5870 * meanValue2 + 0.1140 * meanValue3 maxValue = 0.2989 * maxValue + 0.5870 * maxValue2 + 0.1140 * maxValue3 # meanValue = 438 # maxValue = 2047 threshad = meanValue + iThresh_coeff * stdValue objTent = pymm.threshad(objtophat, threshad, maxValue) data_list = [] data_list.append(objTent) WriteOutputImage(strOutputFile, 1, data_list, 0, 0, 0, strInputFile) '''
def tentDetection_wt_mm(strInputFile, maxTentArea, strOutputFile, strShape='box', iThresh_coeff=0): import pywt import pymorph as pymm objImg = osgeo.gdal.Open(strInputFile, GA_ReadOnly) nRasterCount = objImg.RasterCount poDataset = objImg.ReadAsArray().astype(np.float) geotransform = objImg.GetGeoTransform() pixelWidth = np.fabs(geotransform[1]) pixelHeight = np.fabs(geotransform[5]) resolution = pixelWidth * pixelHeight # NoDataValue = objImg.GetRasterBand(1).GetNoDataValue() # gray scale image if (nRasterCount == 1): objnImg = pymm.to_int32(poDataset) # RGB image elif(nRasterCount == 3): objnImg = pymm.to_gray(poDataset) else: print 'it only supports gray-scale or RGB image' sys.exit(1) # determine the structure element iNum = int(np.sqrt(maxTentArea) / resolution) + 1 if (strShape == 'box'): objStructureElement = pymm.sebox(iNum) elif (strShape == 'cross'): objStructureElement = pymm.secross(iNum) else: objStructureElement = pymm.sedisk(iNum) # decomposition until 1 level wp = pywt.WaveletPacket2D(data=objnImg, wavelet='db4', mode='sym', maxlevel=1) # iMaxLevel = wp.maxlevel() # top-hat wp['h'].data = pymm.openrecth(pymm.to_int32(wp['h'].data), objStructureElement, objStructureElement) wp['v'].data = pymm.openrecth(pymm.to_int32(wp['v'].data), objStructureElement, objStructureElement) wp['d'].data = pymm.openrecth(pymm.to_int32(wp['d'].data), objStructureElement, objStructureElement) wp['a'].data = 0.5 * wp['a'].data # reconstruction wp.reconstruct(update=True) # top-hat for reconstructed image objtophat = pymm.openrecth(pymm.to_int32(wp.data), objStructureElement, objStructureElement) # y = mean + k*std (minValue, maxValue, meanValue, stdValue) = objImg.GetRasterBand(1).GetStatistics(0, 1) if (nRasterCount == 3): (minValue2, maxValue2, meanValue2, stdValue2) = objImg.GetRasterBand(2).GetStatistics(0, 1) (minValue3, maxValue3, meanValue3, stdValue3) = objImg.GetRasterBand(3).GetStatistics(0, 1) meanValue = 0.2989 * meanValue + 0.5870 * meanValue2 + 0.1140 * meanValue3 maxValue = 0.2989 * maxValue + 0.5870 * maxValue2 + 0.1140 * maxValue3 # meanValue = 438 # maxValue = 2047 threshad = meanValue + iThresh_coeff * stdValue objTent = pymm.threshad(objtophat, stdValue, maxValue) data_list = [] data_list.append(objTent) WriteOutputImage(strOutputFile, 1, data_list, 0, 0, 0, strInputFile)
def tentDetection_MM(strInputFile, maxTentArea, strOutputFile, strShape='box', iThresh_coeff=0): # five step to do this # 1. opening-determine the square structure element (6-60 m2/resolution) # 2. opening by reconstruction # 3. top-hat by reconstruction # 4. lower threshold # 5. double threshold import pymorph as pymm objImg = osgeo.gdal.Open(strInputFile, GA_ReadOnly) nRasterCount = objImg.RasterCount poDataset = objImg.ReadAsArray().astype(np.float) geotransform = objImg.GetGeoTransform() pixelWidth = np.fabs(geotransform[1]) pixelHeight = np.fabs(geotransform[5]) resolution = pixelWidth * pixelHeight # NoDataValue = objImg.GetRasterBand(1).GetNoDataValue() # gray scale image if (nRasterCount == 1): objnImg = pymm.to_int32(poDataset) # RGB image elif(nRasterCount == 3): objnImg = pymm.to_gray(poDataset) else: print 'it only supports gray-scale or RGB image' sys.exit(1) # determine the structure element iNum = int(np.sqrt(maxTentArea) / resolution) + 1 if (strShape == 'box'): objStructureElement = pymm.sebox(iNum) elif (strShape == 'cross'): objStructureElement = pymm.secross(iNum) else: objStructureElement = pymm.sedisk(iNum) # opening objOpen = pymm.open(objnImg, objStructureElement) # opening by reconstruction objOpenRec = pymm.openrec(objOpen, objStructureElement, objStructureElement) objtophat = pymm.openrecth(objnImg, objStructureElement, objStructureElement) # objtophat = pymm.subm(objnImg, objOpenRec) # objTent = pymm.threshad(objtophat, 0.25 * objnImg, 0.40 * objnImg) # y = mean + k*std (minValue, maxValue, meanValue, stdValue) = objImg.GetRasterBand(1).GetStatistics(0, 1) if (nRasterCount == 3): (minValue2, maxValue2, meanValue2, stdValue2) = objImg.GetRasterBand(2).GetStatistics(0, 1) (minValue3, maxValue3, meanValue3, stdValue3) = objImg.GetRasterBand(3).GetStatistics(0, 1) meanValue = 0.2989 * meanValue + 0.5870 * meanValue2 + 0.1140 * meanValue3 maxValue = 0.2989 * maxValue + 0.5870 * maxValue2 + 0.1140 * maxValue3 # meanValue = 438 # maxValue = 2047 threshad = meanValue + iThresh_coeff * stdValue objTent = pymm.threshad(objtophat, threshad, maxValue) data_list = [] data_list.append(objTent) WriteOutputImage(strOutputFile, 1, data_list, 0, 0, 0, strInputFile) '''
def tentDetection_wt_mm(strInputFile, maxTentArea, strOutputFile, strShape='box', iThresh_coeff=0): import pywt import pymorph as pymm objImg = osgeo.gdal.Open(strInputFile, GA_ReadOnly) nRasterCount = objImg.RasterCount poDataset = objImg.ReadAsArray().astype(np.float) geotransform = objImg.GetGeoTransform() pixelWidth = np.fabs(geotransform[1]) pixelHeight = np.fabs(geotransform[5]) resolution = pixelWidth * pixelHeight # NoDataValue = objImg.GetRasterBand(1).GetNoDataValue() # gray scale image if (nRasterCount == 1): objnImg = pymm.to_int32(poDataset) # RGB image elif (nRasterCount == 3): objnImg = pymm.to_gray(poDataset) else: print 'it only supports gray-scale or RGB image' sys.exit(1) # determine the structure element iNum = int(np.sqrt(maxTentArea) / resolution) + 1 if (strShape == 'box'): objStructureElement = pymm.sebox(iNum) elif (strShape == 'cross'): objStructureElement = pymm.secross(iNum) else: objStructureElement = pymm.sedisk(iNum) # decomposition until 1 level wp = pywt.WaveletPacket2D(data=objnImg, wavelet='db4', mode='sym', maxlevel=1) # iMaxLevel = wp.maxlevel() # top-hat wp['h'].data = pymm.openrecth(pymm.to_int32(wp['h'].data), objStructureElement, objStructureElement) wp['v'].data = pymm.openrecth(pymm.to_int32(wp['v'].data), objStructureElement, objStructureElement) wp['d'].data = pymm.openrecth(pymm.to_int32(wp['d'].data), objStructureElement, objStructureElement) wp['a'].data = 0.5 * wp['a'].data # reconstruction wp.reconstruct(update=True) # top-hat for reconstructed image objtophat = pymm.openrecth(pymm.to_int32(wp.data), objStructureElement, objStructureElement) # y = mean + k*std (minValue, maxValue, meanValue, stdValue) = objImg.GetRasterBand(1).GetStatistics(0, 1) if (nRasterCount == 3): (minValue2, maxValue2, meanValue2, stdValue2) = objImg.GetRasterBand(2).GetStatistics(0, 1) (minValue3, maxValue3, meanValue3, stdValue3) = objImg.GetRasterBand(3).GetStatistics(0, 1) meanValue = 0.2989 * meanValue + 0.5870 * meanValue2 + 0.1140 * meanValue3 maxValue = 0.2989 * maxValue + 0.5870 * maxValue2 + 0.1140 * maxValue3 # meanValue = 438 # maxValue = 2047 threshad = meanValue + iThresh_coeff * stdValue objTent = pymm.threshad(objtophat, stdValue, maxValue) data_list = [] data_list.append(objTent) WriteOutputImage(strOutputFile, 1, data_list, 0, 0, 0, strInputFile)
def correction_light(I, method, show_light, mask=None): """Corrige la derive eclairement :I: array_like ou iplimage :method: 'polynomial' or 'frequency' :show_light: option affiche correction (true|false) :mask: array de zone non interet :returns: iplimage 32bit """ from progress import * import Tkinter if type(I) == cv.iplimage: if I.nChannels == 3: if method == 'None': I = RGB2L(I) I = cv2array(I)[:, :, 0] I = pymorph.hmin(I, 15, pymorph.sedisk(3)) I = array2cv(I) cv.EqualizeHist(I, I) return I I = RGB2L(I) I_32bit = cv.CreateImage(cv.GetSize(I), cv.IPL_DEPTH_32F, 1) cv.ConvertScale(I, I_32bit, 3000.0, 0.0) I = cv.CloneImage(I_32bit) I = cv2array(I)[:, :, 0] elif len(I.shape) == 3: I = (I[:, :, 0] + I[:, :, 0] + I[:, :, 0])\ / 3.0 # A modifier: non utiliser dans notre cas elif method == 'None': I = array2cv(I) cv.EqualizeHist(I, I) return I I = np.log(I + 10 ** (-6)) (H, W) = np.shape(I) I_out = I * 0 + 10 ** (-6) if method == 'polynomial': ## I = M.A avec A coeff. du polynome I_flat = I.flatten() degree = 3 print("modification degree 3") #degree du polynome nb_coeff = (degree + 1) * (degree + 2) / 2 # nombre coefficient [yy, xx] = np.meshgrid(np.arange(W, dtype=np.float64), np.arange(H, dtype=np.float64)) if mask is not None: xx[mask] = 0 yy[mask] = 0 # Creation de M try: M = np.zeros((H * W, nb_coeff), dtype=np.float64) except MemoryError: print MemoryError return MemoryError i, j = 0, 0 # i,j degree de x,y #Bar progression bar = Tkinter.Tk(className='Correcting Light...') m = Meter(bar, relief='ridge', bd=3) m.pack(fill='x') m.set(0.0, 'Starting correction...') for col in np.arange(nb_coeff): M[:, col] = (xx.flatten() ** i) * (yy.flatten() ** j) i += 1 m.set(0.5 * float(col) / (nb_coeff - 1)) if i + j == degree + 1: i = 0 j += 1 # Resolution au sens des moindres carree: pseudo-inverse try: M = pl.pinv(M) A = np.dot(M, I_flat) except ValueError: return ValueError # Calcul de la surface i, j = 0, 0 surface = np.zeros((H, W), dtype=np.float64) for cmpt in np.arange(nb_coeff): surface += A[cmpt] * (xx ** i) * (yy ** j) # forme quadratique i += 1 m.set(0.5 + 0.5 * float(cmpt) / (nb_coeff - 1)) if i + j == degree + 1: i = 0 j += 1 bar.destroy() I_out = np.exp(I / surface) light = surface elif method == 'frequency': Rx, Ry = 2, 2 # zero padding N = [H, W] filtre = np.zeros((N[1], N[0])) centre_x = round(N[0] / 2) centre_y = round(N[1] / 2) print("FFT2D...") I_fourier = pl.fftshift(pl.fft2(I, N)) # Gaussian filter [xx, yy] = np.meshgrid(np.arange(N[0], dtype=np.float), np.arange(N[1], dtype=np.float)) filtre = np.exp(-2 * ((xx - centre_x) ** 2 + (yy - centre_y) ** 2) / (Rx ** 2 + Ry ** 2)) filtre = pl.transpose(filtre) I_fourier = I_fourier * filtre print("IFFT2D...") I_out = (np.abs(pl.ifft2(pl.ifftshift(I_fourier), N)))[0:H, 0:W] light = I_out I_out = np.exp(I / I_out) else: light = I * 0 I_out = I # Display Light if show_light: light = ((light - light.min()) * 3000.0 / light.max()).astype('float32') light = array2cv(light) fig = pl.figure() pl.imshow(light) fig.show() I_out = (I_out - I_out.min()) * 3000.0 / I_out.max() I_out = I_out.astype('uint8') #chapeau haut de forme I_out = pymorph.hmin(I_out, 25, pymorph.sedisk(3)) #Conversion en iplimage et ajustement contraste gr = array2cv(I_out) cv.EqualizeHist(gr, gr) return gr
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
def subset(data, left=None, top=None, right=None, bottom=None, rows=None, cols=None, center=False, mask_corners=False): """ Subsets a DataArray Args: data (DataArray): The ``xarray.DataArray`` to subset. left (Optional[float]): The left coordinate. top (Optional[float]): The top coordinate. right (Optional[float]): The right coordinate. bottom (Optional[float]): The bottom coordinate. rows (Optional[int]): The number of output rows. cols (Optional[int]): The number of output rows. center (Optional[bool]): Whether to center the subset on ``left`` and ``top``. mask_corners (Optional[bool]): Whether to mask corners (*requires ``pymorph``). Returns: ``xarray.DataArray`` Example: >>> import geowombat as gw >>> >>> with gw.open('image.tif', chunks=512) as ds: >>> >>> ds_sub = gw.subset(ds, >>> left=-263529.884, >>> top=953985.314, >>> rows=2048, >>> cols=2048) """ if isinstance(right, int) or isinstance(right, float): cols = int((right - left) / data.gw.celly) if not isinstance(cols, int): logger.exception( ' The right coordinate or columns must be specified.') if isinstance(bottom, int) or isinstance(bottom, float): rows = int((top - bottom) / data.gw.celly) if not isinstance(rows, int): logger.exception( ' The bottom coordinate or rows must be specified.') x_idx = np.linspace(math.ceil(left), math.ceil(left) + (cols * abs(data.gw.cellx)), cols) + abs(data.gw.cellxh) y_idx = np.linspace(math.ceil(top), math.ceil(top) - (rows * abs(data.gw.celly)), rows) - abs(data.gw.cellyh) if center: y_idx += ((rows / 2.0) * abs(data.gw.celly)) x_idx -= ((cols / 2.0) * abs(data.gw.cellx)) ds_sub = data.sel(y=y_idx, x=x_idx, method='nearest') if mask_corners: if PYMORPH_INSTALLED: try: disk = da.from_array( pymorph.sedisk(r=int(rows / 2.0))[:rows, :cols], chunks=ds_sub.data.chunksize).astype('uint8') ds_sub = ds_sub.where(disk == 1) except: logger.warning( ' Cannot mask corners without a square subset.') else: logger.warning(' Cannot mask corners without Pymorph.') # Update the left and top coordinates transform = list(data.transform) transform[2] = x_idx[0] transform[5] = y_idx[0] # Align the coordinates to the target grid dst_transform, dst_width, dst_height = aligned_target( Affine(*transform), ds_sub.shape[1], ds_sub.shape[0], data.res) ds_sub.attrs['transform'] = dst_transform return ds_sub
import pymorph as m import mahotas from numpy import where, reshape image = mahotas.imread('B.png') # Load image b1 = image[:,:,0] < 100 # Make a binary image from the thresholded red channel b2 = m.erode(b1, m.sedisk(4)) # Erode to enhance contrast of the bridge b3 = m.open(b2,m.sedisk(4)) # Remove the bridge b4 = b2-b3 # Bridge plus small noise b5 = m.areaopen(b4,1000) # Remove small areas leaving only a thinned bridge b6 = m.dilate(b3)*b5 # Extend the non-bridge area slightly and get intersection with the bridge. #b6 is image of end of bridge, now find single points b7 = m.thin(b6, m.endpoints('homotopic')) # Narrow regions to single points. labelled = m.label(b7) # Label endpoints. x1, y1 = reshape(where(labelled == 1),(1,2))[0] x2, y2 = reshape(where(labelled == 2),(1,2))[0] outputimage = m.overlay(b1, m.dilate(b7,m.sedisk(5))) mahotas.imsave('output.png', outputimage)
def addCell(self, eventTuple): if self.maskOn: if self.data.ndim == 2: self.aveData = self.data.copy() else: self.aveData = self.data.mean(axis=2) x, y = eventTuple localValue = self.currentMask[x, y] print str(self.mode) + " " + "x: " + str(x) + ", y: " + str(y) + ", mask val: " + str(localValue) # ensure mask is uint16 self.currentMask = self.currentMask.astype("uint16") sys.stdout.flush() ########## NORMAL MODE if self.mode is None: if localValue > 0 and localValue != self.currentMaskNumber: print "we are altering mask at at %d, %d" % (x, y) # copy the old mask newMask = self.currentMask.copy() # make a labeled image of the current mask labeledCurrentMask = mahotas.label(newMask)[0] roiNumber = labeledCurrentMask[x, y] # set that ROI to zero newMask[labeledCurrentMask == roiNumber] = self.currentMaskNumber newMask = newMask.astype("uint16") self.listOfMasks.append(newMask) self.currentMask = self.listOfMasks[-1] elif localValue > 0 and self.data.ndim == 3: # update info panel labeledCurrentMask = mahotas.label(self.currentMask.copy())[0] roiNumber = labeledCurrentMask[x, y] self.updateInfoPanel(ROI_number=roiNumber) elif localValue == 0: xmin = int(x - self.diskSize) xmax = int(x + self.diskSize) ymin = int(y - self.diskSize) ymax = int(y + self.diskSize) sub_region_image = self.aveData[xmin:xmax, ymin:ymax].copy() # threshold = mahotas.otsu(self.data[xmin:xmax, ymin:ymax].astype('uint16')) # do a gaussian_laplacian filter to find the edges and the center g_l = nd.gaussian_laplace( sub_region_image, 1 ) # second argument is a free parameter, std of gaussian g_l = mahotas.dilate(mahotas.erode(g_l >= 0)) g_l = mahotas.label(g_l)[0] center = g_l == g_l[g_l.shape[0] / 2, g_l.shape[0] / 2] # edges = mahotas.dilate(mahotas.dilate(mahotas.dilate(center))) - center newCell = np.zeros_like(self.currentMask) newCell[xmin:xmax, ymin:ymax] = center newCell = mahotas.dilate(newCell) if self.useNMF: modes, thresh_modes, fit_data, this_cell, is_cell, nmf_limits = self.doLocalNMF(x, y, newCell) for mode, mode_thresh, t, i in zip(modes, thresh_modes, this_cell, is_cell): # need to place it in the right place # have x and y mode_width, mode_height = mode_thresh.shape mode_thresh_fullsize = np.zeros_like(newCell) mode_thresh_fullsize[ nmf_limits[0] : nmf_limits[1], nmf_limits[2] : nmf_limits[3] ] = mode_thresh # need to add all modes belonging to this cell first, # then remove the ones nearby. if i: if t: valid_area = np.logical_and( mahotas.dilate( mahotas.dilate(mahotas.dilate(mahotas.dilate(newCell.astype(bool)))) ), mode_thresh_fullsize, ) newCell = np.logical_or(newCell.astype(bool), valid_area) else: newCell = np.logical_and( newCell.astype(bool), np.logical_not(mahotas.dilate(mode_thresh_fullsize)) ) newCell = mahotas.close_holes(newCell.astype(bool)) self.excludePixels(newCell, 2) newCell = newCell.astype(self.currentMask.dtype) # remove all pixels in and near current mask and filter for ROI size newCell[mahotas.dilate(self.currentMask > 0)] = 0 newCell = self.excludePixels(newCell, 10) newMask = (newCell * self.currentMaskNumber) + self.currentMask newMask = newMask.astype("uint16") self.listOfMasks.append(newMask.copy()) self.currentMask = newMask.copy() elif self.mode is "OGB": # build structuring elements se = pymorph.sebox() se2 = pymorph.sedisk(self.cellRadius, metric="city-block") seJunk = pymorph.sedisk(max(np.floor(self.cellRadius / 4.0), 1), metric="city-block") seExpand = pymorph.sedisk(self.diskSize, metric="city-block") # add a disk around selected point, non-overlapping with adjacent cells dilatedOrignal = mahotas.dilate(self.currentMask.astype(bool), Bc=se) safeUnselected = np.logical_not(dilatedOrignal) # tempMask is tempMask = np.zeros_like(self.currentMask, dtype=bool) tempMask[x, y] = True tempMask = mahotas.dilate(tempMask, Bc=se2) tempMask = np.logical_and(tempMask, safeUnselected) # calculate the area we should add to this disk based on % of a threshold cellMean = self.aveData[tempMask == 1.0].mean() allMeanBw = self.aveData >= (cellMean * float(self.contrastThreshold)) tempLabel = mahotas.label(np.logical_and(allMeanBw, safeUnselected).astype(np.uint16))[0] connMeanBw = tempLabel == tempLabel[x, y] connMeanBw = np.logical_and(np.logical_or(connMeanBw, tempMask), safeUnselected).astype(np.bool) # erode and then dilate to remove sharp bits and edges erodedMean = mahotas.erode(connMeanBw, Bc=seJunk) dilateMean = mahotas.dilate(erodedMean, Bc=seJunk) dilateMean = mahotas.dilate(dilateMean, Bc=seExpand) modes, thresh_modes, fit_data, this_cell, is_cell, limits = self.doLocaNMF(x, y) newCell = np.logical_and(dilateMean, safeUnselected) newMask = (newCell * self.currentMaskNumber) + self.currentMask newMask = newMask.astype("uint16") self.listOfMasks.append(newMask.copy()) self.currentMask = newMask.copy() ########## SQUARE MODE elif self.mode is "square": self.modeData.append((x, y)) if len(self.modeData) == 2: square_mask = np.zeros_like(self.currentMask) xstart = self.modeData[0][0] ystart = self.modeData[0][1] xend = self.modeData[1][0] yend = self.modeData[1][1] square_mask[xstart:xend, ystart:yend] = 1 # check if square_mask interfers with current mask, if so, abort if np.any(np.logical_and(square_mask, self.currentMask)): return None # add square_mask to mask newMask = (square_mask * self.currentMaskNumber) + self.currentMask newMask = newMask.astype("uint16") self.listOfMasks.append(newMask) self.currentMask = self.listOfMasks[-1] # clear current mode data self.clearModeData() ########## CIRCLE MODE elif self.mode is "circle": # make a strel and move it in place to make circle_mask if self.diskSize < 1: return None if self.diskSize is 1: se = np.ones((1, 1)) elif self.diskSize is 2: se = pymorph.secross(r=1) else: se = pymorph.sedisk(r=(self.diskSize - 1)) se_extent = int(se.shape[0] / 2) circle_mask = np.zeros_like(self.currentMask) circle_mask[x - se_extent : x + se_extent + 1, y - se_extent : y + se_extent + 1] = se * 1.0 circle_mask = circle_mask.astype(bool) # check if circle_mask interfers with current mask, if so, abort if np.any(np.logical_and(circle_mask, mahotas.dilate(self.currentMask.astype(bool)))): return None # add circle_mask to mask newMask = (circle_mask * self.currentMaskNumber) + self.currentMask newMask = newMask.astype("uint16") self.listOfMasks.append(newMask) self.currentMask = self.listOfMasks[-1] ########## POLY MODE elif self.mode is "poly": self.modeData.append((x, y)) sys.stdout.flush() self.makeNewMaskAndBackgroundImage()
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)
dapi = sio.imread(dapi_path) #cy3 = sio.imread(cy3_path) plb.imshow(dapi) plb.show() #============================================================================== # Segmentation #============================================================================== small = nd.zoom(dapi, 0.5) labelDAPI, n= nd.label(ex.LowResSegmentation(small)) obj = ex.extractParticles(small,labelDAPI) ex.makeMosaic(obj,20,10000) print n #broken = pymorph.sedisk() pixel_distance = 1 #se = np.array([[1,1,1],[1,1,1],[1,1,1]]) se = np.uint(pymorph.sedisk(pixel_distance)) #2+1+2=5 print se print 'find neighbours at ',pixel_distance, 'from particles' g = ng.findneighborhoods(labelDAPI, se) print 'converting to networkx' G = ng.convertToGraph(g, noBack=True) #============================================================================== # Graphic display #============================================================================== plb.subplot(121, frameon = False, xticks = [], yticks = []) plb.imshow(small) plb.subplot(122, frameon = False, xticks = [], yticks = []) plb.imshow(labelDAPI) plb.show() #plb.subplot(133) nx.draw_networkx(G)
dapi = sio.imread(dapi_path) #cy3 = sio.imread(cy3_path) plb.imshow(dapi) plb.show() #============================================================================== # Segmentation #============================================================================== small = nd.zoom(dapi, 0.5) labelDAPI, n = nd.label(ex.LowResSegmentation(small)) obj = ex.extractParticles(small, labelDAPI) ex.makeMosaic(obj, 20, 10000) print n #broken = pymorph.sedisk() pixel_distance = 1 #se = np.array([[1,1,1],[1,1,1],[1,1,1]]) se = np.uint(pymorph.sedisk(pixel_distance)) #2+1+2=5 print se print 'find neighbours at ', pixel_distance, 'from particles' g = ng.findneighborhoods(labelDAPI, se) print 'converting to networkx' G = ng.convertToGraph(g, noBack=True) #============================================================================== # Graphic display #============================================================================== plb.subplot(121, frameon=False, xticks=[], yticks=[]) plb.imshow(small) plb.subplot(122, frameon=False, xticks=[], yticks=[]) plb.imshow(labelDAPI) plb.show() #plb.subplot(133) nx.draw_networkx(G)
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