pmneila / PyMaxflow

Python library for creating flow networks and computing the maxflow/mincut (aka graph-cuts for Python)
http://pmneila.github.io/PyMaxflow/
242 stars 59 forks source link

`aexpansion_grid` and `abswap_grid` behavior #65

Closed isaacwasserman closed 1 year ago

isaacwasserman commented 1 year ago

I'm working on a multi-segment problem using this library's aexpansion_grid and/or abswap_grid functions, and I've noticed some strange behavior.

I have a simple 4-pixel image:

image = np.array([
    [[1, 0, 0, 0], [0, 1, 0, 0]],
    [[0, 0, 1, 0], [0, 0, 0, 1]]
])

I define my unary energy D as being equal to image, and my pairwise energy V to the 4x4 zero matrix, indicating no penalty for removing pairwise edges.

If I'm not mistaken, the optimal segmentation for this graph is the argmax of the image in dimension 2 (i.e. [[0,1],[2,3]]). However, aexpansion_grid(D,V) returns [[1,0],[0,0]] and abswap_grid(D,V) returns [[3,3],[3,2]].

Am I defining my energy matrices incorrectly?

pmneila commented 1 year ago

Hi @isaacwasserman,

Both aexpansion_grid and abswap_grid minimize the energy (that is, you should expect the argmin, not the argmax). If you negate the image when calling those functions, you get the expected result:

In [15]: maxflow.aexpansion_grid(-image, d)
Out[15]:
array([[0, 1],
       [2, 3]], dtype=int8)

In [16]: maxflow.abswap_grid(-image, d)
Out[16]:
array([[0, 1],
       [2, 3]], dtype=int8)

Also note that aexpansion_grid requires that the pairwise term V is a metric, which in your case is not satisfied (for example, V[a, b] must be 0 if and only if a==b). It works for this simple example, but be aware that it might fail for other unary terms.

Hope that clarifies the issue.

Best