45 averageExistingDescriptors(true)
57 averageExistingDescriptors(
Parametrizable::
get<bool>(
"averageExistingDescriptors"))
66 inPlaceFilter(output);
73 const unsigned int numPoints(cloud.
features.cols());
74 const int featDim(cloud.
features.rows());
76 const int timeDim(cloud.
times.rows());
79 assert (featDim == 3 || featDim == 4);
82 if (averageExistingDescriptors)
86 for(
unsigned int i = 0; i < labelDim ; ++i)
88 if (insertDim != descDim)
89 throw InvalidField(
"VoxelGridDataPointsFilter: Error, descriptor labels do not match descriptor data");
100 const T minBoundX = minValues.x() / vSizeX;
101 const T maxBoundX = maxValues.x() / vSizeX;
102 const T minBoundY = minValues.y() / vSizeY;
103 const T maxBoundY = maxValues.y() / vSizeY;
109 minBoundZ = minValues.z() / vSizeZ;
110 maxBoundZ = maxValues.z() / vSizeZ;
115 const unsigned int numDivX = 1 + maxBoundX - minBoundX;
116 const unsigned int numDivY = 1 + maxBoundY - minBoundY;;
117 unsigned int numDivZ = 0;
121 numDivZ = 1 + maxBoundZ - minBoundZ;
123 unsigned int numVox = numDivX * numDivY;
129 throw InvalidParameter(
"VoxelGridDataPointsFilter: The number of voxel couldn't be computed. There might be NaNs in the feature matrix. Use the fileter RemoveNaNDataPointsFilter before this one if it's the case.");
137 std::vector<unsigned int> indices(numPoints);
143 std::vector<Voxel> voxels;
148 voxels = std::vector<Voxel>(numVox);
150 catch (std::bad_alloc&)
152 throw InvalidParameter((boost::format(
"VoxelGridDataPointsFilter: Memory allocation error with %1% voxels. Try increasing the voxel dimensions.") % numVox).str());
155 for (
unsigned int p = 0; p < numPoints; ++p)
157 const unsigned int i = floor(cloud.
features(0,p)/vSizeX - minBoundX);
158 const unsigned int j = floor(cloud.
features(1,p)/vSizeY- minBoundY);
160 unsigned int idx = 0;
163 k = floor(cloud.
features(2,p)/vSizeZ - minBoundZ);
164 idx = i + j * numDivX + k * numDivX * numDivY;
168 idx = i + j * numDivX;
171 const unsigned int pointsInVox = voxels[idx].numPoints + 1;
173 if (pointsInVox == 1)
175 voxels[idx].firstPoint = p;
178 voxels[idx].numPoints = pointsInVox;
186 std::vector<unsigned int> pointsToKeep;
192 for (
unsigned int p = 0; p < numPoints ; ++p)
194 const unsigned int idx = indices[p];
195 const unsigned int firstPoint = voxels[idx].firstPoint;
203 for (
int f = 0; f < (featDim - 1); ++f)
208 if (averageExistingDescriptors)
210 for (
int d = 0; d < descDim; ++d)
214 for (
int d = 0; d < timeDim; ++d)
216 cloud.
times(d,firstPoint) += cloud.
times(d,p);
225 for(
unsigned int idx = 0; idx < numVox; ++idx)
227 const unsigned int numPoints = voxels[idx].numPoints;
228 const unsigned int firstPoint = voxels[idx].firstPoint;
231 for (
int f = 0; f < (featDim - 1); ++f)
232 cloud.
features(f,firstPoint) /= numPoints;
234 if (averageExistingDescriptors)
236 for (
int d = 0; d < descDim; ++d )
238 for (
int d = 0; d < timeDim; ++d )
239 cloud.
times(d,firstPoint) /= numPoints;
241 pointsToKeep.push_back(firstPoint);
248 if (averageExistingDescriptors)
251 for (
unsigned int p = 0; p < numPoints ; ++p)
253 const unsigned int idx = indices[p];
254 const unsigned int firstPoint = voxels[idx].firstPoint;
260 for (
int d = 0; d < descDim; ++d)
264 for (
int d = 0; d < timeDim; ++d)
266 cloud.
times(d,firstPoint) += cloud.
times(d,p);
272 for (
unsigned int idx = 0; idx < numVox; ++idx)
274 const unsigned int numPoints = voxels[idx].numPoints;
275 const unsigned int firstPoint = voxels[idx].firstPoint;
287 k = idx / (numDivX * numDivY);
289 cloud.
features(3,firstPoint) = maxValues.z() - (k-1) * vSizeZ/2;
291 cloud.
features(3,firstPoint) = k * vSizeZ + vSizeZ/2;
294 j = (idx - k * numDivX * numDivY) / numDivX;
296 cloud.
features(2,firstPoint) = maxValues.y() - (j-1) * vSizeY/2;
298 cloud.
features(2,firstPoint) = j * vSizeY + vSizeY / 2;
300 i = idx - k * numDivX * numDivY - j * numDivX;
302 cloud.
features(1,firstPoint) = maxValues.x() - (i-1) * vSizeX/2;
304 cloud.
features(1,firstPoint) = i * vSizeX + vSizeX / 2;
307 if (averageExistingDescriptors)
309 for (
int d = 0; d < descDim; ++d)
311 for (
int d = 0; d < timeDim; ++d)
312 cloud.
times(d,firstPoint) /= numPoints;
314 pointsToKeep.push_back(firstPoint);
322 std::sort(pointsToKeep.begin(), pointsToKeep.end());
323 int numPtsOut = pointsToKeep.size();
324 for (
int i = 0; i < numPtsOut; ++i)
326 const int k = pointsToKeep[i];
331 if (cloud.
times.rows() != 0)