pmneila/PyMaxflow

contrast-sensitive Potts model for pairwise smoothing on a grid

Closed this issue · 1 comments

Is it currently possible to implement this commonly used term for image segmentation without building the graph manually in a python loop? Or is it only possible to use a single set of constant neighborhood weights across the whole grid?

No, you can definitely use different weights at each location. There are a couple of different ways of doing so, depending on your specific needs. The docstring of add_grid_edges shows one possible way (this is one of the examples, check the docstring for more):

        >>> g = maxflow.GraphFloat()
        >>> nodeids = g.add_grid_nodes((3, 3))
        >>> structure = np.array([[0, 0, 0],
                                  [0, 0, 1],
                                  [0, 1, 0]])
        >>> weights = np.array([[1, 2, 3],
                                [4, 5, 6],
                                [7, 8, 9]])
        >>> g.add_grid_edges(nodeids, weights=weights, structure=structure,
                symmetric=False)
        
        ::
        
            XXX----1--->XXX----2--->XXX
            XXX         XXX         XXX
            |           |           | 
            |           |           | 
           1|          2|          3| 
            |           |           | 
            V           V           V 
            XXX----4--->XXX----5--->XXX 
            XXX         XXX         XXX
            |           |           |
            |           |           |
           4|          5|          6|
            |           |           |
            V           V           V
            XXX----7--->XXX----8--->XXX
            XXX         XXX         XXX

If you need different weights per location AND orientation (e.g., horizontal edges having different capacities than vertical edges), you can call add_grid_edges once per orientation.

Finally, if you need even more flexibility, note that the nodeids in add_grid_edges are not required to have the shape of the image. You can create your own nodeids to match you requirements. For example, consider the 3x3 grid

0    1    2

3    4    5

6    7    8

where you would like to connect 0 to 5 with capacity 1.0, 0 to 8 with capacity 2.0 and 1 to 6 with capacity 3.0. You can create a custom array for nodeids,

g = maxflow.GraphFloat()
g.add_grid_nodes((3, 3))
mynodeids = np.array([
    [0, 5],
    [0, 8],
    [1, 6]])

weights = np.array([[1.0], [2.0], [3.0]])

# Note that nodeids and weights must be broadcastable according to NumPy rules.

# Each node will be connected to its right node (i.e., 0-->5, 0-->8, 1-->6)
structure = np.array([[0, 0, 1]])

g.add_grid_edges(mynodeids, weights, structure)

This is the result:
result

Let me know if none of this methods apply to your problem.