24 template <
typename scalar_t>
30 scalar_t dp2p1[3], n1_copy[3], n2_copy[3];
31 dp2p1[0] = p2[0] - p1[0];
32 dp2p1[1] = p2[1] - p1[1];
33 dp2p1[2] = p2[2] - p1[2];
34 feature[3] = sqrt(dp2p1[0] * dp2p1[0] + dp2p1[1] * dp2p1[1] +
36 if (feature[3] == 0) {
46 if (acos(fabs(angle1)) > acos(fabs(angle2))) {
69 const scalar_t v_norm = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
87 template <
typename scalar_t>
93 static_cast<int>(
floor(11 * (feature[0] + M_PI) / (2.0 * M_PI)));
94 h_index1 = h_index1 >= 11 ? 10 : max(0, h_index1);
96 int h_index2 =
static_cast<int>(
floor(11 * (feature[1] + 1.0) * 0.5));
97 h_index2 = h_index2 >= 11 ? 10 : max(0, h_index2);
99 int h_index3 =
static_cast<int>(
floor(11 * (feature[2] + 1.0) * 0.5));
100 h_index3 = h_index3 >= 11 ? 10 : max(0, h_index3);
102 spfh[idx * 33 + h_index1] += hist_incr;
103 spfh[idx * 33 + h_index2 + 11] += hist_incr;
104 spfh[idx * 33 + h_index3 + 22] += hist_incr;
107 #if defined(__CUDACC__)
108 void ComputeFPFHFeatureCUDA
122 const int64_t n_points =
points.GetLength();
124 const bool filter_fpfh =
125 mask.has_value() && map_info_idx_to_point_idx.has_value();
126 if (mask.has_value() ^ map_info_idx_to_point_idx.has_value()) {
128 "Parameters mask and map_info_idx_to_point_idx must "
129 "either be both provided or both not provided.");
132 if (mask.value().GetShape()[0] != n_points) {
134 "Parameter mask was provided, but its size {:d} should"
135 "be equal to the number of points {:d}.",
136 (
int)mask.value().GetShape()[0], n_points);
138 if (map_info_idx_to_point_idx.value().GetShape()[0] !=
139 counts.GetShape()[0] - (indices.GetShape().size() == 1 ? 1 : 0)) {
141 "Parameter map_info_idx_to_point_idx was provided, "
143 "{:d} should be equal to the size of counts {:d}.",
144 (
int)map_info_idx_to_point_idx.value().GetShape()[0],
145 (
int)counts.GetShape()[0]);
150 map_info_idx_to_point_idx.value_or(
159 filter_fpfh ? map_fpfh_idx_to_point_idx.
GetLength() : n_points;
161 filter_fpfh ? map_spfh_info_idx_to_point_idx.
GetLength() : n_points;
171 {map_spfh_info_idx_to_point_idx},
175 map_point_idx_to_spfh_idx =
181 bool is_radius_search;
183 if (indices.GetShape().size() == 1) {
184 is_radius_search =
true;
186 is_radius_search =
false;
187 nn_size = indices.GetShape()[1];
191 const scalar_t *points_ptr =
points.GetDataPtr<scalar_t>();
192 const scalar_t *normals_ptr = normals.GetDataPtr<scalar_t>();
194 const scalar_t *distance2_ptr = distance2.GetDataPtr<scalar_t>();
196 scalar_t *spfhs_ptr = spfhs.
GetDataPtr<scalar_t>();
197 scalar_t *fpfhs_ptr = fpfhs.GetDataPtr<scalar_t>();
198 const int64_t *map_spfh_info_idx_to_point_idx_ptr =
199 map_spfh_info_idx_to_point_idx.
GetDataPtr<int64_t>();
200 const int64_t *map_fpfh_idx_to_point_idx_ptr =
201 map_fpfh_idx_to_point_idx.
GetDataPtr<int64_t>();
202 const int64_t *map_point_idx_to_spfh_idx_ptr =
203 map_point_idx_to_spfh_idx.
GetDataPtr<int64_t>();
207 points.GetDevice(), n_spfh,
209 int64_t workload_point_idx =
210 filter_fpfh ? map_spfh_info_idx_to_point_idx_ptr
213 int64_t idx = 3 * workload_point_idx;
214 const scalar_t *
point = points_ptr + idx;
215 const scalar_t *normal = normals_ptr + idx;
217 const int indice_size =
218 is_radius_search ? (counts_ptr[workload_idx + 1] -
219 counts_ptr[workload_idx])
220 : counts_ptr[workload_idx];
222 if (indice_size > 1) {
223 const scalar_t hist_incr =
224 100.0 /
static_cast<scalar_t
>(indice_size - 1);
225 for (
int i = 1; i < indice_size; i++) {
226 const int point_idx =
230 counts_ptr[workload_idx]]
231 : indices_ptr[workload_idx *
235 const scalar_t *point_ref =
236 points_ptr + 3 * point_idx;
237 const scalar_t *normal_ref =
238 normals_ptr + 3 * point_idx;
239 scalar_t fea[4] = {0};
240 ComputePairFeature<scalar_t>(
241 point, normal, point_ref, normal_ref, fea);
242 UpdateSPFHFeature<scalar_t>(fea, workload_idx,
243 hist_incr, spfhs_ptr);
250 points.GetDevice(), n_fpfh,
252 int64_t workload_spfh_idx =
253 filter_fpfh ? map_point_idx_to_spfh_idx_ptr
254 [map_fpfh_idx_to_point_idx_ptr
257 const int indice_size =
259 ? (counts_ptr[workload_spfh_idx + 1] -
260 counts_ptr[workload_spfh_idx])
261 : counts_ptr[workload_spfh_idx];
262 if (indice_size > 1) {
263 scalar_t sum[3] = {0.0, 0.0, 0.0};
264 for (
int i = 1; i < indice_size; i++) {
267 ? i + counts_ptr[workload_spfh_idx]
268 : workload_spfh_idx * nn_size + i;
269 const scalar_t dist = distance2_ptr[idx];
270 if (dist == 0.0)
continue;
272 filter_fpfh ? map_point_idx_to_spfh_idx_ptr
275 for (
int j = 0; j < 33; j++) {
277 spfhs_ptr[spfh_idx * 33 + j] / dist;
279 fpfhs_ptr[workload_idx * 33 + j] += val;
282 for (
int j = 0; j < 3; j++) {
283 sum[j] = sum[j] != 0.0 ? 100.0 / sum[j] : 0.0;
285 for (
int j = 0; j < 33; j++) {
286 fpfhs_ptr[workload_idx * 33 + j] *= sum[j / 11];
287 fpfhs_ptr[workload_idx * 33 + j] +=
288 spfhs_ptr[workload_spfh_idx * 33 + j];
#define OPEN3D_HOST_DEVICE
Definition: CUDAUtils.h:44
#define OPEN3D_DEVICE
Definition: CUDAUtils.h:45
#define DISPATCH_FLOAT_DTYPE_TO_TEMPLATE(DTYPE,...)
Definition: Dispatch.h:77
#define LogError(...)
Definition: Logging.h:51
double t
Definition: SurfaceReconstructionPoisson.cpp:172
Point< Real, 3 > point
Definition: SurfaceReconstructionPoisson.cpp:163
T * GetDataPtr()
Definition: Tensor.h:1143
Tensor NonZero() const
Definition: Tensor.cpp:1723
static Tensor Empty(const SizeVector &shape, Dtype dtype, const Device &device=Device("CPU:0"))
Create a tensor with uninitialized values.
Definition: Tensor.cpp:368
static Tensor Arange(const Scalar start, const Scalar stop, const Scalar step=1, const Dtype dtype=core::Int64, const Device &device=core::Device("CPU:0"))
Create a 1D tensor with evenly spaced values in the given interval.
Definition: Tensor.cpp:404
int64_t GetLength() const
Definition: Tensor.h:1124
static Tensor Full(const SizeVector &shape, T fill_value, Dtype dtype, const Device &device=Device("CPU:0"))
Create a tensor fill with specified value.
Definition: Tensor.h:252
static Tensor Zeros(const SizeVector &shape, Dtype dtype, const Device &device=Device("CPU:0"))
Create a tensor fill with zeros.
Definition: Tensor.cpp:374
Tensor GetItem(const TensorKey &tk) const
Definition: Tensor.cpp:441
void IndexSet(const std::vector< Tensor > &index_tensors, const Tensor &src_tensor)
Advanced indexing getter.
Definition: Tensor.cpp:904
static TensorKey Index(int64_t index)
Definition: TensorKey.cpp:133
Definition: Optional.h:259
OPEN3D_HOST_DEVICE OPEN3D_FORCE_INLINE void cross_3x1(const scalar_t *A_3x1_input, const scalar_t *B_3x1_input, scalar_t *C_3x1_output)
Definition: Matrix.h:63
OPEN3D_HOST_DEVICE OPEN3D_FORCE_INLINE scalar_t dot_3x1(const scalar_t *A_3x1_input, const scalar_t *B_3x1_input)
Definition: Matrix.h:89
const Dtype Int64
Definition: Dtype.cpp:47
void ParallelFor(const Device &device, int64_t n, const func_t &func)
Definition: ParallelFor.h:108
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 int32_t
Definition: K4aPlugin.cpp:395
OPEN3D_HOST_DEVICE void ComputePairFeature(const scalar_t *p1, const scalar_t *n1, const scalar_t *p2, const scalar_t *n2, scalar_t *feature)
Definition: FeatureImpl.h:25
void ComputeFPFHFeatureCPU(const core::Tensor &points, const core::Tensor &normals, const core::Tensor &indices, const core::Tensor &distance2, const core::Tensor &counts, core::Tensor &fpfhs, const utility::optional< core::Tensor > &mask=utility::nullopt, const utility::optional< core::Tensor > &map_batch_info_idx_to_point_idx=utility::nullopt)
Definition: FeatureImpl.h:112
OPEN3D_HOST_DEVICE void UpdateSPFHFeature(const scalar_t *feature, int64_t idx, scalar_t hist_incr, scalar_t *spfh)
Definition: FeatureImpl.h:88
FN_SPECIFIERS MiniVec< float, N > floor(const MiniVec< float, N > &a)
Definition: MiniVec.h:75
Definition: PinholeCameraIntrinsic.cpp:16