Thanks everyone for the advice and tips. I am getting closer to a solution. The (obvious) plan is for each edge find neighbouring regions, use segment_mask to extract indices into the depth map and calculate depth features (average depth, surface normals etc) and then combine segments based on these feature(s). Some of the advice in the replies, suggest using a graph package and having some way to directly access the pixels of each super-pixel with some interesting ideas provided. 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... Which takes a segment mask/array and creates a set of vertices and edges representing the region connectivity graph. This looks like it might be sufficient. Am I being too naive? Should I just learn/use a graph package? Also, any advice/gotchas on how to join/combine segments? There seems to be a few join/relabel functions in the library. Thanks again, Michael. -- On 22/04/13 8:32 PM, St�fan van der Walt wrote:
On Mon, Apr 22, 2013 at 11:55 AM, Juan Nunez-Iglesias <jni.soma@gmail.com> wrote:
It's very convenient to have direct access back to the pixels/voxels making up each superpixel. Therefore, I stored on each node an array containing all the linear indices into the `ravel`ed version of the image. This is pretty expensive, though, so if could do it over, I would store the index of a single pixel belonging to that superpixel and pair it with a flood fill algorithm, so that a function `g.get_pixel_indices(superpixel_id)` would transparently return the pixel list, but in O(superpixel_size) time while only using up a singe int of space. 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). Perhaps it will be a bit painful to extend to N-d, but it is doable.
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.
Related note: does skimage have an nd implementation of flood fill? I think one of the recent PRs made an attempt at a 2D version called ``connected_component``, but otherwise no.
St�fan
On Tue, Apr 23, 2013 at 3: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...
I think Gaël's comment might be the key: scipy.sparse.cs_graph_components Stéfan
@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<http://peekaboo-vision.blogspot.com.au/2011/08/region-connectivity-graphs-in...>
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+1return 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?
participants (3)
-
Brickle Macho
-
Juan Nunez-Iglesias
-
Stéfan van der Walt