简体   繁体   中英

Path Intersection with obstacle map

I do have a multidimensional obstacle map, which might look like that:

[1 1 1 1]
[0 0 0 0] 
[0 0 1 1]
[0 1 1 0]

so there are two areas defined by the ones (top four ones -> Area1, bottom four ones -> Area2)

I then have a path with points lying in that map like:

[(0, 0), (1, 0), (1, 1), (2, 1), (2, 2)]

and I would like to know, which areas have been crossed. Ideally I would like to know for each point in what area it lies. So the result should be a list of areas of the same length:

[Area1, None, None, None, Area2] 

In Pseudo Python Code I imagined something like:

map = array(...)
polygons = get_polygons_from_map(map)

areas = []
for point in path: 
  for polygon in polygons:
    if point in polygon: 
      areas.append(polygon)
      break
   else: 
    area.append(None) 

The missing part here is obviously get_polygons_from_map . I originally created the maps with opencv

map = np.zeros((self.size_y_px, self.size_x_px), np.uint8)
cv2.fillPoly(map, polygon_list, 1)

Is there some library that could help me with implementing this?

Small note: The map has a few elements, would be good if the algorithm wouldn't be somewhat performant

This is a question with probably a ton of different answers. But to use something, that does not require a lot of fine-tuning I suggest to use some clustering methods from scikit-learn.

https://scikit-learn.org/stable/modules/clustering.html

Espescially the DBSCAN method should allow you to get all areas on the map as a cluster and then use these cluster in the other parts of the code

https://scikit-learn.org/stable/modules/generated/sklearn.cluster.DBSCAN.html#sklearn.cluster.DBSCAN

Let's say you start with an array as in the upper part of your description

from collections import defaultdict
from sklearn.cluster import DBSCAN
import numpy as np

my_map = np.array([[1, 1, 1, 1],
                   [0, 0, 0, 0], 
                   [0, 0, 1, 1],
                   [0, 1, 1, 0]], dtype=np.int32)
area_coordinates = np.argwhere(my_map == 1)

# eps will depend on your definition of two points belonging to one area (e.g. horizontal + vertical vs. diagonal connection)
clustering = DBSCAN(eps=1.1, min_samples=2).fit(area_coordinates)
polygons = defaultdict(set)
for point, label in zip(area_coordinates, clustering.labels_):
    polygons[label].update([tuple(point)])

for polygon, pg_points in polygons.items():
    print(f"polygon {polygon}:", pg_points)

This will result in following output:

polygon 0: {(0, 1), (0, 3), (0, 0), (0, 2)}
polygon 1: {(3, 2), (3, 1), (2, 3), (2, 2)}

I hope, this answer suits your intention. If anything is not clear, let me know, please.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM