forked from hfyxin/fare-gate-visual-game
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathradar_clustering.py
97 lines (86 loc) · 3.85 KB
/
radar_clustering.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
from sklearn.cluster import DBSCAN
import numpy as np
def cluster_bbox(cluster_point_cloud, cluster_label):
x_values = [
point["x"] for point in cluster_point_cloud if point["index"] == cluster_label
]
y_values = [
point["y"] for point in cluster_point_cloud if point["index"] == cluster_label
]
x1 = min(x_values)
y1 = min(y_values)
x2 = max(x_values)
y2 = max(y_values)
return x1, y1, x2, y2
def obj_height(cluster_point_cloud, cluster_label):
z_values = [
point["z"] for point in cluster_point_cloud if point["index"] == cluster_label
]
# height/size
z1 = min(z_values)
z2 = max(z_values)
size = z2 - z1
height = z2
return size, height
class ClusterProcessor:
def __init__(self, eps=400, min_samples=5):
self.eps = eps
self.min_samples = min_samples
def cluster_points(self, radar_points):
"""
:param radar_points: Any
:return: centroids -- {'x': Xc, 'y': Yc, 'z': Zc, 'numPoints': n}
cluster_point_cloud -- -- {'x': Xn, 'y': Yn, 'z': Zn, 'Cluster Label': k}
"""
cluster_obj = DBSCAN(
eps=self.eps, min_samples=self.min_samples, metric="euclidean", n_jobs=-1
).fit(
radar_points
) # eps is trial and error val --> 400 will probably be ok for denser pointcloud
clusters = set(cluster_obj.labels_) # Set of labels (no repeats)
pointLabels = (
cluster_obj.labels_
) # List of labels by points (with repeated labels)
# Initialize lists for centroid, clustered points and cluster idxs
centroids = []
cluster_point_cloud = []
# Iterate thru clusters
for clusterIdx, cluster in enumerate(clusters): # No repeats in a cluster
if cluster >= 0: # Discard the -1 cluster which is the unassociated points
centroids.append({"x": 0, "y": 0, "z": 0, "numPoints": 0})
# Go thru points/labels
for labelIdx, label in enumerate(pointLabels):
if label == cluster:
# Accumulate coords values for centroid calc
centroids[clusterIdx]["x"] = (
centroids[clusterIdx]["x"] + radar_points[labelIdx][0]
) # X
centroids[clusterIdx]["y"] = (
centroids[clusterIdx]["y"] + radar_points[labelIdx][1]
) # Y
centroids[clusterIdx]["z"] = (
centroids[clusterIdx]["z"] + radar_points[labelIdx][2]
) # Z
centroids[clusterIdx]["numPoints"] = (
centroids[clusterIdx]["numPoints"] + 1
) # store the count to divide later
# Accumulate each radar point associated with cluster label
cluster_point_cloud.append(
{
"x": radar_points[labelIdx][0],
"y": radar_points[labelIdx][1],
"z": radar_points[labelIdx][2],
"index": cluster,
}
)
# Compute the centroid of the cluster, store the number of points
centroids[clusterIdx]["x"] = (
centroids[clusterIdx]["x"] / centroids[clusterIdx]["numPoints"]
)
centroids[clusterIdx]["y"] = (
centroids[clusterIdx]["y"] / centroids[clusterIdx]["numPoints"]
)
centroids[clusterIdx]["z"] = (
centroids[clusterIdx]["z"] / centroids[clusterIdx]["numPoints"]
)
return centroids, cluster_point_cloud