def findWatershedMask(img, mask): img_mask = findCells(img, mask, init_smooth_sigma, init_niblack_window_size, init_niblack_k) img_mask = mh.dilate(mh.dilate(img_mask), Bc=np.ones((1, 3), dtype=np.bool)) img_mask = sk.morphology.remove_small_objects(img_mask, min_size=4) return img_mask
def test_fast_binary(): # This test is based on an internal code decision: the fast code is only triggered for CARRAYs # Therefore, we test to see if both paths lead to the same result np.random.seed(34) for i in range(8): f = np.random.random((128, 128)) > .9 f2 = np.dstack([f, f, f]) SEs = [ np.ones((3, 3)), np.ones((5, 5)), np.array([[0, 1, 0], [0, 0, 0], [0, 0, 0]]), np.array([[0, 0, 0], [1, 0, 0], [0, 0, 0]]), np.array([[1, 0, 0], [1, 0, 0], [0, 0, 0]]), np.array([[1, 1, 1], [1, 1, 1], [1, 1, 0]]), np.array([[1, 1, 1], [0, 1, 1], [1, 1, 0]]), ] for Bc in SEs: assert np.all( mahotas.erode(f, Bc=Bc) == mahotas.erode(f2[:, :, 1], Bc=Bc)) # For dilate, the border conditions are different; # This is not great, but it's actually the slow implementation # which has the most unsatisfactory behaviour: assert np.all( mahotas.dilate(f, Bc=Bc)[1:-1, 1:-1] == mahotas.dilate( f2[:, :, 1], Bc=Bc)[1:-1, 1:-1])
def test_se_zeros(): np.random.seed(35) f = np.random.random((128, 128)) > .9 f2 = np.dstack([f, f, f]) mahotas.erode(f, np.zeros((3, 3))) mahotas.dilate(f, np.zeros((3, 3))) mahotas.erode(f2[:, :, 1], np.zeros((3, 3))) mahotas.dilate(f2[:, :, 1], np.zeros((3, 3)))
def test_se_zeros(): np.random.seed(35) f = np.random.random((128, 128)) > 0.9 f2 = np.dstack([f, f, f]) mahotas.erode(f, np.zeros((3, 3))) mahotas.dilate(f, np.zeros((3, 3))) mahotas.erode(f2[:, :, 1], np.zeros((3, 3))) mahotas.dilate(f2[:, :, 1], np.zeros((3, 3)))
def extract(self): '''Extracts neighbour features. Returns ------- pandas.DataFrame extracted feature values for each object in `label_image` ''' # Create an empty dataset in case no objects were detected logger.info('extract neighbour features') features = list() for obj in self.object_ids: pad = max(self.neighbour_distance, self.touching_distance) object_image = self._get_bbox_containing_neighbours(obj, pad) # dilate the current object object_image_dilate = mh.dilate(object_image == obj, Bc=mh.disk( self.neighbour_distance)) # mask the corresponding region of the label image object_image_mask = np.copy(object_image) object_image_mask[object_image_dilate == 0] = 0 object_image_mask[object_image == obj] = 0 neighbour_ids = np.unique(object_image_mask) unique_values = neighbour_ids[np.nonzero(neighbour_ids)].tolist() neighbour_count = len(unique_values) # save these unique values as a string if neighbour_count == 0: neighbour_string = '.' else: neighbour_string = '.'.join(str(x) for x in unique_values) # create an inverted image of the surrounding cells neighbours = np.zeros_like(object_image) for n in unique_values: neighbours += mh.dilate(object_image == n) # calculate the distance from each pixel of object to neighbours dist = ndi.morphology.distance_transform_edt( np.invert(neighbours > 0)) # select perimeter pixels whose distance to neighbours is # less than threshold touching distance perimeter_image = mh.bwperim(object_image == obj) dist[perimeter_image == 0] = 0 dist[dist > self.touching_distance] = 0 fraction_touching = np.count_nonzero(dist) / float( np.count_nonzero(perimeter_image)) values = [neighbour_count, neighbour_string, fraction_touching] features.append(values) return pd.DataFrame(features, columns=self.names, index=self.object_ids)
def recreate_dyn_bnd(label1, label2, r=10): amount = r / 2 dilated_label1 = np.array(label1) for i in range(amount): dilated_label1 = mh.dilate(dilated_label1) dilated_label2 = np.array(label2) for i in range(amount): dilated_label2 = mh.dilate(dilated_label2) dyn_bnd = np.logical_and(dilated_label1, dilated_label2) return dyn_bnd.astype(np.bool)
def start(_argv): args = parseArgv(_argv) # expand all system paths homepath = lambda pathy: os.path.expanduser(pathy) realpath = lambda pathy: os.path.realpath(homepath(pathy)) sharepath = lambda share, pathy: os.path.join(share, homepath(pathy)) GROWN = args['grow'] ROOTOUT = args['out'] TOP_DEEP = args['deep'] TILESIZE = args['size'] N_TOP_IDS = args['number'] + 1 DATA = realpath(args['ids']) IDS_OUT = sharepath(ROOTOUT, args['images']) # Count most spread or deep ids BIG_IDS, BIG_COUNTS = biggest.main(DATA, sharepath(ROOTOUT, 'spread_count.txt'), s=TILESIZE) DEEP_IDS, DEEP_COUNTS = deepest.main(DATA, sharepath(ROOTOUT, 'deep_count.txt'), s=TILESIZE) ALL_IDS = [BIG_IDS, DEEP_IDS][TOP_DEEP][-N_TOP_IDS:-1] if not os.path.exists(ROOTOUT): print ROOTOUT, 'must exist' return -1 if not os.path.exists(IDS_OUT): os.makedirs(IDS_OUT) def savepng(zpath, black): grey = black.astype(np.uint8) * 255 colorgrey = cv2.cvtColor(grey, cv2.COLOR_GRAY2RGB) cv2.imwrite(zpath, colorgrey) print 'wrote', zpath with h5py.File(DATA, 'r') as df: vol = df[df.keys()[0]] for zed in range(vol.shape[0]): zpath = os.path.join(IDS_OUT, str(zed + 1).zfill(5) + '.png') if os.path.exists(zpath): continue plane = vol[zed, :, :] black = np.zeros(plane.shape, dtype=np.bool) is_all_black = np.zeros(len(ALL_IDS), dtype=np.bool) for idin, idy in enumerate(ALL_IDS): idy_in_plane = plane == idy if (not np.any(idy_in_plane)): is_all_black[idin] = True continue black[idy_in_plane] = True if (not np.any(is_all_black)): savepng(zpath, black) continue for grow in range(GROWN): black = mh.dilate(black) savepng(zpath, black)
def findneighborhoods(label, neighborhood): ''' given a labelled image, should return the adjacency list of particles, for a given neighborhood: neighborhood=np.array([0,1,0],[1,1,1],[0,1,0]) The background (0), is kept as a particle neighbor No fancy indexing ''' #make the labels list labmax = label.max() #print labmax neighb_dic = { } # a dictionnary containing particle label as key and neighborhood for i in range(1, labmax + 1): mask = (label == i) #print mask dilated = mh.dilate(mask, neighborhood) neighbor = np.logical_and(dilated, np.logical_not(mask)) #print neighbor #============================================================================== # #Done without fancy indexing #============================================================================== flatlab = np.ndarray.flatten(label) flatneighborhood = np.ndarray.flatten(neighbor) flatneighbors = flatlab[flatneighborhood] flatneighbors.sort() #set is a trick so that each value of the neighborhoods is present only once neighb_dic[i] = set(flatneighbors) #print np.nonzero(flatneighbors) return neighb_dic
def findneighborhoods(label,neighborhood): ''' given a labelled image, should return the adjacency list of particles, for a given neighborhood: neighborhood=np.array([0,1,0],[1,1,1],[0,1,0]) The background (0), is kept as a particle neighbor No fancy indexing ''' #make the labels list labmax = label.max() #print labmax neighb_dic = {} # a dictionnary containing particle label as key and neighborhood for i in range(1,labmax+1): mask = (label ==i) #print mask dilated = mh.dilate(mask,neighborhood) neighbor = np.logical_and(dilated, np.logical_not(mask)) #print neighbor #============================================================================== # #Done without fancy indexing #============================================================================== flatlab = np.ndarray.flatten(label) flatneighborhood = np.ndarray.flatten(neighbor) flatneighbors = flatlab[flatneighborhood] flatneighbors.sort() #set is a trick so that each value of the neighborhoods is present only once neighb_dic[i] = set(flatneighbors) #print np.nonzero(flatneighbors) return neighb_dic
def predict(self, filenames_list): if not isinstance(filenames_list, list): raise Exception('Input list of files is not a list actually') rectangles = [] for filename in filenames_list: im = cv2.imread(filename) (h, w) = im[:, :, 0].shape ### PREPROCESS # Convert to HSV, yields better results than BGR if self.colorspace == 'hsv': im = cv2.cvtColor(im, cv2.COLOR_BGR2HSV) elif self.colorspace == 'lab': im = cv2.cvtColor(im, cv2.COLOR_BGR2LAB) elif self.colorspace == 'rgbn': im = (color.normalize_RGBratio(im) * 255).astype('uint8') # gets original image hist baseHist = hist.getHist(im) ### PROCESS # Perform region selection by histogram similarity. # Returns a mask on whole image hist.simHist(im, baseHist, stop=self.stop) ### POST # Erase smaller detected blobs kernel = np.ones((h // 51, h // 51), np.uint8) im = mahotas.erode(im[:, :, 0], kernel) im = mahotas.dilate(im, kernel) im = blob.largest_blob(im) ### Draw boundary rectangle rectangles.append(blob.bound_rect(im)) return rectangles
def border(W,Bc=None): ''' B, neighbours, border_id = border(Regs,Bc=None) Label the borders between regions. B[y,x] = border_id[r0,r1] if (y,x) is on the border between regions (r0,r1). neighbours is a dict : (region) -> (list of regions) -Input: Regs: A labeled image Bc: A structuring element (default: 3x3 cross) ''' bg = W.max() B = np.zeros_like(W) neighbours = defaultdict(set) border_id = defaultdict(xrange(1,W.max()**2).__iter__().next) for obji in xrange(1,W.max()): B_obji = (mahotas.dilate(W == obji,Bc)-(W==obji)) for neighbour in np.unique(W[B_obji]): if neighbour == 0 or neighbour == bg: continue a1,a2 = obji,neighbour if a2 < a1: a1,a2 = a2,a1 B[B_obji & (W==neighbour)] = border_id[a1,a2] neighbours[a1].add(a2) neighbours[a2].add(a1) return B, dict(neighbours), dict(border_id)
def create_fullContour_labels(): for purpose in ['train','validate','test']: img_search_string = '/media/vkaynig/Data1/Cmor_paper_data/labels/' + purpose + '/*.tif' img_files = sorted( glob.glob( img_search_string ) ) for img_index in xrange(np.shape(img_files)[0]): print 'reading image ' + img_files[img_index] + '.' label = mahotas.imread(img_files[img_index]) #membranes = np.logical_and(label[:,:,0]==0, label[:,:,1]==255) boundaries = label == -1 boundaries[0:-1,:] = np.logical_or(boundaries[0:-1,:], np.diff(label, axis=0)!=0) boundaries[:,0:-1] = np.logical_or(boundaries[:,0:-1], np.diff(label, axis=1)!=0) membranes = np.logical_or(boundaries, label[:,:]==0) shrink_radius=5 y,x = np.ogrid[-shrink_radius:shrink_radius+1, -shrink_radius:shrink_radius+1] disc = x*x + y*y <= (shrink_radius ** 2) non_membrane = 1-mahotas.dilate(membranes, disc) img_file_name = os.path.basename(img_files[img_index])[:-4]+ '.tif' outputPath = '/media/vkaynig/Data1/Cmor_paper_data/labels/' print 'writing image: ' + img_file_name mahotas.imsave(outputPath + 'background_fullContour/' + purpose + '/' + img_file_name, np.uint8(non_membrane*255)) mahotas.imsave(outputPath + 'membranes_fullContour/' + purpose + '/' + img_file_name, np.uint8(membranes*255))
def watershed_adjusted_membranes(img_file_name, img_membrane_file_name): print 'reading image ' + img_file_name img = mahotas.imread(img_file_name) label_img = mahotas.imread(img_membrane_file_name) blur_img = scipy.ndimage.gaussian_filter(img, 1) #put boundaries as either extracellular/unlabeled space or gradient between two labeled regions into one image boundaries = label_img==0 boundaries[0:-1,:] = np.logical_or(boundaries[0:-1,:], np.diff(label_img, axis=0)!=0) boundaries[:,0:-1] = np.logical_or(boundaries[:,0:-1], np.diff(label_img, axis=1)!=0) #erode to be sure we include at least one membrane shrink_radius=4 y,x = np.ogrid[-shrink_radius:shrink_radius+1, -shrink_radius:shrink_radius+1] shrink_disc = x*x + y*y <= (shrink_radius ** 2) inside = mahotas.dilate(boundaries ==0, shrink_disc) #use watersheds to find the actual membranes (sort of) seeds = label_img.copy() seeds[np.nonzero(inside==0)] = 0 seeds,_ = mahotas.label(seeds == 0) wsImage = 255-np.uint8(scale_to_unit_interval(blur_img)*255) grow = mahotas.cwatershed(wsImage, seeds) membrane = np.zeros(img.shape, dtype=np.uint8) membrane[0:-1,:] = np.diff(grow, axis=0) != 0 membrane[:,0:-1] = np.logical_or(membrane[:,0:-1], np.diff(grow,axis=1) != 0) return np.uint8(membrane*255)
def create_fullContour_labels(): #img_search_string = '/media/vkaynig/NewVolume/IAE_ISBI2012/fullContours/I*_train.tif' img_search_string = '/media/vkaynig/NewVolume/Cmor_paper_data/labels/*.tif' img_files = sorted(glob.glob(img_search_string)) for img_index in xrange(np.shape(img_files)[0]): print 'reading image ' + img_files[img_index] + '.' label = mahotas.imread(img_files[img_index]) #membranes = np.logical_and(label[:,:,0]==0, label[:,:,1]==255) membranes = label[:, :] == 0 shrink_radius = 5 y, x = np.ogrid[-shrink_radius:shrink_radius + 1, -shrink_radius:shrink_radius + 1] disc = x * x + y * y <= (shrink_radius**2) non_membrane = 1 - mahotas.dilate(membranes, disc) #fileName = "/media/vkaynig/NewVolume/IAE_ISBI2012/fullContours/" fileName = "/media/vkaynig/NewVolume/Cmor_paper_data/labels/" fileName_label = fileName + ( img_files[img_index])[52:58] + "_fullContour.tif" fileName_background = fileName + ( img_files[img_index])[52:58] + "_background.tif" print 'writing image' + fileName_label mahotas.imsave(fileName_label, np.uint8(membranes * 255)) mahotas.imsave(fileName_background, np.uint8(non_membrane * 255))
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 watershed(Image_Current_T, CellDiam): #If there are pixels above the threshold proceed to watershed if Image_Current_T.max() == True: #Create distance transform from thresholded image to help identify cell seeds Image_Current_Tdist = mh.distance(Image_Current_T) Image_Current_Tdist[Image_Current_Tdist < CellDiam * 0.3] = 0 #Define Sure Background for watershed #Background is dilated proportional to cell diam. Allows final cell sizes to be a bit larger at end. #Will not affect cell number but can influence overlap #See https://docs.opencv.org/3.4/d3/db4/tutorial_py_watershed.html for tutorial that helps explain this Dilate_Iterations = int(CellDiam // 2) Dilate_bc = np.ones( (3, 3)) #Use square structuring element instead of cross Image_Current_SureBackground = Image_Current_T for j in range(Dilate_Iterations): Image_Current_SureBackground = mh.dilate( Image_Current_SureBackground, Bc=Dilate_bc) #Create seeds/foreground for watershed #See https://docs.opencv.org/3.4/d3/db4/tutorial_py_watershed.html for tutorial that helps explain this Regmax_bc = np.ones((CellDiam, CellDiam)) Image_Current_Seeds = mh.locmax(Image_Current_Tdist, Bc=Regmax_bc) Image_Current_Seeds[Image_Current_Tdist == 0] = False Image_Current_Seeds = mh.dilate(Image_Current_Seeds, np.ones((3, 3))) seeds, nr_nuclei = mh.label(Image_Current_Seeds, Bc=np.ones((3, 3))) Image_Current_Unknown = Image_Current_SureBackground.astype( int) - Image_Current_Seeds.astype(int) seeds += 1 seeds[Image_Current_Unknown == 1] = 0 #Perform watershed Image_Current_Watershed = mh.cwatershed( surface=Image_Current_SureBackground, markers=seeds) Image_Current_Watershed -= 1 #Done so that background value is equal to 0. Image_Current_Cells = Image_Current_Watershed #If there are no pixels above the threshold watershed procedure has issues. Set cell count to 0. elif Image_Current_T.max() == False: Image_Current_Cells = Image_Current_T.astype(int) nr_nuclei = 0 #return Image_Current_Seeds, nr_nuclei return Image_Current_Cells, nr_nuclei
def grab_neighbors(array, label): thresholded_array = Util.threshold(array, label) thresholded_array_dilated = mh.dilate(thresholded_array.astype(np.uint64)) all_neighbors = np.unique(array[thresholded_array_dilated == thresholded_array_dilated.max()].astype(np.uint64)) all_neighbors = np.delete(all_neighbors, np.where(all_neighbors == label)) return all_neighbors
def test_sum_minlength_arg(): for _ in range(8): f = mh.dilate(np.random.random_sample((64, 64)) > .8) labeled, n = mh.labeled.label(f) sizes = mh.labeled.labeled_sum(f, labeled) sizes2 = mh.labeled.labeled_sum(f, labeled, minlength=(n + 23)) assert len(sizes) == (n + 1) assert len(sizes2) == (n + 23) assert np.all(sizes == sizes2[:n + 1])
def mask_and_dilation(mask_path): """ :param mask_path: :return: """ mask = fits.open(mask_path)[0].data > 0 dil_mask = mh.dilate(mask > 0, Bc=np.ones((5, 5), dtype=bool)) return mask, dil_mask
def test_dilate_1(): A = np.zeros((16,16), dtype=np.uint8) B = np.array([ [0,1,0], [2,2,1], [1,3,0]], dtype=np.uint8) A[8,8] = 1 D = mahotas.dilate(A, B) assert np.sum(D) == np.sum(B+(B>0))
def test_sum_minlength_arg(): for _ in range(8): f = mh.dilate(np.random.random_sample((64,64)) > .8) labeled, n = mh.labeled.label(f) sizes = mh.labeled.labeled_sum(f, labeled) sizes2 = mh.labeled.labeled_sum(f, labeled, minlength=(n+23)) assert len(sizes) == (n+1) assert len(sizes2) == (n+23) assert np.all(sizes == sizes2[:n+1])
def test_dilate_erode(): A = np.zeros((128, 128), dtype=bool) Bc = np.array([[0, 1, 0], [1, 1, 1], [0, 1, 0]], bool) A[32, 32] = True origs = [] for i in range(12): origs.append(A.copy()) A = mahotas.dilate(A, Bc) for i in range(12): A = mahotas.erode(A, Bc) assert np.all(A == origs[-i - 1])
def UpdateImage(self): sigma = self.Slider_Sigma.value()/2; dilate = self.Slider_Dilate.value() if self.Combo_ImageType.currentText() == 'DAPI': if self.Check_NoisyMode.isChecked(): self.DAPI_mask = mh.dilate(self.img_array > self.T_mean, np.ones((dilate, dilate))); self.gaussian_f = mh.gaussian_filter(self.img_array.astype('int'), sigma) else: self.gaussian_f = mh.gaussian_filter(self.img_array.astype('float'), sigma) self.DAPI_mask = mh.dilate(self.gaussian_f > self.gaussian_f.mean(), np.ones((dilate, dilate))); if self.Check_SingleColor.isChecked(): self.im_axes.imshow(mh.as_rgb(0, 0, self.DAPI_mask)); else: plt.imshow(mh.as_rgb(np.maximum(self.img_array,self.gaussian_f), self.gaussian_f, self.gaussian_f > self.T_otsu)) self.ClusterMap.setupUi(figure=self.im_figure, title='Image Display', xlabel='pixels (x)', ylabel='pixels(y)') self.Button_SNR.setEnabled(False); self.Check_TissueMaxima.setEnabled(False); self.DAPI_set_bool = True self.Text_Log.append('>Updated image; DAPI; sigma=%.1f,dilate=%d\n' % (sigma, dilate)) elif self.Combo_ImageType.currentText() == 'Fluorescence (Signal)': self.gaussian_f = mh.gaussian_filter(self.img_array.astype('float'), sigma) self.gT_mean = self.gaussian_f.mean() all_maximas = mh.regmax(self.gaussian_f) self.all_maximas = mh.dilate(all_maximas, np.ones((dilate, dilate))) if self.Check_TissueMaxima.isChecked(): self.tissue_maxima = self.all_maximas*self.Tissue_Mask self.im_axes.imshow(mh.as_rgb( np.maximum(255*self.tissue_maxima, self.gaussian_f), self.gaussian_f, self.img_array > self.gT_mean)) else: self.im_axes.imshow(mh.as_rgb( np.maximum(255*self.all_maximas, self.gaussian_f), self.gaussian_f, self.img_array > self.gT_mean)) self.ClusterMap.setupUi(figure=self.im_figure, title='Image Display', xlabel='pixels (x)', ylabel='pixels(y)') self.Text_Log.append('>Updated image; Mode: Fluor; sigma=%.1f,dilate=%d\n' % (sigma, dilate)) if self.DAPI_set_bool: self.Button_SNR.setEnabled(True); self.Check_TissueMaxima.setEnabled(True)
def split(image, array, label): ''' ''' large_label = Util.threshold(array, label) label_bbox = mh.bbox(large_label) label = large_label[label_bbox[0]:label_bbox[1], label_bbox[2]:label_bbox[3]] image = image[label_bbox[0]:label_bbox[1], label_bbox[2]:label_bbox[3]] # # smooth the image # image = mh.gaussian_filter(image, 3.5) grad_x = np.gradient(image)[0] grad_y = np.gradient(image)[1] grad = np.add(np.abs(grad_x), np.abs(grad_y)) #grad = np.add(np.abs(grad_x), np.abs(grad_y)) grad -= grad.min() grad /= grad.max() grad *= 255 grad = grad.astype(np.uint8) #imshow(grad) # we need 4 labels as output max_label = 0 #while max_label!=3: coords = zip(*np.where(label == 1)) seed1 = random.choice(coords) seed2 = random.choice(coords) seeds = np.zeros(label.shape, dtype=np.uint64) seeds[seed1] = 1 seeds[seed2] = 2 # imshow(seeds) for i in range(10): seeds = mh.dilate(seeds) ws = mh.cwatershed(grad, seeds) ws[label == 0] = 0 ws_relabeled = skimage.measure.label(ws.astype(np.uint64)) max_label = ws_relabeled.max() #print max_label large_label = np.zeros(large_label.shape, dtype=np.uint64) large_label[label_bbox[0]:label_bbox[1], label_bbox[2]:label_bbox[3]] = ws return large_label
def countCones(self): self.ConeCounts.SetRegionalMaxima(mh.regmax(self.params['curImage'])) s,ncones=mh.label(self.ConeCounts.RegionalMaxima) self.ConeCounts.SetSeeds(s) self.ConeCounts.SetNpoints(ncones) if self.params['min_cone_size'] > 0: mask = np.ones((self.params['min_cone_size'],self.params['min_cone_size'])) rm=mh.dilate(self.ConeCounts.RegionalMaxima,mask) self.ConeCounts.SetRegionalMaxima(mh.regmax(rm)) s,ncones = mh.label(self.ConeCounts.RegionalMaxima) self.ConeCounts.SetSeeds(s) self.ConeCounts.SetNpoints(ncones)
def test_fast_binary(): # This test is based on an internal code decision: the fast code is only triggered for CARRAYs # Therefore, we test to see if both paths lead to the same result np.random.seed(34) for i in xrange(8): f = np.random.random((128,128)) > .9 f2 = np.dstack([f,f,f]) SEs = [ np.ones((3,3)), np.ones((5,5)), np.array([ [0,1,0], [0,0,0], [0,0,0]]), np.array([ [0,0,0], [1,0,0], [0,0,0]]), np.array([ [1,0,0], [1,0,0], [0,0,0]]), np.array([ [1,1,1], [1,1,1], [1,1,0]]), np.array([ [1,1,1], [0,1,1], [1,1,0]]), ] for Bc in SEs: assert np.all(mahotas.erode(f,Bc=Bc) == mahotas.erode(f2[:,:,1],Bc=Bc)) # For dilate, the border conditions are different; # This is not great, but it's actually the slow implementation # which has the most unsatisfactory behaviour: assert np.all(mahotas.dilate(f,Bc=Bc)[1:-1,1:-1] == mahotas.dilate(f2[:,:,1],Bc=Bc)[1:-1,1:-1])
def test_dilate_erode(): A = np.zeros((100,100)) Bc = np.array([ [0, 1, 0], [1, 1, 1], [0, 1, 0]], bool) A[30,30] = 1 A = (A!=0) orig = A.copy() for i in xrange(12): A = mahotas.dilate(A, Bc) for i in xrange(12): A = mahotas.erode(A, Bc) assert np.all(A == orig)
def random_watershed(array, speed_image, border_seeds=False, erode=False): ''' ''' copy_array = np.array(array, dtype=np.bool) if erode: for i in range(10): copy_array = mh.erode(copy_array) seed_array = np.array(copy_array) if border_seeds: seed_array = mh.labeled.border(copy_array, 1, 0, Bc=mh.disk(7)) coords = zip(*np.where(seed_array==1)) if len(coords) == 0: # print 'err' return np.zeros(array.shape) seed1_ = None seed2_ = None max_distance = -np.inf for i in range(10): seed1 = random.choice(coords) seed2 = random.choice(coords) d = distance.euclidean(seed1, seed2) if max_distance < d: max_distance = d seed1_ = seed1 seed2_ = seed2 seeds = np.zeros(array.shape, dtype=np.uint8) seeds[seed1_[0], seed1_[1]] = 1 seeds[seed2_[0], seed2_[1]] = 2 for i in range(8): seeds = mh.dilate(seeds) # Util.view(seeds,large=True) # print speed_image.shape, seeds.shape ws = mh.cwatershed(speed_image, seeds) ws[array == 0] = 0 return ws
def grab_neighbors(array, label): thresholded_array = Util.threshold(array, label) thresholded_array_dilated = mh.dilate( thresholded_array.astype(np.uint64)) copy = np.array(array) copy[thresholded_array_dilated != thresholded_array_dilated.max()] = 0 copy[thresholded_array == 1] = 0 copy_hist = Util.get_histogram(copy.astype(np.uint64)) copy_hist[0] = 0 # ignore zeros # copy_hist[label] = 0 # ignore ourselves return np.where(copy_hist > 0)[0]
def geodesic_reconstruction_1d(f, g): new = np.copy(f) while True: old = np.copy(new) print "old", old new = mahotas.dilate(g, np.asarray([1])) print "new", new changed = False for i in range(len(g)): new[i] = min(new[i], f[i]) if new[i] != old[i]: changed = True print "newnew", new if not changed: break print "---" print new
def dark_watershed(image, seed_image, threshold=50., dilate=True): ''' ''' coords = zip(*np.where(seed_image == threshold)) print 'seeds:', len(coords) seeds = np.zeros(seed_image.shape, dtype=np.uint64) for c in coords: seeds[c[0], c[1]] = seeds.max() + 1 if dilate: for i in range(8): seeds = mh.dilate(seeds) ws = mh.cwatershed(image, seeds) return seeds, ws
def mahotas_clean_up_seg(input_jacobian, frame_num): import mahotas as mh dsk = mh.disk(7) thresh_r = 0.1 thresh_g = 1 size_cutoff = 200 thresholded_jacobian = (np.int32(np.log(1+input_jacobian[frame_num][0])>thresh_r)+\ np.int32(np.log(1+input_jacobian[frame_num][1])>thresh_g))>0 thresholded_jacobian = mh.close_holes(thresholded_jacobian) thresholded_jacobian = mh.erode(thresholded_jacobian, dsk) labeled = mh.label(thresholded_jacobian)[0] sizes = mh.labeled.labeled_size(labeled) too_small = np.where(sizes < size_cutoff) labeled = mh.labeled.remove_regions(labeled, too_small) thresholded_jacobian = labeled > 0 thresholded_jacobian = mh.dilate(thresholded_jacobian, dsk) return thresholded_jacobian
def mahotas_clean_up_seg(input_jacobian,frame_num): import mahotas as mh dsk = mh.disk(7) thresh_r = 0.1 thresh_g = 1 size_cutoff = 200 thresholded_jacobian = (np.int32(np.log(1+input_jacobian[frame_num][0])>thresh_r)+\ np.int32(np.log(1+input_jacobian[frame_num][1])>thresh_g))>0 thresholded_jacobian = mh.close_holes(thresholded_jacobian) thresholded_jacobian = mh.erode(thresholded_jacobian,dsk) labeled = mh.label(thresholded_jacobian)[0] sizes = mh.labeled.labeled_size(labeled) too_small = np.where(sizes < size_cutoff) labeled = mh.labeled.remove_regions(labeled, too_small) thresholded_jacobian = labeled>0 thresholded_jacobian = mh.dilate(thresholded_jacobian,dsk) return thresholded_jacobian
def show_segmentation_boundaries(input_image,seg_mask,frame_num,sizeX,sizeY): import mahotas as mh cmap = plt.get_cmap('gray') #outlines dsk = mh.disk(7) boundaries = mh.dilate(seg_mask,dsk)-seg_mask boundaries=boundaries>0 cmap_2_use = truncate_colormap(cmap,0.9,1) border2overlay = np.ma.masked_where(boundaries ==0, boundaries) x =mh.as_rgb(input_image[frame_num][0,:,:],input_image[frame_num][1,:,:],np.zeros((sizeY,sizeX))) x[:,:,1][x[:,:,1]>240]=240 x[:,:,0][x[:,:,0]>240]=240 slice2show = [slice(0,sizeY),slice(0,sizeX)] plt.imshow(x[slice2show]/np.array([240.,240.,1]).reshape(1,1,3)) plt.imshow(border2overlay[slice2show],cmap_2_use,alpha=0.8),plt.axis('off')
def test_grey_erode(): from mahotas.tests.pymorph_copy import erode as slow_erode from mahotas.tests.pymorph_copy import dilate as slow_dilate np.random.seed(334) for i in range(8): f = np.random.random_sample((128,128)) f *= 255 f = f.astype(np.uint8) B = (np.random.random_sample((3,3))*255).astype(np.uint8) B //= 4 fast = mahotas.erode(f,B) slow = slow_erode(f,B) # mahotas & pymorph use different border conventions. assert np.all(fast[1:-1,1:-1] == slow[1:-1,1:-1]) fast = mahotas.dilate(f,B) slow = slow_dilate(f,B) # mahotas & pymorph use different border conventions. assert np.all(fast[1:-1,1:-1] == slow[1:-1,1:-1])
def getMaximaImage(self): """returns an RGBA type array suitable for overlay""" r = self.params['display_cone_size'] + 1 #use this value for now.... #generate a circle mask [y,x] = np.ogrid[-r:r,-r:r] mask = x*x + y*y <= r if np.count_nonzero(self.ConeCounts.Seeds) != self.ConeCounts.nPoints: #Some regional maxima are not points #this is a slow function, only required for display self._filterMaxima() #pass newImg = np.zeros(self.ConeCounts.Seeds.shape + (4,),dtype=np.uint8) #create a new array of size orgImage but 4D newImg[:,:,1] = self.ConeCounts.Seeds > 0 newImg[:,:,1] = mh.dilate(newImg[:,:,1],mask) * 255 newImg[:,:,3][newImg[:,:,1]>0] = 1 return np.float64(newImg)
def test_grey_erode(): from mahotas.tests.pymorph_copy import erode as slow_erode from mahotas.tests.pymorph_copy import dilate as slow_dilate np.random.seed(334) for i in range(8): f = np.random.random_sample((128, 128)) f *= 255 f = f.astype(np.uint8) B = (np.random.random_sample((3, 3)) * 255).astype(np.uint8) B //= 4 fast = mahotas.erode(f, B) slow = slow_erode(f, B) # mahotas & pymorph use different border conventions. assert np.all(fast[1:-1, 1:-1] == slow[1:-1, 1:-1]) fast = mahotas.dilate(f, B) slow = slow_dilate(f, B) # mahotas & pymorph use different border conventions. assert np.all(fast[1:-1, 1:-1] == slow[1:-1, 1:-1])
def segment(fname): dna = mh.imread(fname) dna = dna[:,:,0] sigma = 12. dnaf = mh.gaussian_filter(dna, sigma) T_mean = dnaf.mean() bin_image = dnaf > T_mean labeled, nr_objects = mh.label(bin_image) maxima = mh.regmax(mh.stretch(dnaf)) maxima = mh.dilate(maxima, np.ones((5,5))) maxima,_ = mh.label(maxima) dist = mh.distance(bin_image) dist = 255 - mh.stretch(dist) watershed = mh.cwatershed(dist, maxima) watershed *= bin_image return watershed
def test_erode_dilate(self): binary = self.data.binary_img.astype(bool)[0] s = np.sum(binary) e = multi_erode(binary, 0) self.assertEqual(np.sum(e), s) eroded = multi_erode(binary, 1) self.assertLess(np.sum(eroded), s) self.assertArrayEqual(mh.erode(binary), eroded) dilated = multi_dilate(binary, 1) self.assertGreater(np.sum(dilated), s) self.assertArrayEqual(mh.dilate(binary), dilated) eroded = multi_erode(binary, 100) self.assertEqual(eroded.sum(), 0) dilated = multi_dilate(binary, 300) self.assertEqual(dilated.sum(), np.product(binary.shape))
def grab_neighbors(array, label): thresholded_array = Util.threshold(array, label) thresholded_array_dilated = mh.dilate( thresholded_array.astype(np.uint64)) all_neighbors = np.unique( array[thresholded_array_dilated == thresholded_array_dilated.max()].astype(np.uint64)) all_neighbors = np.delete(all_neighbors, np.where(all_neighbors == label)) # neighbors = {} # for n in all_neighbors: # border = mh.labeled.border(array, label, n) # border_xy = np.where(border==True) # neighbors[str(n)] = border_xy return all_neighbors
def show_segmentation_boundaries(input_image, seg_mask, frame_num, sizeX, sizeY): import mahotas as mh cmap = plt.get_cmap('gray') #outlines dsk = mh.disk(7) boundaries = mh.dilate(seg_mask, dsk) - seg_mask boundaries = boundaries > 0 cmap_2_use = truncate_colormap(cmap, 0.9, 1) border2overlay = np.ma.masked_where(boundaries == 0, boundaries) x = mh.as_rgb(input_image[frame_num][0, :, :], input_image[frame_num][1, :, :], np.zeros((sizeY, sizeX))) x[:, :, 1][x[:, :, 1] > 240] = 240 x[:, :, 0][x[:, :, 0] > 240] = 240 slice2show = [slice(0, sizeY), slice(0, sizeX)] plt.imshow(x[slice2show] / np.array([240., 240., 1]).reshape(1, 1, 3)) plt.imshow(border2overlay[slice2show], cmap_2_use, alpha=0.8), plt.axis('off')
def hemorrhages_detect(img): moat = moat_operator(img, sigma=5.0) show_image(moat); plt.axis('off'); plt.savefig('../presentation/pics/hemorrhages/1.png') m_clahe = skimage.exposure.equalize_adapthist(moat) m_med = mh.median_filter(m_clahe, Bc=np.ones((5, 5))) show_image(m_med); plt.axis('off'); plt.savefig('../presentation/pics/hemorrhages/2.png') threshold_global_otsu = skimage.filters.threshold_otsu(m_med) print 'Otsu threshold:', threshold_global_otsu segmented = m_med <= 0.9 * threshold_global_otsu show_image(segmented); plt.axis('off'); plt.savefig('../presentation/pics/hemorrhages/3.png') #vessels = od.detect_vessels_3(img) vessels = detect_vessels_3(m_med, one_channel_img=True, gabor_perc=88.0) vessels = skimage.morphology.remove_small_objects(vessels, min_size=150) segmented[mh.dilate(vessels, Bc=np.ones((10, 10)))] = False show_image(segmented); plt.axis('off'); plt.savefig('../presentation/pics/hemorrhages/4.png') segm_label = skimage.measure.label(segmented) segm_eccen = np.array(map(attrgetter('eccentricity'), skimage.measure.regionprops(segm_label + 1))) segm_area = cl_areas(segm_label) #segm_circ = cf.cl_circularity(segm_label) segm_filtered = leave_segments_by_mask(segm_label, (segm_eccen < 0.85) & (segm_area < 30000), replace_value=0) != 0 return segm_filtered
def segment_tissue2d(input_file, output_file, voxel_xy): # load image img = io.imread(input_file) # normalize image img = ndimage.median_filter(img, 3) img = img * 255. / img.max() ##segment kidney tissue sizefactor = 10. small = ndimage.interpolation.zoom( img, 1. / sizefactor) # scale the image to a smaller size imgf = ndimage.gaussian_filter(small, 3. / voxel_xy) # Gaussian filter median = np.percentile(imgf, 40) # 40-th percentile for thresholding kmask = imgf > median * 1.5 # thresholding kmask = mahotas.dilate(kmask, mahotas.disk(5)) kmask = mahotas.close_holes(kmask) # closing holes kmask = mahotas.erode(kmask, mahotas.disk(5)) * 255 # remove objects that are darker than 2*percentile l, n = ndimage.label(kmask) llist = np.unique(l) if len(llist) > 2: means = ndimage.mean(imgf, l, llist) bv = llist[np.where(means < median * 2)] ix = np.in1d(l.ravel(), bv).reshape(l.shape) kmask[ix] = 0 kmask = ndimage.interpolation.zoom(kmask, sizefactor) # scale back to normal size kmask = normalize(kmask) kmask = (kmask > mahotas.otsu(kmask.astype(np.uint8)) ) # remove artifacts of interpolation tifffile.imsave(output_file, img_as_ubyte(kmask), compress=5)
import readmagick import pymorph import mahotas dna = readmagick.readimg('dna-0.xcf[0]').max(2) dna2 = readmagick.readimg('dna-1.xcf[0]').max(2) borders = readmagick.readimg('dna-0.xcf[1]') borders = borders[:,:,0] > borders[:,:,1] for i in xrange(2): borders = mahotas.dilate(borders, np.ones((3,3))) readmagick.writeimg(pymorph.overlay(dna, borders), 'dna.png') readmagick.writeimg(pymorph.overlay(dna2, borders), 'dna2.png')
from pylab import imshow import mahotas wally = mahotas.imread('data/DepartmentStore.jpg') wfloat = wally.astype(float) r,g,b = wfloat.transpose((2,0,1)) w = wfloat.mean(2) pattern = np.ones((24,16), float) for i in xrange(2): pattern[i::4] = -1 v = mahotas.convolve(r-w, pattern) mask = (v == v.max()) mask = mahotas.dilate(mask, np.ones((48,24))) wally -= .8*wally * ~mask[:,:,None] imshow(wally)
def grab_patch(image, prob, segmentation, l, n, patch_size=(75, 75), skip_boundaries=False, sample_rate=1): borders = mh.labeled.border(segmentation, l, n) # # treat interrupted borders separately # borders_labeled = skimage.measure.label(borders) border_bbox = mh.bbox(borders) patch_centers = [] border_yx = indices = zip(*np.where(borders == 1)) if len(border_yx) < 2: return [] # always sample the middle point border_center = (border_yx[len(border_yx) / (2)][0], border_yx[len(border_yx) / (2)][1]) patch_centers.append(border_center) if sample_rate > 1 or sample_rate == -1: if sample_rate > len(border_yx) or sample_rate == -1: samples = 1 else: samples = len(border_yx) / sample_rate for i, s in enumerate(border_yx): if i % samples == 0: sample_point = s if distance.euclidean(patch_centers[-1], sample_point) < patch_size[0]: # sample to close # print 'sample to close', patch_centers[-1], sample_point continue patch_centers.append(sample_point) borders_w_center = np.array(borders.astype(np.uint8)) for i, c in enumerate(patch_centers): borders_w_center[c[0], c[1]] = 10 * (i + 1) # print 'marking', c, borders_w_center.shape # if debug: # fig = plt.figure(figsize=(5,5)) # fig.text(0,1,'\n\n\n\n\nAll borders '+str(l)+','+str(n))#+'\n\n'+str(np.round(_matrices[u], 2))) # plt.imshow(borders_labeled[border_bbox[0]:border_bbox[1], border_bbox[2]:border_bbox[3]], interpolation='nearest') # fig = plt.figure(figsize=(5,5)) # fig.text(0,1,'\n\n\n\n\nWith center(s) '+str(l)+','+str(n))#+'\n\n'+str(np.round(_matrices[u], 2))) # plt.imshow(borders_w_center[border_bbox[0]:border_bbox[1], border_bbox[2]:border_bbox[3]], interpolation='nearest')#, cmap='ocean') patches = [] for i, c in enumerate(patch_centers): # for border_center in patch_centers: # check if border_center is too close to the 4 edges new_border_center = [c[0], c[1]] if new_border_center[0] < patch_size[0] / 2: # print 'oob1', new_border_center # return None continue if new_border_center[0] + patch_size[0] / 2 >= segmentation.shape[0]: # print 'oob2', new_border_center # return None continue if new_border_center[1] < patch_size[1] / 2: # print 'oob3', new_border_center # return None continue if new_border_center[1] + patch_size[1] / 2 >= segmentation.shape[1]: # print 'oob4', new_border_center # return None continue # print new_border_center, patch_size[0]/2, border_center[0] < patch_size[0]/2 # continue bbox = [ new_border_center[0] - patch_size[0] / 2, new_border_center[0] + patch_size[0] / 2, new_border_center[1] - patch_size[1] / 2, new_border_center[1] + patch_size[1] / 2 ] ### workaround to not sample white border of probability map if skip_boundaries: if bbox[0] <= 33: continue if bbox[1] >= segmentation.shape[0] - 33: continue if bbox[2] <= 33: continue if bbox[3] >= segmentation.shape[1] - 33: continue # threshold for label1 array1 = _metrics.Util.threshold(segmentation, l).astype(np.uint8) # threshold for label2 array2 = _metrics.Util.threshold(segmentation, n).astype(np.uint8) merged_array = array1 + array2 # dilate for overlap dilated_array1 = np.array(array1) dilated_array2 = np.array(array2) for o in range(10): dilated_array1 = mh.dilate(dilated_array1.astype(np.uint64)) dilated_array2 = mh.dilate(dilated_array2.astype(np.uint64)) overlap = np.logical_and(dilated_array1, dilated_array2) overlap[merged_array == 0] = 0 output = {} output['id'] = str(uuid.uuid4()) output['image'] = image[bbox[0]:bbox[1] + 1, bbox[2]:bbox[3] + 1] output['prob'] = prob[bbox[0]:bbox[1] + 1, bbox[2]:bbox[3] + 1] output['l'] = l output['n'] = n output['bbox'] = bbox output['border'] = border_yx output['border_center'] = new_border_center output['binary1'] = array1[bbox[0]:bbox[1] + 1, bbox[2]:bbox[3] + 1].astype(np.bool) # output['binary2'] = array2[bbox[0]:bbox[1] + 1, bbox[2]:bbox[3] + 1].astype(np.bool) output['overlap'] = overlap[bbox[0]:bbox[1] + 1, bbox[2]:bbox[3] + 1].astype(np.bool) output['borders_labeled'] = borders_labeled[ border_bbox[0]:border_bbox[1], border_bbox[2]:border_bbox[3]] output['borders_w_center'] = borders_w_center[ border_bbox[0]:border_bbox[1], border_bbox[2]:border_bbox[3]] patches.append(output) return patches
from pylab import imshow import numpy as np import mahotas wally = mahotas.imread('waldo.jpg') imshow(wally) wfloat = wally.astype(float) r,g,b = wfloat.transpose((2,0,1)) # split into rgb channels, better to use floats w = wfloat.mean(2) # w is the white channel pattern = np.ones((24,16),float) for i in xrange(2): pattern[i::4] = -1 # build a pattern of +1,+1,-1,-1 on vertical axis -> Wally's shirt. v = mahotas.convolve(r-w, pattern) # convolve red-white, will give strong response where shirt mask = (v == v.max()) mask = mahotas.dilate(mask,np.ones((48,24))) # look for max and dilate it to make it visible wally -= .8*wally * ~mask[:,:,None] imshow(wally)# imshow(wally)
def _classify(path, name, frames, channels, target, choices, CellObject): gnp.free_reuse_cache() #GPU TO USE, WE HAVE 2, I PREFER IF YOU'RE USING GPU 0 #whole images take up a lot of memory so we need to coordinate this. # if you're not using the notebook or a script make sure to shutdown or restart the notebook # you can use nvidia-smi in terminal to see what process are running on the GPU gnp._useGPUid = 0 #protein localization categories localizationTerms=['ACTIN', 'BUDNECK', 'BUDTIP', 'CELLPERIPHERY', 'CYTOPLASM', 'ENDOSOME', 'ER', 'GOLGI', 'MITOCHONDRIA', 'NUCLEARPERIPHERY', 'NUCLEI', 'NUCLEOLUS', 'PEROXISOME', 'SPINDLE', 'SPINDLEPOLE', 'VACUOLARMEMBRANE', 'VACUOLE'] #normalization values (don't need to change) norm_vals = np.load('/home/morphology/mpg4/OrenKraus/Data_Sets/Yeast_Protein_Localization/Yolanda_Chong/overal_mean_std_for_single_cell_crops_based_on_Huh.npz') #may change to better model (constatly training bgnumpy.track_memory_usage=Trueetter networks) model_path = '/home/okraus/mil_models_backup/mil_models/Yeast_Protein_Localization/Yeast_NAND_a_10_scratch_Dropout_v5_MAP_early_stopping_best_model.npz' #load model and set evaluation type (MIL convolves across whole images) #change size curImages, sizes = getImageData(path, frames, channels) curImages = normalize_by_constant_values(curImages,norm_vals['means'],norm_vals['stdevs']) sizeX=sizes[1] sizeY=sizes[0] nn = modelEvalFunctions.loadResizedModel(model_path,sizeY,sizeX) model = modelEvalFunctions.evaluateModel_MIL(nn,localizationTerms,outputLayer='loc') nn.ForwardProp({'X0':gnp.garray(curImages)}) # GET RATIOS OF CLASSES #values of prediction maps above pred_maps = nn._layers['MIL_pool'].Z[target-1].as_numpy_array() #calculate relative activation of each map area = pred_maps.sum(1).sum(1) / pred_maps.sum() #calculate absolute area of each map (optional) area2 = pred_maps.sum(1).sum(1) / (pred_maps.shape[1]*pred_maps.shape[2]) #plot relative activations per class, use area or area2 area_lib = {} jacobian = getJacobian(nn,frames) plt.imshow(jacobian[target-1,0]) loc = str(settings.MEDIA_ROOT + '/classes/' + name.split('.')[0]+"_FULL0") save(loc) mahotas_segmentation = mahotas_clean_up_seg(jacobian,target-1) plt.imshow(mahotas_segmentation) loc = str(settings.MEDIA_ROOT + '/classes/' + name.split('.')[0]+"_FULL1") save(loc) show_segmentation_boundaries(curImages,mahotas_segmentation,target-1,sizeX, sizeY) loc = str(settings.MEDIA_ROOT + '/classes/' + name.split('.')[0]+"_FULL2") save(loc) top5indices = np.argsort(area)[::-1][:5] del jacobian del mahotas_segmentation for i in range(len(localizationTerms)): if i in top5indices: area_lib[localizationTerms[i]] = area[i] jacobian_per_class = getJacobian_per_class(nn,i,frames) im2show = mahotas_clean_up_seg(jacobian_per_class, target-1) overlay(curImages,im2show,target-1,sizeX, sizeY) loc = str(settings.MEDIA_ROOT + '/classes/' + name.split('.')[0]+"_"+localizationTerms[i]) save(loc) np.save(loc, im2show) continue if localizationTerms[i] not in choices: continue area_lib[localizationTerms[i]] = area[i] jacobian_per_class = getJacobian_per_class(nn,i,frames)[target-1] im2show = np.int8(np.log(1+jacobian_per_class[0])>0.1+np.int8(np.log(1+jacobian_per_class[1])>1))>0 im2show = mh.dilate(mh.dilate(mh.dilate(mh.erode(mh.erode(mh.erode(im2show>0)))))) overlay(curImages,im2show,target-1,sizeX, sizeY) loc = str(settings.MEDIA_ROOT + '/classes/' + name.split('.')[0]+"_"+localizationTerms[i]) save(loc) np.save(loc, im2show) del nn del model gnp.free_reuse_cache() f = [['Class', 'Area']] for key in area_lib: f.append([str(key), area_lib[key]]) CellObject.activations = f CellObject.save() from openpyxl import Workbook wb = Workbook() ws = wb.active for arr in f: ws.append(arr) wb.save(settings.MEDIA_ROOT + '/classes/' + name.split('.')[0] + '.xlsx') if CellObject.email != '': send_mail('Deep Cell Vision', 'Your image has been classified. Go to http://deepcellvision.com/results/' +CellObject.name + ' to see your results' , '*****@*****.**', [CellObject.email], fail_silently=False) return
# This code is supporting material for the book # Building Machine Learning Systems with Python # by Willi Richert and Luis Pedro Coelho # published by PACKT Publishing # # It is made available under the MIT License from matplotlib import pyplot as plt import numpy as np import mahotas as mh image = mh.imread('../1400OS_10_01.jpeg') image = mh.colors.rgb2gray(image, dtype=np.uint8) image = image[::4, ::4] thresh = mh.sobel(image) filtered = mh.sobel(image, just_filter=True) thresh = mh.dilate(thresh, np.ones((7, 7))) filtered = mh.dilate(mh.stretch(filtered), np.ones((7, 7))) h, w = thresh.shape canvas = 255 * np.ones((h, w * 2 + 64), np.uint8) canvas[:, :w] = thresh * 255 canvas[:, -w:] = filtered mh.imsave('../1400OS_10_09+.jpg', canvas)
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 doLocalNMF(self, x, y, roi, n_comp=7, diskSizeMultiplier=3): # do NMF decomposition n = NMF(n_components=n_comp, tol=1e-1) xmin_nmf = max(0, int(x - self.diskSize * diskSizeMultiplier)) xmax_nmf = min(int(x + self.diskSize * diskSizeMultiplier), self.data.shape[0]) ymin_nmf = max(0, int(y - self.diskSize * diskSizeMultiplier)) ymax_nmf = min(int(y + self.diskSize * diskSizeMultiplier), self.data.shape[1]) xcenter_nmf = (xmax_nmf - xmin_nmf) / 2 ycenter_nmf = (ymax_nmf - ymin_nmf) / 2 reshaped_sub_region_data = self.data_white[xmin_nmf:xmax_nmf, ymin_nmf:ymax_nmf, :].reshape( xmax_nmf - xmin_nmf * ymax_nmf - ymin_nmf, self.data.shape[2] ) n.fit(reshaped_sub_region_data - reshaped_sub_region_data.min()) transformed_sub_region_data = n.transform(reshaped_sub_region_data - reshaped_sub_region_data.min()) modes = transformed_sub_region_data.reshape(xmax_nmf - xmin_nmf, ymax_nmf - ymin_nmf, n_comp).copy() modes = [m for m in np.rollaxis(modes, 2, 0)] params = [] this_cell = [] is_cell = [] thresh_modes = [] fit_data = [] for i, mode in enumerate(modes): # threshold mode uint16_mode = (mode / mode.max() * 2 ** 16).astype("uint16") uint16_mode = mahotas.dilate(mahotas.erode(uint16_mode)) uint16_mode = nd.gaussian_filter(uint16_mode, 1) thresh_mode = uint16_mode > mahotas.otsu(uint16_mode) # exclude all pixels less than 75% of typical size smallest_roi = 0.75 * self.diskSize * self.diskSize * np.pi thresh_mode = self.excludePixels(thresh_mode, smallest_roi).astype(int) thresh_modes.append(thresh_mode) # thresh_mode = (mode.astype('uint16') > mahotas.otsu(mode.astype('uint16'))).astype(int) # fit thresholded mode fit_parameters = self.fitgaussian(thresh_mode) fit_height, fit_xcenter, fit_ycenter, fit_xwidth, fit_ywidth = fit_parameters params.append(fit_parameters) # is cell-like? if 1 <= np.abs(fit_xwidth) <= 2 * self.diskSize and 1 <= np.abs(fit_ywidth) <= 2 * self.diskSize: if 0.02 <= thresh_mode.sum() / float(thresh_mode.size) <= 0.40: is_cell.append(True) else: is_cell.append(False) else: is_cell.append(False) # is this cell? if ( np.linalg.norm(np.array([xcenter_nmf, ycenter_nmf]) - np.array([fit_xcenter, fit_ycenter])) < self.diskSize * 1.5 ): this_cell.append(True) else: this_cell.append(False) fit_gaussian = self.gaussian(*fit_parameters) xcoords = np.mgrid[0 : xmax_nmf - xmin_nmf, 0 : ymax_nmf - ymin_nmf][0] ycoords = np.mgrid[0 : xmax_nmf - xmin_nmf, 0 : ymax_nmf - ymin_nmf][1] fit_data.append(fit_gaussian(xcoords, ycoords)) # print 'this cell', this_cell # print 'is cell', is_cell # print ' ' return ( modes, thresh_modes, fit_data, np.array(this_cell), np.array(is_cell), (xmin_nmf, xmax_nmf, ymin_nmf, ymax_nmf), )
def test_dilate_slice(): np.random.seed(30) for i in range(16): f = (np.random.random_sample((256,256))*255).astype(np.uint8) assert np.all(mahotas.dilate(f[:3,:3]) == mahotas.dilate(f[:3,:3].copy()))
def python_nuvolatools(timg, tdrawable, mangaoptype=0, lowlevelnumber=0, highlevelnumber=255, samplethreshold=90, minblobarea=1, maxblobarea=10, otsuon=0, fancyproc=0, cbrregistry=0, numberOfDilations=1): ####CBR Registry section ###note CBR registry is meant to become a very compact way of specifying multiple values (i.e. for multiple operations, even as binary values) and should be processed in this section to initialize the necessary variables. This has priority over everything else passed as arguments to the present function ####variables init width = tdrawable.width height = tdrawable.height swidth = tdrawable.mask_bounds[2] - tdrawable.mask_bounds[0] sheight = tdrawable.mask_bounds[3] - tdrawable.mask_bounds[1] soffsetX = tdrawable.mask_bounds[0] soffsetY = tdrawable.mask_bounds[1] sselectionBox = tdrawable.mask_bounds shapedetfillratio = 0.0 shapedetfillrange = 0.0 shapedethwratio = 0.0 shapedethwrange = 0.0 shapeselectex = 1 shapeinvertpic = 0 radiusoperation = 0 radiuspixel = 1 uniqueExtension = "" if ((cbrregistry & 16)== 16): dateNow = datetime.datetime.now() uniqueExtension = str(time.mktime(dateNow.timetuple())) if ((mangaoptype==2) or (mangaoptype==3) or (mangaoptype==4)): if ((cbrregistry & 4)== 4): extradata = readdialogdatafromshm() root = Tk() if ((cbrregistry & 4)!= 4): d = MyDialog(root) extradata = d.result print "Extra parameters input result:", extradata print "EXTRA PARAMETERS RAW", extradata shapedetfillratio = float(extradata[0]) shapedethwratio = float(extradata[1]) shapedetfillrange = float(extradata[2]) shapedethwrange = float(extradata[3]) shapeselectex = int(extradata[4]) shapeinvertpic = int(extradata[5]) radiusoperation = int(extradata[6]) radiuspixel = int(extradata[7]) #basically, invertpic means setting the whitepores operation... so: # (shapeinvertpic) complements the whitepores condition ~_~ scropBox = (swidth,sheight,soffsetX,soffsetY) ####creating work image (currently the imgg is NOT USED) imgg = gimp.Image(width, height, GRAY) imgg.disable_undo() layer_imgg = gimp.Layer(imgg, "work layer", width, height, GRAY_IMAGE, 100, NORMAL_MODE) layer_imgg.add_alpha() imgg.add_layer(layer_imgg, 0) pdb.gimp_image_crop(imgg,swidth,sheight,soffsetX,soffsetY) ##pdb.gimp_edit_copy(tdrawable) ##imggpastelayer = pdb.gimp_edit_paste(layer_imgg, True) ##imgg.add_layer(imggpastelayer, 1) ##imggreturnlayer = pdb.gimp_image_flatten(imgg) wdrawable = tdrawable.copy() if (fancyproc): timg.add_layer(wdrawable, 0) wdrawable.add_alpha() pdb.gimp_layer_set_name(wdrawable,"nuvola work layer") #### FANCY OPERATIONS (work layer) if (fancyproc): ### this is a preset known to work well for me ~_~ ...doing two passes! (I should make this optonal tho) ## excluding the gaussian blur, useless for now. #pdb.plug_in_gauss_rle(timg, wdrawable, maxblurrad***, 1, 1) #mablurrad will give error since this variable has been removed pdb.gimp_levels(wdrawable, 0, 0, highlevelnumber, 1, 0, 255) #first let's minimize the background pdb.plug_in_unsharp_mask(timg, wdrawable, 5, 0.5, 0) # only then, more crispness #pdb.plug_in_unsharp_mask(timg, wdrawable, 5, 0.5, 0) ###maybe this is excessive, let's comment it pdb.gimp_levels(wdrawable, 0, lowlevelnumber, 255, 1, 0, 255) #then, further darken the blacks pdb.plug_in_antialias(timg, wdrawable) # a touch of antialias~ ####conversion to numpy array #pdb.file_png_save(timg, tdrawable, "/dev/shm/"+uniqueExtension+"nuvolatools-pngtimgfile.png", "pngtimgfile.png", 0, 9, 1, 1, 1, 1, 1) #img = makenparrayfromfile("/dev/shm/"+uniqueExtension+"nuvolatools-pngtimgfile.png", sselectionBox, uniqueExtension) #pdb.file_gif_save(timg, tdrawable, "/dev/shm/"+uniqueExtension+"nuvolatools-pngtimgfile.gif", "pngtimgfile.gif", 0, 0, 0, 0) #img = makenparrayfromfile("/dev/shm/"+uniqueExtension+"nuvolatools-pngtimgfile.gif", sselectionBox, uniqueExtension) pdb.file_tiff_save(timg, tdrawable, "/dev/shm/"+uniqueExtension+"nuvolatools-pngtimgfile.tif", "pngtimgfile.tif", 1) print "calling nparrayfrom pngtimgfile" img = makenparrayfromfile("/dev/shm/"+uniqueExtension+"nuvolatools-pngtimgfile.tif", sselectionBox, uniqueExtension) #pdb.file_png_save(timg, wdrawable, "/dev/shm/"+uniqueExtension+"nuvolatools-wpngtimgfile.png", "wpngtimgfile.png", 0, 9, 1, 1, 1, 1, 1) #wimg = makenparrayfromfile("/dev/shm/"+uniqueExtension+"nuvolatools-wpngtimgfile.png", sselectionBox, uniqueExtension) <-- only if fancyproc if (fancyproc): print "calling nparrayfrom wpngtimgfile" pdb.file_tiff_save(timg, wdrawable, "/dev/shm/"+uniqueExtension+"nuvolatools-wpngtimgfile.tif", "wpngtimgfile.tif",1) wimg = makenparrayfromfile("/dev/shm/"+uniqueExtension+"nuvolatools-wpngtimgfile.tif", sselectionBox, uniqueExtension) #### thresholding and labeling imglabel, labelnum, imgbin, imgbinneg, img, imgneg, imgotsu, imgtosaveotsu, imgotsuneg = imagepreprocesslabel(img, mangaoptype, otsuon, samplethreshold, shapeinvertpic) if (fancyproc): wimglabel, wlabelnum, wimgbin, wimgbinneg, wimg, wimgneg, wimgotsu, wimgtosaveotsu, wimgotsuneg = imagepreprocesslabel(wimg, mangaoptype, otsuon, samplethreshold, shapeinvertpic) #### special for the shapedetector: we are actually using the work layer since it should give a much better shape separation if ((mangaoptype==2) and (fancyproc)): imglabel = wimglabel labelnum = wlabelnum imgbin = wimgbin imgbinneg = wimgbinneg img = wimg imgneg = wimgneg imgotsu = wimgotsu imgtosaveotsu = wimgtosaveotsu imgotsuneg = wimgotsuneg ####blob measurement via pymorph, parameter maxblobarea pdb.gimp_progress_set_text('Measuring specks sizes.. (may take some time)') imgblobdata = measurefromlabel(imglabel, tdrawable, fancyproc) print imgblobdata, len(imgblobdata) #len of data == number of labels, of course. #### speckles operation start if ((mangaoptype==0) or (mangaoptype==1)): #print "making measurement from labels" imgspeckles = img; #create a copy of the original nparray imgspecklesres = makefromlabel(imgbinneg, imgspeckles, imglabel, imgblobdata,minblobarea,maxblobarea,fancyproc, shapedetfillratio, shapedetfillrange, shapedethwratio, shapedethwrange, shapeselectex, radiusoperation, radiuspixel, mangaoptype, uniqueExtension) if (mangaoptype==2): imgspeckles = img; #create a copy of the original nparray ### for now, fancyproc is needed true if we want to match specific shapes fancyproc = True print "pre-call shape det parameters", shapedetfillratio, shapedetfillrange, shapedethwratio, shapedethwrange, shapeselectex, radiusoperation, radiuspixel imgspecklesres = makefromlabel(imgbinneg, imgspeckles, imglabel, imgblobdata,minblobarea,maxblobarea,fancyproc, shapedetfillratio, shapedetfillrange, shapedethwratio, shapedethwrange, shapeselectex, radiusoperation, radiuspixel, mangaoptype, uniqueExtension) #### Fancy operation: dilation #if (mangaoptype==1): # propagate_mode=1 print "processing dilations" for i in range(numberOfDilations): imgspecklesresdil = mahotas.dilate(imgspecklesres) imgspecklesres = imgspecklesresdil #### Fancy operation: thinning skeleton from mahotas when processing lineart print "thinning skeleton, this may take some minutes for very large pictures!" if ((fancyproc) and (mangaoptype == 3)): #if ((mangaoptype == 0)): minsegment=256 minoverlap=64 #if (not fancyproc): # wimgbinneg is not declared if fancyproc is false, so for debugging purposes we assign it # wimgbinneg = imgbinneg #preliminary results show a *less crisp* starting picture is MUCH desirable ~_~ wbinneglen=len(wimgbinneg) wbinneglenintparts=wbinneglen/minsegment wbinneglenintrem=wbinneglen-wbinneglenintparts*minsegment wbinnegindex=0 #wimgbinneg=mahotas.erode(wimgbinneg) ###this has a very positive effect of stabilizing certain aspects of the picture, however it's also altering it greatly. Commented for the time being. #wimgbinneg=mahotas.erode(wimgbinneg) print "processing segment at", wbinnegindex, "/",wbinneglen imgthin=mahotas.thin(wimgbinneg[wbinnegindex:wbinnegindex+minsegment]) wbinnegindex=wbinnegindex+minsegment while (wbinnegindex<=wbinneglen): pdb.gimp_progress_set_text("processing segment at "+str(wbinnegindex)+"/"+str(wbinneglen)) wbinnegindex=wbinnegindex-minoverlap ###makes it 25% more computationally expensive, but pays with no artifacts if (wbinnegindex+minsegment <= wbinneglen): imgthinpart=mahotas.thin(wimgbinneg[wbinnegindex:wbinnegindex+minsegment]) if (wbinnegindex+minsegment > wbinneglen): imgthinpart=mahotas.thin(wimgbinneg[wbinnegindex:]) #print imgthin[0] #print imgthinpart[0] imgthin=np.append(imgthin[0:wbinnegindex+minoverlap/2],imgthinpart[minoverlap/2:], axis=0) wbinnegindex=wbinnegindex+minsegment print "skeleton thinned" io.imsave('/dev/shm/'+uniqueExtension+'nuvolatools-imgthin.png', imgthin*255) ### a word of wisdom: this damn fails with "memory error" for VERY large pictures ~_~ ###skel, distance = medial_axis(wimgbinneg, return_distance=True) ###print "medialaxis done" ###skeldist=skel*distance ###io.imsave('/dev/shm/'+uniqueExtension+'nuvolatools-medialaxis2.png', skeldist) #### if whitepores = True or (shapeinvertpic), invert the picture if ((mangaoptype==1) or (shapeinvertpic)): imgnegres = pymorph.neg(imgspecklesres) imgspecklesres = imgnegres ####saving numpy intermediates #io.imsave('/dev/shm/'+uniqueExtension+'nuvolatools-imgtosaveotsu.png', imgtosaveotsu) #io.imsave('/dev/shm/'+uniqueExtension+'nuvolatools-imgbinneg.png', imgbinneg*255) io.imsave('/dev/shm/'+uniqueExtension+'nuvolatools-imgbin.png', imgbin*255) if (otsuon == 1): io.imsave('/dev/shm/'+uniqueExtension+'nuvolatools-imgotsuneg.png',imgotsuneg*255) io.imsave('/dev/shm/'+uniqueExtension+'nuvolatools-imglabel.png',imglabel) io.imsave('/dev/shm/'+uniqueExtension+'nuvolatools-imgspecklesres.png',imgspecklesres) ####creating spare GIMP layers layer_specks = gimp.Layer(timg, "negative specks", swidth, sheight, GRAY_IMAGE, 100, NORMAL_MODE) ####loading specks as layer layer_specks = pdb.gimp_file_load_layer(timg, '/dev/shm/'+uniqueExtension+'nuvolatools-imgspecklesres.png') #pdb.gimp_layer_add_alpha(layer_specks) timg.add_layer(layer_specks, 0) layer_specks.add_alpha() pdb.gimp_layer_set_name(layer_specks,"speckles remover") #### if whitepores = True or (shapeinvertpic), use the correct layer name if ((mangaoptype==1) or (shapeinvertpic)): pdb.gimp_layer_set_name(layer_specks,"white pores filler") print tdrawable.mask_bounds, tdrawable.mask_bounds[2]-tdrawable.mask_bounds[0], tdrawable.mask_bounds[3]-tdrawable.mask_bounds[1], tdrawable.mask_bounds[0], tdrawable.mask_bounds[1] #### removing background and publishing #layer_specks.resize(tdrawable.mask_bounds[2]-tdrawable.mask_bounds[0], tdrawable.mask_bounds[3]-tdrawable.mask_bounds[1], tdrawable.mask_bounds[0], tdrawable.mask_bounds[1]) pdb.gimp_by_color_select(layer_specks, gimpcolor.RGB(0,0,0), 0, CHANNEL_OP_REPLACE, False, False, 0, False) #### if whitepores = True, invert the selection if ((mangaoptype==1) or (shapeinvertpic)): pdb.gimp_by_color_select(layer_specks, gimpcolor.RGB(255,255,255), 0, CHANNEL_OP_REPLACE, False, False, 0, False) pdb.gimp_edit_clear(layer_specks) pdb.gimp_selection_none(timg) #print dir(layer_specks) #print dir(pdb) ##layer_two = layer_one.copy() ##layer_two.mode = MULTIPLY_MODE ##layer_two.name = "Y Dots" ##timg.add_layer(layer_two, 0) imgg.flatten() ##bump_layer = imgg.active_layer layer_specks.translate(soffsetX, soffsetY) ####sending back layers #layer_one.image = imgtosaveotsu #timg.add_layer(layer_one, 0) if ((cbrregistry & 1)== 1): wdrawable.add_alpha() pdb.gimp_selection_all(timg) print "matched cbr registry 1 -> clearing wdrawable" #pdb.gimp_drawable_delete(wdrawable) pdb.gimp_edit_clear(wdrawable) pdb.gimp_selection_none(timg) if ((cbrregistry & 2)== 2): print "saving current picture in xcf format" timgfilename=pdb.gimp_image_get_filename(timg) timgname=pdb.gimp_image_get_name(timg) print timgname, timgfilename timgfilenames=timgfilename+str(cbrregistry)+"op"+str(mangaoptype)+".xcf" timgnames=timgname+str(cbrregistry)+"op"+str(mangaoptype)+".xcf" print timgnames,timgfilenames pdb.gimp_xcf_save(2,timg,wdrawable,timgfilenames,timgnames) #pdb.file_xjt_save(timg,wdrawable,timgfilenames,timgnames,1,0,1,0) #pdb.gimp_file_save(timg,wdrawable,timgfilenames,timgnames) #### Final if ((cbrregistry & 8)== 8): os.system("rm -v /dev/shm/"+uniqueExtension+"nuvolatools-*") os.system("rm -f /dev/shm/"+uniqueExtension+"nuvolatools-*") gimp.delete(imgg)