-
Notifications
You must be signed in to change notification settings - Fork 0
/
subsample.py
149 lines (121 loc) · 4.64 KB
/
subsample.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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
import laspy
import numpy as np
import math
import pcl
from open3d import *
from pyflann import *
def visualize_points(data, start, end):
"""
Inputs: a numpy array data of size (dim, 3) of 3D points.
Process: Then, data is visualized using Open3D.
"""
pcd = PointCloud()
pcd.points = Vector3dVector(data[start:end])
draw_geometries([pcd])
def get_k_nearest_neighbors(data, start, end, start_test, end_test, k):
"""
Inputs: a numpy array of 3D points, starting / ending indices, and
starting and ending indices for the test portion of data.
Process: finds the k-nearest neighbors from data[start : end] relative
to data[start_test : end_test]
Outputs: the k-nearest neighbors from the points in data[start : end].
"""
flann = FLANN()
result, dists = flann.nn(data[start_test:end_test], data[start:end],
k, algorithm="kmeans", branching=32, iterations=7, checks=16)
get_points = lambda p: data[p]
return get_points(result).reshape((end - start) * k, 3)
def voxel_filter(data, x_filter, y_filter, z_filter):
"""
Inputs: a numpy array of 3D points and x_filter, y_filter, z_filter,
which determines the size of the voxel grid filter used to subsample data.
Outputs: a numpy array of voxel filtered points.
"""
cloud = pcl.PointCloud()
cloud.from_array(data.astype(np.float32))
filt = p.make_voxel_grid_filter()
filt.set_leaf_size(x_filter, y_filter, z_filter)
return filt.filter().to_array()
def voxelize(data, x_len, y_len, z_len):
x_iter = 1 / x_len
y_iter = 1 / y_len
a = np.ones(shape=(x_len, y_len, 3))
for i in range(0, data.shape[0]):
point = data[i, :]
x = point[0]
y = point[1]
z = point[2]
square_x = int(x // x_iter)
square_y = int(y // y_iter)
if square_x == x_len:
square_x = x_len - 1
if square_y == y_len:
square_y = y_len - 1
if a[square_x, square_y, 2] > z:
a[square_x, square_y, :] = point
for i in range(0, x_len):
for j in range(0, y_len):
if np.array_equal(a[i][j], [1, 1, 1]):
x_kernel = [i - 1, i + 1]
y_kernel = [j - 1, j + 1]
for l in range(0, 2):
if x_kernel[l] == x_len or x_kernel[l] == -1:
del x_kernel[l]
if y_kernel[l] == x_len or y_kernel[l] == -1:
del y_kernel[l]
sigma = 0
for m in range(0, len(x_kernel)):
for n in range(0, len(y_kernel)):
sigma += a[m][n][2]
a[i][j] = [((i + 1) * x_iter) / 2, ((j + 1) * x_iter) / 2, sigma / (len(x_kernel) + len(y_kernel))]
return a.reshape((x_len * y_len, 3))
def box_subsample(data, origin, length, width, height):
"""
Inputs: a numpy array of 3D points, an origin for the box in 3D space,
the length, width, and height of each box.
Process: places a length x width x height rectangular prism at origin
and finds every point in data within this prism.
Outputs: a numpy array of points within the prism.
"""
p = []
for i in range(0, 8):
p.append(np.empty((3, 1)))
p[0][0, 0] = origin[0] - (length / 2)
p[0][1, 0] = origin[1] + (width / 2)
p[0][2, 0] = origin[2]
p[1][0, 0] = origin[0] + (length / 2)
p[1][1, 0] = origin[1] + (width / 2)
p[1][2, 0] = origin[2]
p[2][0, 0] = origin[0] + (length / 2)
p[2][1, 0] = origin[1] - (width / 2)
p[2][2, 0] = origin[2]
p[3][0, 0] = origin[0] - (length / 2)
p[3][1, 0] = origin[1] - (width / 2)
p[3][2, 0] = origin[2]
p[4][0, 0] = p[0][0, 0]
p[4][1, 0] = p[0][1, 0]
p[4][2, 0] = origin[2] + height
p[5][0, 0] = p[1][0, 0]
p[5][1, 0] = p[1][1, 0]
p[5][2, 0] = origin[2] + height
p[6][0, 0] = p[2][0, 0]
p[6][1, 0] = p[2][1, 0]
p[6][2, 0] = origin[2] + height
p[4][0, 0] = p[3][0, 0]
p[4][1, 0] = p[3][1, 0]
p[4][2, 0] = origin[2] + height
u = np.transpose(p[1] - p[0])
v = np.transpose(p[3] - p[0])
w = np.transpose(p[0] - p[4])
indices = []
for j in range(0, data.shape[0]):
point = data[j]
add_x = p[0][0, 0] <= point[0] and point[0] <= p[1][0, 0]
add_y = p[2][1, 0] <= point[1] and point[1] <= p[0][1, 0]
add_z = p[3][2, 0] <= point[2] and point[2] <= p[4][2, 0]
if add_x and add_y and add_z:
indices.append(j)
new = np.empty((len(indices), 3))
for k in range(0, len(indices)):
new[k] = data[indices[k]]
return new