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;
120 const std::optional<core::Tensor> &mask,
121 const std::optional<core::Tensor> &map_info_idx_to_point_idx) {
124 const int64_t n_points =
points.GetLength();
126 const bool filter_fpfh =
127 mask.has_value() && map_info_idx_to_point_idx.has_value();
128 if (mask.has_value() ^ map_info_idx_to_point_idx.has_value()) {
130 "Parameters mask and map_info_idx_to_point_idx must "
131 "either be both provided or both not provided.");
134 if (mask.value().GetShape()[0] != n_points) {
136 "Parameter mask was provided, but its size {:d} should"
137 "be equal to the number of points {:d}.",
138 (
int)mask.value().GetShape()[0], n_points);
140 if (map_info_idx_to_point_idx.value().GetShape()[0] !=
141 counts.GetShape()[0] - (
indices.GetShape().size() == 1 ? 1 : 0)) {
143 "Parameter map_info_idx_to_point_idx was provided, "
145 "{:d} should be equal to the size of counts {:d}.",
146 (
int)map_info_idx_to_point_idx.value().GetShape()[0],
147 (
int)counts.GetShape()[0]);
152 map_info_idx_to_point_idx.value_or(
160 const int32_t n_fpfh =
161 filter_fpfh ? map_fpfh_idx_to_point_idx.
GetLength() : n_points;
162 const int32_t n_spfh =
163 filter_fpfh ? map_spfh_info_idx_to_point_idx.
GetLength() : n_points;
173 {map_spfh_info_idx_to_point_idx},
177 map_point_idx_to_spfh_idx =
183 bool is_radius_search;
185 if (
indices.GetShape().size() == 1) {
186 is_radius_search =
true;
188 is_radius_search =
false;
189 nn_size =
indices.GetShape()[1];
193 const scalar_t *points_ptr =
points.GetDataPtr<scalar_t>();
194 const scalar_t *normals_ptr =
normals.GetDataPtr<scalar_t>();
195 const int32_t *indices_ptr =
indices.GetDataPtr<int32_t>();
196 const scalar_t *distance2_ptr = distance2.GetDataPtr<scalar_t>();
197 const int32_t *counts_ptr = counts.GetDataPtr<int32_t>();
198 scalar_t *spfhs_ptr = spfhs.
GetDataPtr<scalar_t>();
199 scalar_t *fpfhs_ptr = fpfhs.GetDataPtr<scalar_t>();
200 const int64_t *map_spfh_info_idx_to_point_idx_ptr =
201 map_spfh_info_idx_to_point_idx.
GetDataPtr<int64_t>();
202 const int64_t *map_fpfh_idx_to_point_idx_ptr =
203 map_fpfh_idx_to_point_idx.
GetDataPtr<int64_t>();
204 const int64_t *map_point_idx_to_spfh_idx_ptr =
205 map_point_idx_to_spfh_idx.
GetDataPtr<int64_t>();
209 points.GetDevice(), n_spfh,
211 int64_t workload_point_idx =
212 filter_fpfh ? map_spfh_info_idx_to_point_idx_ptr
215 int64_t idx = 3 * workload_point_idx;
216 const scalar_t *
point = points_ptr + idx;
217 const scalar_t *normal = normals_ptr + idx;
219 const int indice_size =
220 is_radius_search ? (counts_ptr[workload_idx + 1] -
221 counts_ptr[workload_idx])
222 : counts_ptr[workload_idx];
224 if (indice_size > 1) {
225 const scalar_t hist_incr =
226 100.0 /
static_cast<scalar_t
>(indice_size - 1);
227 for (
int i = 1; i < indice_size; i++) {
228 const int point_idx =
232 counts_ptr[workload_idx]]
233 : indices_ptr[workload_idx *
237 const scalar_t *point_ref =
238 points_ptr + 3 * point_idx;
239 const scalar_t *normal_ref =
240 normals_ptr + 3 * point_idx;
241 scalar_t fea[4] = {0};
242 ComputePairFeature<scalar_t>(
243 point, normal, point_ref, normal_ref, fea);
244 UpdateSPFHFeature<scalar_t>(fea, workload_idx,
245 hist_incr, spfhs_ptr);
252 points.GetDevice(), n_fpfh,
254 int64_t workload_spfh_idx =
255 filter_fpfh ? map_point_idx_to_spfh_idx_ptr
256 [map_fpfh_idx_to_point_idx_ptr
259 const int indice_size =
261 ? (counts_ptr[workload_spfh_idx + 1] -
262 counts_ptr[workload_spfh_idx])
263 : counts_ptr[workload_spfh_idx];
264 if (indice_size > 1) {
265 scalar_t sum[3] = {0.0, 0.0, 0.0};
266 for (
int i = 1; i < indice_size; i++) {
269 ? i + counts_ptr[workload_spfh_idx]
270 : workload_spfh_idx * nn_size + i;
271 const scalar_t
dist = distance2_ptr[idx];
272 if (
dist == 0.0)
continue;
273 const int32_t spfh_idx =
274 filter_fpfh ? map_point_idx_to_spfh_idx_ptr
277 for (
int j = 0; j < 33; j++) {
279 spfhs_ptr[spfh_idx * 33 + j] /
dist;
281 fpfhs_ptr[workload_idx * 33 + j] += val;
284 for (
int j = 0; j < 3; j++) {
285 sum[j] = sum[j] != 0.0 ? 100.0 / sum[j] : 0.0;
287 for (
int j = 0; j < 33; j++) {
288 fpfhs_ptr[workload_idx * 33 + j] *= sum[j / 11];
289 fpfhs_ptr[workload_idx * 33 + j] +=
290 spfhs_ptr[workload_spfh_idx * 33 + j];
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 std::optional< core::Tensor > &mask=std::nullopt, const std::optional< core::Tensor > &map_batch_info_idx_to_point_idx=std::nullopt)
Definition FeatureImpl.h:114