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.