HI all,
I am trying to add another MCP subclass to use with GIS data in the graph submodule in skimage. In particular, I'd like to allow the left and right borders of the cost np.array to be connected, i.e. to be neighbors. I thought it would suffice to change what are considered edges...so I created new functions to assign edges as should be required for this case (I think), but I get the same results as MCP_Geometric (which makes me think the computation is not taking this into account or I am missing some other required change). Could you help me figure this out?
Here’s an example of what I’d like the subclass to do
import skimage.graph.mcp as mcp np.random.seed(0) a = np.ones((5, 5), dtype=np.float32) a[0:, 1] = 1 a ''' array([[ 1., 1., 1., 1., 1.], [ 1., 1., 1., 1., 1.], [ 1., 1., 1., 1., 1.], [ 1., 1., 1., 1., 1.], [ 1., 1., 1., 1., 1.]], dtype=float32) '''
# First column is not connected with columns 3+ under Geometric (as expected) m = mcp.MCP_Geometric(a, fully_connected=True) costs, traceback = m.find_costs([(1, 4)]) costs ''' array([[ inf, inf, 2.41421356, 1.41421356, 1. ], [ inf, inf, 2. , 1. , 0. ], [ inf, inf, 2.41421356, 1.41421356, 1. ], [ inf, inf, 2.82842712, 2.41421356, 2. ], [ inf, inf, 3.82842712, 3.41421356, 3. ]]) '''
# For GIS should be different m = mcp.MCP_GIS(a, fully_connected=True) costs, traceback = m.find_costs([(1, 4)]) costs ''' Curently array([[ inf, inf, 2.41421356, 1.41421356, 1. ], [ inf, inf, 2. , 1. , 0. ], [ inf, inf, 2.41421356, 1.41421356, 1. ], [ inf, inf, 2.82842712, 2.41421356, 2. ], [ inf, inf, 3.82842712, 3.41421356, 3. ]])
Expected (correct one)
array([[ 1.41421356, inf, 2.41421356, 1.41421356, 1. ], [ 1. , inf, 2. , 1. , 0. ], [ 1.41421356, inf, 2.41421356, 1.41421356, 1. ], [ 2.41421356, inf, 2.82842712, 2.41421356, 2. ], [ 3.41421356, inf, 3.82842712, 3.41421356, 3. ]]) '''
My code is in https://github.com/ozak/scikitimage/blob/GIS/skimage/graph/_mcp.pyx
I’d appreciate any help or pointers you can give.
Cheers,
Ömer
Hello Ömer,
Your subclass will have to have some specialcase logic in find_costs() to actually handle wrapping the index around when it needs to go off the left or right sides of the array. Right now all your code does is remove the warning flags that the edge map provides to prevent this from happening, but it doesn't seem to actually do anything to implement wraparound.
Currently, your subclass reimplements find_costs() as find_costs_gis(), but no actual code is different between those two methods! And in any case, you should probably just override find_costs() rather than make a special new method find_costs_gis(). (This made it all a little confusing to figure out what you were actually doing in the code.)
I'm actually a little surprised your code isn't giving you a segfault, because if the edgemap flags are disabled without handling index wraparound, the coststracing will happily head right out of the array's memory and into wherever else.
If you're not comfortable with numpy array striding and dealing with flat indices into ndarrays (both of which are heavily used here), this might be a little tricky. But the basic gist of what you should do is not monkey with the edge map. Instead, in the loop in find_costs() that sets the use_offset flag, you might want to see if the edge map says you'll be stepping over the left or right edge. If so, set some special flag that you will then use to switch between the standard indexfinding: new_index = index + flat_offsets[i] and something you'll have to implement that deals with the wraparound correctly.
Does this help? Zach
On Wed, Aug 15, 2018 at 5:21 PM, Ömer Özak omer.ozak@gmail.com wrote:
HI all,
I am trying to add another MCP subclass to use with GIS data in the graph submodule in skimage. In particular, I'd like to allow the left and right borders of the cost np.array to be connected, i.e. to be neighbors. I thought it would suffice to change what are considered edges...so I created new functions to assign edges as should be required for this case (I think), but I get the same results as MCP_Geometric (which makes me think the computation is not taking this into account or I am missing some other required change). Could you help me figure this out?
Here’s an example of what I’d like the subclass to do
import skimage.graph.mcp as mcp np.random.seed(0) a = np.ones((5, 5), dtype=np.float32) a[0:, 1] = 1 a ''' array([[ 1., 1., 1., 1., 1.], [ 1., 1., 1., 1., 1.], [ 1., 1., 1., 1., 1.], [ 1., 1., 1., 1., 1.], [ 1., 1., 1., 1., 1.]], dtype=float32) '''
# First column is not connected with columns 3+ under Geometric (as expected) m = mcp.MCP_Geometric(a, fully_connected=True) costs, traceback = m.find_costs([(1, 4)]) costs ''' array([[ inf, inf, 2.41421356, 1.41421356, 1. ], [ inf, inf, 2. , 1. , 0. ], [ inf, inf, 2.41421356, 1.41421356, 1. ], [ inf, inf, 2.82842712, 2.41421356, 2. ], [ inf, inf, 3.82842712, 3.41421356, 3. ]]) '''
# For GIS should be different m = mcp.MCP_GIS(a, fully_connected=True) costs, traceback = m.find_costs([(1, 4)]) costs ''' Curently array([[ inf, inf, 2.41421356, 1.41421356, 1. ], [ inf, inf, 2. , 1. , 0. ], [ inf, inf, 2.41421356, 1.41421356, 1. ], [ inf, inf, 2.82842712, 2.41421356, 2. ], [ inf, inf, 3.82842712, 3.41421356, 3. ]])
Expected (correct one)
array([[ 1.41421356, inf, 2.41421356, 1.41421356, 1. ], [ 1. , inf, 2. , 1. , 0. ], [ 1.41421356, inf, 2.41421356, 1.41421356, 1. ], [ 2.41421356, inf, 2.82842712, 2.41421356, 2. ], [ 3.41421356, inf, 3.82842712, 3.41421356, 3. ]]) '''
My code is in https://github.com/ozak/scikitimage/blob/GIS/skimage/graph/_mcp.pyx
I’d appreciate any help or pointers you can give.
Cheers,
Ömer
scikitimage mailing list scikitimage@python.org https://mail.python.org/mailman/listinfo/scikitimage
participants (2)

Zach Pincus

Ömer Özak