def test_sereflect(): yield _brute_test, pymorph.secross() se = pymorph.secross() se[1, 1] = 1 # This makes it non-symmetric yield _brute_test, se se[2, 1] = 1 # This makes it non-symmetric yield _brute_test, se se = np.zeros((9, 9), bool) se[0, 4] = 1 yield _brute_test, se se = np.zeros((9, 9), bool) se[1, 1] = se[1, 2] = se[0, 4] = 1 yield _brute_test, se
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
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
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 infrec(f, g, Bc=None): if Bc is None: Bc = pymorph.secross() n = f.size return fast_conditional_dilate(f, g, Bc, n);
def areaclose(image): return pymorph.areaclose(image, 4, pymorph.secross())
def test_neg(): pymorph.neg(pymorph.secross()) == ~pymorph.secross()
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()
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 infrec(f, g, Bc=None): if Bc is None: Bc = pymorph.secross() n = f.size return fast_conditional_dilate(f, g, Bc, n)
def test_serot(): se = pymorph.secross() assert np.all(pymorph.serot(se, 90) == se) assert not np.all(pymorph.serot(se, 45) == se)
def test_labelflat(): assert np.all(pymorph.labelflat(pymorph.secross()) == pymorph.secross())
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 test_sesum(): assert np.all(pymorph.sesum(pymorph.secross(), 1) == pymorph.secross()) assert len(pymorph.sesum(pymorph.secross(), 0).shape) == 2
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 test_secross(): assert np.all(pymorph.secross() == np.array([[0,1,0],[1,1,1],[0,1,0]])) assert np.all(pymorph.secross(0) == np.array([[1]])) assert np.all(pymorph.secross(2).shape == (5,5)) assert np.all(pymorph.secross(9).shape == (2*9+1,2*9+1))