Exemplo n.º 1
0
def segment_volume_mc(pmaps,
                      threshold=0.4,
                      sigma=2.0,
                      beta=0.6,
                      ws=None,
                      sp_min_size=100):
    if ws is None:
        ws = distance_transform_watershed(pmaps,
                                          threshold,
                                          sigma,
                                          min_size=sp_min_size)[0]

    rag = compute_rag(ws, 1)
    features = nrag.accumulateEdgeMeanAndLength(rag, pmaps, numberOfThreads=1)
    probs = features[:, 0]  # mean edge prob
    edge_sizes = features[:, 1]
    costs = transform_probabilities_to_costs(probs,
                                             edge_sizes=edge_sizes,
                                             beta=beta)
    graph = nifty.graph.undirectedGraph(rag.numberOfNodes)
    graph.insertEdges(rag.uvIds())

    node_labels = multicut_kernighan_lin(graph, costs)

    return nifty.tools.take(node_labels, ws)
Exemplo n.º 2
0
    def segment_volume(self, pmaps):
        if self.ws_2D:
            # WS in 2D
            ws = self.ws_dt_2D(pmaps)
        else:
            # WS in 3D
            ws, _ = distance_transform_watershed(pmaps,
                                                 self.ws_threshold,
                                                 self.ws_sigma,
                                                 sigma_weights=self.ws_w_sigma,
                                                 min_size=self.ws_minsize)

        rag = compute_rag(ws, 1)
        # Computing edge features
        features = nrag.accumulateEdgeMeanAndLength(
            rag, pmaps, numberOfThreads=1)  # DO NOT CHANGE numberOfThreads
        probs = features[:, 0]  # mean edge prob
        edge_sizes = features[:, 1]
        # Prob -> edge costs
        costs = transform_probabilities_to_costs(probs,
                                                 edge_sizes=edge_sizes,
                                                 beta=self.beta)
        # Creating graph
        graph = nifty.graph.undirectedGraph(rag.numberOfNodes)
        graph.insertEdges(rag.uvIds())
        # Solving Multicut
        node_labels = multicut_kernighan_lin(graph, costs)
        return nifty.tools.take(node_labels, ws)
Exemplo n.º 3
0
    def test_distance_transform_watershed_2d(self):
        from elf.segmentation.watershed import distance_transform_watershed
        shape = (256, 256)
        inp = np.random.rand(*shape).astype('float32')

        # test for different options
        configs = [{
            'sigma_seeds': 2.
        }, {
            'sigma_seeds': 2.,
            'pixel_pitch': (1, 1)
        }, {
            'sigma_seeds': 2.,
            'pixel_pitch': (4, 2)
        }, {
            'sigma_seeds': 0.,
            'sigma_weights': 0.,
            'min_size': 0
        }]
        for config in configs:
            ws, max_id = distance_transform_watershed(inp,
                                                      threshold=.5,
                                                      **config)
            self.assertEqual(inp.shape, ws.shape)
            # make sure result is non-trivial
            self.assertGreater(max_id, 32)
            self.assertEqual(ws.max(), max_id)
            self.assertNotIn(0, ws)
Exemplo n.º 4
0
    def execute(self, slot, subindex, roi, result):
        assert slot is self.Superpixels, "Unknown or unconnected output slot: {}".format(
            slot)

        pmap = self._opSelectedInput.Output(roi.start, roi.stop).wait()

        if self.debug_results:
            self.debug_results.clear()

        # distance_transform_watershed expects a default value of None for pixel_pitch.
        if self.PixelPitch.value == []:
            pixel_pitch_to_pass = None
        else:
            pixel_pitch_to_pass = self.PixelPitch.value

        ws, max_id = distance_transform_watershed(
            pmap[..., 0],
            self.Threshold.value,
            self.Sigma.value,
            self.Sigma.value,
            self.MinSize.value,
            self.Alpha.value,
            pixel_pitch_to_pass,
            self.ApplyNonmaxSuppression.value,
        )

        result[..., 0] = ws

        self.watershed_completed()
Exemplo n.º 5
0
    def test_distance_transform_watershed_suppression(self):
        from elf.segmentation.watershed import distance_transform_watershed
        shape = (256, 256)
        inp = np.random.rand(*shape).astype('float32')

        ws, max_id = distance_transform_watershed(
            inp, threshold=.5, sigma_seeds=2., apply_nonmax_suppression=True)
        self.assertEqual(inp.shape, ws.shape)
        # make sure result is non-trivial
        self.assertGreater(max_id, 32)
        self.assertEqual(ws.max(), max_id)
        self.assertNotIn(0, ws)
Exemplo n.º 6
0
 def ws_dt_2D(self, pmaps):
     # Axis 0 is assumed z-axis!!!
     ws = np.zeros_like(pmaps).astype(np.uint32)
     max_idx = 1
     for i in range(pmaps.shape[0]):
         _pmaps = pmaps[i]
         _ws, _ = distance_transform_watershed(_pmaps,
                                               self.ws_threshold,
                                               self.ws_sigma,
                                               sigma_weights=self.ws_w_sigma,
                                               min_size=self.ws_minsize)
         _ws = _ws + max_idx
         max_idx = _ws.max()
         ws[i] = _ws
     return ws
Exemplo n.º 7
0
def segment_volume_lmc_from_seg(boundary_pmaps,
                                nuclei_seg,
                                threshold=0.4,
                                sigma=2.0,
                                sp_min_size=100):
    watershed = distance_transform_watershed(boundary_pmaps,
                                             threshold,
                                             sigma,
                                             min_size=sp_min_size)[0]

    # compute the region adjacency graph
    rag = compute_rag(watershed)

    # compute the edge costs
    features = compute_boundary_mean_and_length(rag, boundary_pmaps)
    costs, sizes = features[:, 0], features[:, 1]

    # transform the edge costs from [0, 1] to  [-inf, inf], which is
    # necessary for the multicut. This is done by intepreting the values
    # as probabilities for an edge being 'true' and then taking the negative log-likelihood.
    # in addition, we weight the costs by the size of the corresponding edge

    # we choose a boundary bias smaller than 0.5 in order to
    # decrease the degree of over segmentation
    boundary_bias = .6

    costs = transform_probabilities_to_costs(costs,
                                             edge_sizes=sizes,
                                             beta=boundary_bias)
    max_cost = np.abs(np.max(costs))
    lifted_uvs, lifted_costs = lifted_problem_from_segmentation(
        rag,
        watershed,
        nuclei_seg,
        overlap_threshold=0.2,
        graph_depth=4,
        same_segment_cost=5 * max_cost,
        different_segment_cost=-5 * max_cost)

    # solve the full lifted problem using the kernighan lin approximation introduced in
    # http://openaccess.thecvf.com/content_iccv_2015/html/Keuper_Efficient_Decomposition_of_ICCV_2015_paper.html
    node_labels = lmc.lifted_multicut_kernighan_lin(rag, costs, lifted_uvs,
                                                    lifted_costs)
    lifted_segmentation = project_node_labels_to_pixels(rag, node_labels)
    return lifted_segmentation
Exemplo n.º 8
0
def get_result_function(input_data):
    """
    Returns the result of the watershed algorithm directly from
    the core function.
    """

    ws, max_id = distance_transform_watershed(
        input_data[..., 0],
        WS_PARAMS["threshold"],
        WS_PARAMS["sigma"],
        WS_PARAMS["sigma"],
        WS_PARAMS["min_size"],
        WS_PARAMS["alpha"],
        WS_PARAMS["pixel_pitch"],
        WS_PARAMS["apply_nonmax_suppression"],
    )

    return ws, max_id
Exemplo n.º 9
0
    def test_distance_transform_watershed_masked(self):
        from elf.segmentation.watershed import distance_transform_watershed
        shape = (32, 128, 128)
        inp = np.random.rand(*shape).astype('float32')
        mask = np.zeros(shape, dtype='bool')
        mask[8:24, 28:100, 37:93] = 1

        # test for different options
        ws, max_id = distance_transform_watershed(inp,
                                                  threshold=.5,
                                                  mask=mask,
                                                  sigma_seeds=2.)
        self.assertEqual(inp.shape, ws.shape)
        # make sure result is non-trivial
        self.assertGreater(max_id, 32)
        self.assertEqual(ws.max(), max_id)
        self.assertNotIn(0, ws[mask])
        self.assertTrue((ws[np.logical_not(mask)] == 0).all())