-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathPointCollection.cpp
More file actions
237 lines (153 loc) · 5.94 KB
/
PointCollection.cpp
File metadata and controls
237 lines (153 loc) · 5.94 KB
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
#include <iostream>
#include <vector>
#include <array>
#include <algorithm>
#include "PointCollection.h"
#include "CircularBuffer.h"
#include "CircularBufferCollection.h"
using namespace std;
array<unsigned int,2> PointCollection::IndexToSubscript(unsigned int ncols, unsigned int nrows, unsigned int idx){
unsigned int row, col;
col = idx % ncols;
row = (idx - col) / ncols;
return {row, col};
}
unsigned int PointCollection::SubscriptToIndex(unsigned int ncols, unsigned int row, unsigned int col){
return row*ncols + col;
}
// Sort PointCollection by z
void PointCollection::SortByZ()
{
sort(points_.begin(), points_.end(), [](Point a, Point b) { return a.z > b.z; });
}
// Set the int16 RGB colormap
void PointCollection::SetRGBColors(vector<array<unsigned int, 3>> colormap)
{
unsigned int ncolors = colormap.size();
for (unsigned int j(0); j < points_.size(); j++){
points_[j].rgb_color = colormap[points_[j].tree_idx % ncolors];
}
}
// Extract and copy a subset from a vector of Points based on the classification attribute
PointCollection PointCollection::FilterPointsByClass(vector<unsigned int>& keep_classes)
{
PointCollection point_collection_subset;
for (unsigned int j(0); j < points_.size(); j++){
for (unsigned int k(0); k < keep_classes.size(); k++){
if (points_[j].classification == keep_classes[k]){
//point_collection_subset.PushBackPoint(points_[j]);
point_collection_subset.points_.push_back(points_[j]);
}
}
}
return point_collection_subset;
}
// Compute point indexes
void PointCollection::ComputePointIndexes()
{
for (unsigned int j(0); j < points_.size(); j++){
points_[j].point_idx = j;
}
}
// Compute the BoundingBox object of the PointCollection object
void PointCollection::ComputeBoundingBox()
{
auto result1 = minmax_element(points_.begin(), points_.end(), [](Point a, Point b) { return a.x >= b.x; });
auto result2 = minmax_element(points_.begin(), points_.end(), [](Point a, Point b) { return a.y >= b.y; });
BoundingBox bounding_box;
bounding_box.x_max_idx = result1.first - points_.begin();
bounding_box.x_min_idx = result1.second - points_.begin();
bounding_box.y_max_idx = result2.first - points_.begin();
bounding_box.y_min_idx = result2.second - points_.begin();
bounding_box.x_max = points_[bounding_box.x_max_idx].x;
bounding_box.x_min = points_[bounding_box.x_min_idx].x;
bounding_box.x_max = points_[bounding_box.y_max_idx].y;
bounding_box.y_min = points_[bounding_box.y_min_idx].y;
bounding_box.availability = true;
bounding_box_ = bounding_box;
}
// Compute the grid coordinates
void PointCollection::ComputeGridCoordinates()
{
if (coordinate_scaling_ != 1 and coordinate_scaling_ != 10){
coordinate_scaling_ = 1;
cerr << "Warning: scaling factor should be 1 or 10. Defaulting to 1." << endl;
}
if (not bounding_box_.availability){
ComputeBoundingBox();
}
for(unsigned int j(0); j < points_.size(); j++){
points_[j].row = (int) round((points_[j].y - points_[bounding_box_.y_min_idx].y) * double(coordinate_scaling_)); //round(
points_[j].col = (int) round((points_[j].x - points_[bounding_box_.x_min_idx].x) * double(coordinate_scaling_));
}
n_cols_ = points_[bounding_box_.x_max_idx].col + 1; // Number of columns
n_rows_ = points_[bounding_box_.y_max_idx].row + 1; // Number of rows
cout << "nrows: " << n_rows_ << endl;
cout << "ncols: " << n_cols_ << endl;
}
// Compute grid node membership
void PointCollection::AssignGridCells()
{
vector<vector<int>> idx_grid(n_cols_*n_rows_);
cout << "size: " << n_cols_*n_rows_ << endl;
for(unsigned int j(0); j < points_.size(); j++){
idx_grid[SubscriptToIndex(n_cols_, points_[j].row, points_[j].col)].push_back(j);
}
idx_grid_ = idx_grid;
}
// Extract the grid values located within the given CircularBuffer
void PointCollection::ExtractPointsInBuffer(CircularBuffer& circular_buffer, PointCollection& sample, int& col_0, int& row_0)
{
vector<int> tmp_idx;
int col_idx, row_idx;
for(unsigned int j(0); j < circular_buffer.coordinate_offsets_.size(); j++){
// Check if row and column are inside the grid
col_idx = col_0 + circular_buffer.coordinate_offsets_[j][0];
row_idx = row_0 + circular_buffer.coordinate_offsets_[j][1];
// Check if the kernel cell is located within the grid
if (((unsigned int)row_idx <= n_rows_-1) and ((unsigned int)row_idx >= 0) and ((unsigned int)col_idx <= n_cols_-1) and ((unsigned int)col_idx >= 0)){
tmp_idx = idx_grid_[SubscriptToIndex(n_cols_, row_idx, col_idx)]; // Grid cell linear index
// Check if the grid cell is non-empty
if (not tmp_idx.empty()){
for(unsigned int k(0); k < tmp_idx.size(); k++){
// Check if the point is non-segmented
if (not points_[tmp_idx[k]].segmentation_status){
sample.points_.push_back(points_[tmp_idx[k]]);
}
}
}
}
}
}
// Find the local maxima
void PointCollection::FindLocalMaxima(CircularBuffer& circular_buffer)
{
bool locmax;
PointCollection local_points;
local_points.points_.reserve(1000); // Value based on max point density (current max. density is ~70 pts per square meter for ALS)
for(unsigned int j(0); j < points_.size(); j++){
if (points_[j].local_maxima_status == 2){ // If the LocalMaximaStatus is undetermined
int col_0 = points_[j].col;
int row_0 = points_[j].row;
ExtractPointsInBuffer(circular_buffer, local_points, col_0, row_0);
locmax = true;
unsigned int k(0);
while(locmax and (k < local_points.points_.size())){
locmax = (points_[j].z >= local_points.points_[k].z);
points_[local_points.points_[k].point_idx].local_maxima_status = 0;
k++;
}
if (locmax){
points_[j].local_maxima_status = 1;
} else {
points_[j].local_maxima_status = 0;
}
}
local_points.points_.clear();
}
}
// Get coordinate scaling factor
unsigned int PointCollection::GetScalingFactor()
{
return coordinate_scaling_;
}