10 #include <tbb/task_group.h>
13 #include <unordered_map>
23 template <
class TReal,
31 min_sqr_dist_to_center_(
std::numeric_limits<TReal>::max()),
33 static_assert(POS_FN !=
MAX,
"MAX is not allowed for point positions");
34 static_assert(FEAT_FN !=
CENTER,
35 "CENTER is not allowed for feature vectors");
38 template <
class Derived,
class Derived2,
class Derived3>
39 inline void AddPoint(
const Eigen::MatrixBase<Derived>& pos,
40 const Eigen::MatrixBase<Derived2>& voxel_center,
41 const Eigen::ArrayBase<Derived3>& feat) {
42 bool new_nearest_neighbor =
false;
45 sqr_d = (voxel_center - pos).squaredNorm();
46 if (sqr_d < min_sqr_dist_to_center_) {
47 new_nearest_neighbor =
true;
48 min_sqr_dist_to_center_ = sqr_d;
52 position_ += pos.array();
55 }
else if (POS_FN ==
CENTER) {
56 if (count_ == 0) position_ = voxel_center;
60 features_.resizeLike(feat);
67 }
else if (FEAT_FN ==
MAX) {
68 features_ = features_.max(feat);
73 inline Eigen::Array<TReal, 3, 1>
Position()
const {
75 return position_ / count_;
82 inline Eigen::Array<TFeat, Eigen::Dynamic, 1>
Features()
const {
84 return features_ / count_;
91 inline int Count()
const {
return count_; }
95 TReal min_sqr_dist_to_center_;
96 Eigen::Array<TReal, 3, 1> position_;
97 Eigen::Array<TFeat, Eigen::Dynamic, 1> features_;
100 template <
class TReal,
108 min_sqr_dist_to_center_(
std::numeric_limits<TReal>::max()),
110 static_assert(POS_FN !=
MAX,
"MAX is not allowed for point positions");
111 static_assert(FEAT_FN !=
CENTER,
112 "CENTER is not allowed for feature vectors");
115 template <
class Derived,
class Derived2,
class Derived3>
116 inline void AddPoint(
const Eigen::MatrixBase<Derived>& pos,
117 const Eigen::MatrixBase<Derived2>& voxel_center,
118 const Eigen::ArrayBase<Derived3>& feat,
120 bool new_nearest_neighbor =
false;
123 sqr_d = (voxel_center - pos).squaredNorm();
124 if (sqr_d < min_sqr_dist_to_center_) {
125 new_nearest_neighbor =
true;
126 min_sqr_dist_to_center_ = sqr_d;
131 position_ += pos.array();
134 }
else if (POS_FN ==
CENTER) {
135 if (count_ == 0) position_ = voxel_center;
139 features_.resizeLike(feat);
147 }
else if (FEAT_FN ==
MAX) {
149 index_.resizeLike(feat);
160 }
else if (FEAT_FN ==
MAX) {
161 for (
int i = 0; i < features_.rows(); ++i) {
162 if (feat(i) > features_(i)) {
163 features_(i) = feat(i);
171 inline Eigen::Array<TReal, 3, 1>
Position()
const {
173 return position_ / count_;
180 inline Eigen::Array<TFeat, Eigen::Dynamic, 1>
Features()
const {
182 return features_ / count_;
189 inline int Count()
const {
return count_; }
191 inline Eigen::Array<size_t, Eigen::Dynamic, 1>
Index()
const {
197 TReal min_sqr_dist_to_center_;
198 Eigen::Array<TReal, 3, 1> position_;
199 Eigen::Array<TFeat, Eigen::Dynamic, 1> features_;
200 Eigen::Array<size_t, Eigen::Dynamic, 1> index_;
206 const size_t num_positions,
207 const T*
const positions,
208 const T voxel_size) {
209 typedef Eigen::Array<double, 3, 1> Vec3_t;
210 if (num_positions == 0) {
214 Vec3_t bb_min, bb_max;
215 bb_min << positions[0], positions[1], positions[2];
218 Vec3_t voxel_size3(voxel_size, voxel_size, voxel_size);
220 for (
size_t i = 1; i < num_positions; ++i) {
221 Vec3_t pos(positions[i * 3 + 0], positions[i * 3 + 1],
222 positions[i * 3 + 2]);
223 bb_min = bb_min.min(pos);
224 bb_max = bb_max.max(pos);
228 bb_min /= voxel_size3;
229 bb_min = bb_min.floor() * voxel_size3;
230 bb_max /= voxel_size3;
231 bb_max = bb_max.ceil() * voxel_size3;
233 if (voxel_size *
double(std::numeric_limits<int>::max()) <
235 voxel_size *
double(std::numeric_limits<int>::min()) >
237 err =
"voxel_size is too small\n";
248 template <
class TDerived>
250 const Eigen::ArrayBase<TDerived>& pos,
251 const typename TDerived::Scalar& inv_voxel_size) {
252 typedef typename TDerived::Scalar Scalar_t;
253 Eigen::Array<Scalar_t, 3, 1> ref_coord = pos * inv_voxel_size;
255 Eigen::Vector3i voxel_index;
256 voxel_index = ref_coord.floor().template cast<int>();
261 template <
class TReal,
class TFeat,
class ACCUMULATOR,
class OUTPUT_ALLOCATOR>
263 const TReal*
const inp_positions,
265 const TFeat* inp_features,
267 OUTPUT_ALLOCATOR& output_allocator) {
271 output_allocator.AllocPooledPositions(&out_pos_ptr, 0);
272 output_allocator.AllocPooledFeatures(&out_feat_ptr, 0, in_channels);
276 typedef Eigen::Array<TReal, 3, 1> Vec3_t;
277 typedef Eigen::Array<TFeat, Eigen::Dynamic, 1> FeatureVec_t;
279 std::unordered_map<Eigen::Vector3i, ACCUMULATOR,
281 voxelindex_to_accpoint;
284 Eigen::Vector3i voxel_index;
285 TReal inv_voxel_size = 1 / voxel_size;
286 TReal half_voxel_size = 0.5 * voxel_size;
287 for (
size_t i = 0; i < num_inp; ++i) {
288 Eigen::Map<const Vec3_t> pos(inp_positions + i * 3);
292 voxel_center << voxel_index(0) * voxel_size + half_voxel_size,
293 voxel_index(1) * voxel_size + half_voxel_size,
294 voxel_index(2) * voxel_size + half_voxel_size;
296 Eigen::Map<const FeatureVec_t> feat(inp_features + in_channels * i,
298 voxelindex_to_accpoint[voxel_index].AddPoint(
299 pos.matrix(), voxel_center.matrix(), feat);
302 const size_t num_out = voxelindex_to_accpoint.size();
306 output_allocator.AllocPooledPositions(&out_pos_ptr, num_out);
307 output_allocator.AllocPooledFeatures(&out_feat_ptr, num_out, in_channels);
310 for (
const auto point : voxelindex_to_accpoint) {
311 Vec3_t pos = point.second.Position();
312 Eigen::Map<Vec3_t> out_pos(out_pos_ptr + i * 3);
315 Eigen::Map<FeatureVec_t> out_feat(out_feat_ptr + i * in_channels,
317 out_feat = point.second.Features();
324 template <
class TReal,
class TFeat,
class ACCUMULATOR, AccumulationFn FEAT_FN>
327 const TReal*
const inp_positions,
329 const TFeat*
const inp_features,
331 const TReal*
const pooled_positions,
332 const TFeat*
const pooled_features_gradient,
337 memset(features_backprop, 0,
sizeof(TFeat) * num_inp * in_channels);
339 typedef Eigen::Array<TReal, 3, 1> Vec3_t;
340 typedef Eigen::Array<TFeat, Eigen::Dynamic, 1> FeatureVec_t;
342 Vec3_t voxel_size3(voxel_size, voxel_size, voxel_size);
345 tbb::task_group task_group;
347 std::unordered_map<Eigen::Vector3i, ACCUMULATOR,
349 voxelindex_to_accpoint;
353 Eigen::Vector3i voxel_index;
354 TReal inv_voxel_size = 1 / voxel_size;
355 TReal half_voxel_size = 0.5 * voxel_size;
356 for (
size_t i = 0; i < num_inp; ++i) {
357 Eigen::Map<const Vec3_t> pos(inp_positions + i * 3);
361 voxel_center << voxel_index(0) * voxel_size + half_voxel_size,
362 voxel_index(1) * voxel_size + half_voxel_size,
363 voxel_index(2) * voxel_size + half_voxel_size;
365 Eigen::Map<const FeatureVec_t> feat(inp_features + in_channels * i,
367 voxelindex_to_accpoint[voxel_index].AddPoint(
368 pos.matrix(), voxel_center.matrix(), feat, i);
372 std::unordered_map<Eigen::Vector3i,
size_t,
374 voxelindex_to_gradindex;
377 Eigen::Vector3i voxel_index;
378 TReal inv_voxel_size = 1 / voxel_size;
379 for (
size_t i = 0; i < num_pooled; ++i) {
380 Eigen::Map<const Vec3_t> pos(pooled_positions + i * 3);
384 voxelindex_to_gradindex[voxel_index] = i;
391 Eigen::Vector3i voxel_index;
392 TReal inv_voxel_size = 1 / voxel_size;
393 for (
size_t i = 0; i < num_inp; ++i) {
394 Eigen::Map<const Vec3_t> pos(inp_positions + i * 3);
398 Eigen::Map<FeatureVec_t> feat_bp(
399 features_backprop + in_channels * i, in_channels);
401 size_t grad_idx = voxelindex_to_gradindex[voxel_index];
402 int count = voxelindex_to_accpoint[voxel_index].Count();
403 Eigen::Map<const FeatureVec_t> grad(
404 pooled_features_gradient + in_channels * grad_idx,
406 feat_bp = grad /
count;
411 for (
const auto point : voxelindex_to_accpoint) {
412 size_t idx = point.second.Index()(0);
413 Eigen::Map<FeatureVec_t> feat_bp(
414 features_backprop + in_channels * idx, in_channels);
416 size_t grad_idx = voxelindex_to_gradindex[point.first];
417 Eigen::Map<const FeatureVec_t> grad(
418 pooled_features_gradient + in_channels * grad_idx,
424 if (FEAT_FN ==
MAX) {
425 for (
const auto point : voxelindex_to_accpoint) {
426 size_t grad_idx = voxelindex_to_gradindex[point.first];
427 Eigen::Map<const FeatureVec_t> grad(
428 pooled_features_gradient + in_channels * grad_idx,
430 for (
int i = 0; i < in_channels; ++i) {
431 size_t idx = point.second.Index()(i);
432 Eigen::Map<FeatureVec_t> feat_bp(
433 features_backprop + in_channels * idx, in_channels);
434 feat_bp(i) = grad(i);
484 template <
class TReal,
class TFeat,
class OUTPUT_ALLOCATOR>
486 const TReal*
const inp_positions,
488 const TFeat* inp_features,
490 OUTPUT_ALLOCATOR& output_allocator,
493 #define CALL_TEMPLATE(POS_FN, FEAT_FN) \
494 if (POS_FN == position_fn && FEAT_FN == feature_fn) { \
495 _VoxelPooling<TReal, TFeat, \
496 Accumulator<TReal, TFeat, POS_FN, FEAT_FN>>( \
497 num_inp, inp_positions, in_channels, inp_features, voxel_size, \
529 template <
class TReal,
class TFeat>
532 const TReal*
const inp_positions,
534 const TFeat*
const inp_features,
536 const TReal*
const pooled_positions,
537 const TFeat*
const pooled_features_gradient,
541 #define CALL_TEMPLATE(POS_FN, FEAT_FN) \
542 if (POS_FN == position_fn && FEAT_FN == feature_fn) { \
543 _VoxelPoolingBackprop< \
545 AccumulatorBackprop<TReal, TFeat, POS_FN, FEAT_FN>, FEAT_FN>( \
546 features_backprop, num_inp, inp_positions, in_channels, \
547 inp_features, num_pooled, pooled_positions, \
548 pooled_features_gradient, voxel_size); \
#define CALL_TEMPLATE(POS_FN, FEAT_FN)
Definition: VoxelPooling.h:104
Eigen::Array< TFeat, Eigen::Dynamic, 1 > Features() const
Definition: VoxelPooling.h:180
void AddPoint(const Eigen::MatrixBase< Derived > &pos, const Eigen::MatrixBase< Derived2 > &voxel_center, const Eigen::ArrayBase< Derived3 > &feat, const size_t idx)
Definition: VoxelPooling.h:116
Eigen::Array< TReal, 3, 1 > Position() const
Definition: VoxelPooling.h:171
Eigen::Array< size_t, Eigen::Dynamic, 1 > Index() const
Definition: VoxelPooling.h:191
int Count() const
Definition: VoxelPooling.h:189
AccumulatorBackprop()
Definition: VoxelPooling.h:106
Definition: VoxelPooling.h:27
int Count() const
Definition: VoxelPooling.h:91
void AddPoint(const Eigen::MatrixBase< Derived > &pos, const Eigen::MatrixBase< Derived2 > &voxel_center, const Eigen::ArrayBase< Derived3 > &feat)
Definition: VoxelPooling.h:39
Eigen::Array< TReal, 3, 1 > Position() const
Definition: VoxelPooling.h:73
Accumulator()
Definition: VoxelPooling.h:29
Eigen::Array< TFeat, Eigen::Dynamic, 1 > Features() const
Definition: VoxelPooling.h:82
const char const char value recording_handle imu_sample recording_handle uint8_t size_t data_size k4a_record_configuration_t config target_format k4a_capture_t capture_handle k4a_imu_sample_t imu_sample playback_handle k4a_logging_message_cb_t void min_level device_handle k4a_imu_sample_t timeout_in_ms capture_handle capture_handle capture_handle image_handle temperature_c k4a_image_t image_handle uint8_t image_handle image_handle image_handle image_handle image_handle timestamp_usec white_balance image_handle k4a_device_configuration_t config device_handle char size_t serial_number_size bool int32_t int32_t int32_t int32_t k4a_color_control_mode_t default_mode value const const k4a_calibration_t calibration char size_t
Definition: K4aPlugin.cpp:719
AccumulationFn
Definition: VoxelPooling.h:21
@ CENTER
Definition: VoxelPooling.h:21
@ NEAREST_NEIGHBOR
Definition: VoxelPooling.h:21
@ MAX
Definition: VoxelPooling.h:21
@ AVERAGE
Definition: VoxelPooling.h:21
void VoxelPoolingBackprop(TFeat *features_backprop, size_t num_inp, const TReal *const inp_positions, int in_channels, const TFeat *const inp_features, size_t num_pooled, const TReal *const pooled_positions, const TFeat *const pooled_features_gradient, TReal voxel_size, AccumulationFn position_fn, AccumulationFn feature_fn)
Definition: VoxelPooling.h:530
bool CheckVoxelSize(std::string &err, const size_t num_positions, const T *const positions, const T voxel_size)
Function for debugging. Checks if the voxel size is too small.
Definition: VoxelPooling.h:205
void VoxelPooling(size_t num_inp, const TReal *const inp_positions, int in_channels, const TFeat *inp_features, TReal voxel_size, OUTPUT_ALLOCATOR &output_allocator, AccumulationFn position_fn, AccumulationFn feature_fn)
Definition: VoxelPooling.h:485
void _VoxelPoolingBackprop(TFeat *features_backprop, size_t num_inp, const TReal *const inp_positions, int in_channels, const TFeat *const inp_features, size_t num_pooled, const TReal *const pooled_positions, const TFeat *const pooled_features_gradient, TReal voxel_size)
Definition: VoxelPooling.h:325
void _VoxelPooling(size_t num_inp, const TReal *const inp_positions, int in_channels, const TFeat *inp_features, TReal voxel_size, OUTPUT_ALLOCATOR &output_allocator)
Definition: VoxelPooling.h:262
HOST_DEVICE utility::MiniVec< int, 3 > ComputeVoxelIndex(const TVecf &pos, const typename TVecf::Scalar_t &inv_voxel_size)
Definition: NeighborSearchCommon.h:42
Definition: PinholeCameraIntrinsic.cpp:16