@Michael:

On Tue, Apr 23, 2013 at 11:34 AM, Brickle Macho <bricklemacho@gmail.com> wrote:
Being a little naive I was hoping to have a simple set of edges to traverse.   I found a Peekaboo blog entry: http://peekaboo-vision.blogspot.com.au/2011/08/region-connectivity-graphs-in-python.html

Either this or Stefan's/Gael's suggestion are good. You're not doing anything complicated so a simple edge list is indeed fine.

Also, any advice/gotchas on how to join/combine segments?

This is a whole big can of worms! It really depends on what you're doing later. For example, do you want to do this hierarchically? Or do you want to do it in one shot? One shot is simplest: for each edge, keep a score, something like Pr(join(u, v)). Then, threshold this graph, ie, throw away all the edges where your probability is lower than some value. Finally, do a connected components search, and iterate over all superpixels as follows:

# connected_components is a list of lists, for example
out = np.zeros_like(image)
for i, c in enumerate(connected_components):
    for superpixel in c:
        out[image==superpixel] = i+1
return out
Each call to `image==superpixel` is O(image.size), but this should be manageable for smallish images.


@stefan:

On 22/04/13 8:32 PM, Stéfan van der Walt wrote:
Thanks for sharing that good advice. Juan.  There is also an
intermediary storage format, one that I used before with some success.
  Think of a 2-D example: you store the start and end indices of each
column that comprises the object, paired with an index into the rows
(very similar to CSR).  

Got it. Slightly more space, slightly faster. I imagine you stored repeated row indices if the object was not convex?

Perhaps it will be a bit painful to extend to N-d, but it is doable.

Yeah, although I'd prefer to implement flood fill. ;) 

Another option is to store a graph in an array.  This goes along very
well with the implementation of ``graph.label``.  At each position in
the array, you store the index of the previous pixel to which it is
connected.  For any super-pixel, you can then store only the last
pixel, and traverse indices backward to get the entire super-pixel.
Con: 2 x storage.

I actually don't understand this at all, but it sounds really interesting. It seems to me like you can only represent chain topologies, but that would make no sense? Could you elaborate?