def _check_fullresults(self): f = z5py.File(self.input_path) ds_inp = f[self.input_key] ds_inp.n_threads = 8 ds_ws = f[self.ws_key] ds_ws.n_threads = 8 seg = ds_ws[:] rag = nrag.gridRag(seg, numberOfLabels=int(seg.max()) + 1) inp = ds_inp[:] # compute nifty features features_nifty = nrag.accumulateEdgeStandartFeatures(rag, inp, 0., 1.) # load features features = z5py.File(self.output_path)[self.output_key][:] self.assertEqual(len(features_nifty), len(features)) self.assertEqual(features_nifty.shape[1], features.shape[1] - 1) # we can only assert equality for mean, std, min, max and len print(features_nifty[:10, 0]) print(features[:10, 0]) # -> mean self.assertTrue(np.allclose(features_nifty[:, 0], features[:, 0])) # -> std self.assertTrue(np.allclose(features_nifty[:, 1], features[:, 1])) # -> min self.assertTrue(np.allclose(features_nifty[:, 2], features[:, 2])) # -> max self.assertTrue(np.allclose(features_nifty[:, 8], features[:, 8])) self.assertFalse(np.allcose(features[:, 3:8], 0)) # check that the edge-lens agree len_nifty = nrag.accumulateEdgeMeanAndLength(rag, inp)[:, 1] self.assertTrue(np.allclose(len_nifty, features_block[:, -1]))
def compute_edge_features(rag, input_path, input_key, max_threads, calc_filter_2d=True): # hard coded features filter_list = [ ff.gaussianSmoothing, ff.laplacianOfGaussian, ff.hessianOfGaussianEigenvalues ] sigmas = [1.6, 4.2, 8.2] # load the data data = read_hdf5(input_path, input_key) features = [] # iterate over the filter, compute them and then accumulate feature responses over the edges for filtr_fu in filter_list: for sigma in sigmas: response = compute_2d_filter( filtr_fu, data, sigma, max_threads) if calc_filter_2d else filtr_fu(data, sigma) # for multichannel feature we need to accumulate over the channels if response.ndim == 3: features.append( nrag.accumulateEdgeStandartFeatures( rag, response, response.min(), response.max(), numberOfThreads=max_threads)) else: for c in range(response.shape[-1]): response_c = response[..., c] features.append( nrag.accumulateEdgeStandartFeatures( rag, response_c, response_c.min(), response_c.max(), numberOfThreads=max_threads)) features = np.concatenate(features, axis=1) return np.nan_to_num(features)
def edge_statistics_callback(rag, input_path, input_key, statistic, max_threads): stats_to_index = {'mean': 0, 'max': 8, 'median': 5, 'q75': 6, 'q90': 7} assert statistic in stats_to_index index = stats_to_index[statistic] data = read_hdf5(input_path, input_key) edge_probs = nrag.accumulateEdgeStandartFeatures( rag, data, data.min(), data.max(), numberOfThreads=max_threads)[:, index] return np.nan_to_num(edge_probs)
def forward(self, embeddings, sp_seg, affs, offs): # expecting first two args as N, C, D, H, W and third as 2, L. First should be l2-normalized w.r.t. C assert embeddings.ndim == sp_seg.ndim # get edge weights affs = affs[0] # bs must be 1 affs[self.sep_chnl:] *= -1 affs[self.sep_chnl:] += +1 rag = nrag.gridRag(sp_seg.squeeze(0).squeeze(0).long().cpu().numpy(), int(sp_seg.max()) + 1, numberOfThreads=1) edges = torch.from_numpy(rag.uvIds().astype(np.int)).to(affs.device).T hmap = (affs[0] + affs[1]) / 2 hmap = (hmap - hmap.min()).float() hmap = hmap / (hmap.max() + 1e-6) weights = torch.from_numpy( nrag.accumulateEdgeStandartFeatures(rag, hmap.cpu().numpy(), 0, 1, numberOfThreads=1)).to( affs.device) C = int(sp_seg.max()) + 1 mask = torch.zeros((C, ) + sp_seg.shape, dtype=torch.int8, device=sp_seg.device) mask.scatter_(0, sp_seg[None].long(), 1) masked_embeddings = mask * embeddings[None] n_pix_per_sp = mask.flatten(1).sum(1, keepdim=True) sp_means = masked_embeddings.transpose( 1, 2).flatten(2).sum(2) / n_pix_per_sp intra_sp_dist = self.distance(sp_means[..., None, None, None], masked_embeddings.transpose(1, 2), dim=1) intra_sp_dist = torch.clamp(intra_sp_dist - self.delta_var, min=0) / n_pix_per_sp[..., None, None, None] intra_sp_dist = intra_sp_dist[mask.bool()].sum() / C edge_feats = sp_means[edges] inter_sp_dist = self.distance(edge_feats[0], edge_feats[1], dim=1, kd=False) inter_sp_dist = inter_sp_dist * weights[:, 0] inter_sp_dist = torch.clamp(self.delta_dist - inter_sp_dist, min=0) inter_sp_dist = inter_sp_dist.sum() / edges.shape[1] loss = self.alpha * inter_sp_dist + self.beta * intra_sp_dist return loss.mean()
def _check_subresults(self): f = z5py.File(self.input_path) f_feat = z5py.File(self.output_path) ds_inp = f[self.input_key] ds_ws = f[self.ws_key] shape = ds_ws.shape blocking = nt.blocking([0, 0, 0], list(shape), self.block_shape) halo = [1, 1, 1] for block_id in range(blocking.numberOfBlocks): # get the block with the appropriate halo # and the corresponding bounding box block = blocking.getBlockWithHalo(block_id, halo) outer_block, inner_block = block.outerBlock, block.innerBlock bb = tuple( slice(beg, end) for beg, end in zip(inner_block.begin, outer_block.end)) # load the segmentation and the input # and compute the nifty graph seg = ds_ws[bb] rag = nrag.gridRag(seg, numberOfLabels=int(seg.max()) + 1) inp = ds_inp[bb] # compute nifty features features_nifty = nrag.accumulateEdgeStandartFeatures( rag, inp, 0., 1.) # load the features feat_key = os.path.join('blocks', 'block_%i' % block_id) features_block = f_feat[feat_key][:] # compare features self.assertEqual(len(features_nifty), len(features_block)) self.assertEqual(features_nifty.shape[1], features_block.shape[1] - 1) self.assertTrue(np.allclose(features_nifty, features_block[:, :-1])) len_nifty = nrag.accumulateEdgeMeanAndLength(rag, inp)[:, 1] self.assertTrue(np.allclose(len_nifty, features_block[:, -1]))
def compute_boundary_features(rag, boundary_map, min_value=0, max_value=1, n_threads=None): """ Compute edge features from boundary map. Arguments: rag [RegionAdjacencyGraph] - region adjacency graph boundary_map [np.ndarray] - boundary map. min_value [float] - minimum value used in accumulation (default: 0) max_value [float] - maximum value used in accumulation (default: 1) n_threads [int] - number of threads used, set to cpu count by default. (default: None) """ n_threads = multiprocessing.cpu_count() if n_threads is None else n_threads if tuple(rag.shape) != boundary_map.shape: raise ValueError("Incompatible shapes: %s, %s" % (str(rag.shape), str(boundary_map.shape))) features = nrag.accumulateEdgeStandartFeatures(rag, boundary_map, min_value, max_value, numberOfThreads=n_threads) return features
def _boundary_features(self, rag, input_): min_val, max_val = input_.min(), input_.max() return np.nan_to_num( nrag.accumulateEdgeStandartFeatures(rag, input_, min_val, max_val))
def _compute_edge_probabilities(self, input_, fragments=None): assert input_.ndim == 3 features = nrag.accumulateEdgeStandartFeatures(self.rag, input_, self.min_value, self.max_value) return features[:, self.stat_index]