1

I am working on binary images in Python using OpenCV. I have two sets of points: PNodes and FNodes. I want to find the closest PNode to each of the FNodes (shortest m-path); closest in terms of 8-connected chessboard distance.

In the example below, suppose PNodes (donated by *) are: (6,1), (6,5) and (5,8). (indexing starts from 0, first element is row number). FNodes (denoted by #) are: (0,1), (0,9), (1,6), (2,5) and (4,3).

import numpy as np 
In = np.array ((
      [ 0,  1#, 0,  0,  0,  0,  0,  0,  0,  1#, 0],
      [ 1,  0,  0,  0,  0,  0,  1#, 0,  1,  0,  0],
      [ 0,  1,  0,  0,  0,  1#, 0,  0,  1,  0,  0],
      [ 0,  0,  1,  0,  0,  0,  1,  0,  0,  1,  0],
      [ 0,  1,  1,  1#, 0,  1,  0,  0,  1,  0,  0],
      [ 0,  1,  0,  0,  0,  1,  0,  0,  1*, 0,  0],
      [ 0,  1*, 0,  0,  0,  1*, 0,  0,  1,  0,  0],
      [ 0,  1,  0,  0,  1,  0,  1,  1,  0,  0,  0],
      [ 0,  0,  1,  1,  0,  0,  0,  1,  0,  0,  0]), dtype = "uint8") 

Distance_Matrix =  np.array ((
      [ 0,  6#, 0,  0,  0,  0,  0,  0,  0,  5#, 0],
      [ 5,  0,  0,  0,  0,  0,  5#, 0,  4,  0,  0],
      [ 0,  4,  0,  0,  0,  4#, 0,  0,  3,  0,  0],
      [ 0,  0,  3,  0,  0,  0,  3,  0,  0,  2,  0],
      [ 0,  2,  2,  3#, 0,  2,  0,  0,  1,  0,  0],
      [ 0,  1,  0,  0,  0,  1,  0,  0,  **, 0,  0],
      [ 0, **,  0,  0,  0,  **, 0,  0,  1,  0,  0],
      [ 0,  1,  0,  0,  1,  0,  1,  1,  0,  0,  0],
      [ 0,  0,  1,  1,  0,  0,  0,  1,  0,  0,  0]), dtype = "uint8") 

I am not concerned with the exact value of distance, I just want to find out the closest pair. Something like this: FNode at (0,1) is closest to PNode at (6,1). FNode at (4,3) is closest to PNode at (6,1). All distances are in terms of 8-connected chessboard distance.

Ultimate requirement from this entire process: Basically, I just want to make sure all PNodes have atleast 1 FNode which lie within a given distance range (along the path of 1s).

Suppose PNode (PN_1) has a FNode (FN_1) which lies within the required distance range, I also make sure that PN_1 is closest to FN_1, and not any other PNode.

For a better understanding, I have attached an image below; FNodes are rectangular and PNodes are circular.

I don't care about other elements in this matrix, apart from those of PNodes and FNodes, as depicted.

enter image description here

aL_eX
  • 1,453
  • 2
  • 15
  • 30
Saania
  • 625
  • 1
  • 6
  • 26
  • I was wondering if Dijkstras Shortest Path Algorithm will be useful in this case. Any feedback? – Saania Jan 19 '18 at 18:48

1 Answers1

0

I'd use Dijkstra's algorithm for this. It finds the shortest distance between a source node and every other node by exploring nearer nodes before farther nodes.

Seed a Dijkstra search at each of your P-nodes and halt the search when you either find the first F-node or exceed your distance constraint.

Since you don't have a graph, per se, you can generate neighbours using offsets. For instance if you have a cell (x,y) you can define some offsets

dx = [-1,-1, 0, 1,1,1,0,-1]
dy = [ 0,-1,-1,-1,0,1,1, 1]

and then take (x+dx[i], y+dy[i]) for i∈[0,7] to generate the neighbours of a given cell.

You can define a separate 2D array/matrix for tracking whether cells have been visited.

Richard
  • 56,349
  • 34
  • 180
  • 251