@@ -82,21 +82,19 @@ namespace jsk_pcl_ros
82
82
83
83
void OrganizedStatisticalOutlierRemoval::filterCloud (
84
84
const pcl::PCLPointCloud2::Ptr pcl_cloud,
85
- pcl::PointIndices ::Ptr pcl_indices_filtered ,
85
+ pcl::PCLPointCloud2 ::Ptr pcl_cloud_filtered ,
86
86
bool keep_organized)
87
87
{
88
- #if PCL_VERSION_COMPARE (<, 1, 9, 0)
89
- pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
90
- pcl::fromPCLPointCloud2 (*pcl_cloud, *cloud);
91
88
if (keep_organized) {
89
+ pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
90
+ pcl::fromPCLPointCloud2 (*pcl_cloud, *cloud);
92
91
// Initialize the spatial locator
93
92
pcl::search::Search<pcl::PointXYZ>::Ptr tree;
94
93
tree.reset (new pcl::search::OrganizedNeighbor<pcl::PointXYZ> ());
95
94
tree->setInputCloud (cloud);
96
95
97
96
// Allocate enough space to hold the results
98
97
std::vector<int > indices (cloud->size ());
99
- std::vector<int > indices_filtered;
100
98
std::vector<int > nn_indices (mean_k_);
101
99
std::vector<float > nn_dists (mean_k_);
102
100
std::vector<float > distances (indices.size ());
@@ -142,6 +140,9 @@ namespace jsk_pcl_ros
142
140
double distance_threshold = mean + std_mul_ * stddev; // a distance that is bigger than this signals an outlier
143
141
144
142
// Build a new cloud by neglecting outliers
143
+ int nr_p = 0 ;
144
+ int nr_removed_p = 0 ;
145
+ bool remove_point = false ;
145
146
for (int cp = 0 ; cp < static_cast <int > (indices.size ()); ++cp)
146
147
{
147
148
bool remove_point = false ;
@@ -153,12 +154,22 @@ namespace jsk_pcl_ros
153
154
{
154
155
remove_point = (distances[cp] > distance_threshold);
155
156
}
156
- if (!remove_point)
157
+
158
+ if (remove_point)
157
159
{
158
- indices_filtered.push_back (indices[cp]);
160
+ /* Set the current point to NaN. */
161
+ *(reinterpret_cast <float *>(&pcl_cloud_filtered->data [nr_p * pcl_cloud_filtered->point_step ])+0 ) = std::numeric_limits<float >::quiet_NaN ();
162
+ *(reinterpret_cast <float *>(&pcl_cloud_filtered->data [nr_p * pcl_cloud_filtered->point_step ])+1 ) = std::numeric_limits<float >::quiet_NaN ();
163
+ *(reinterpret_cast <float *>(&pcl_cloud_filtered->data [nr_p * pcl_cloud_filtered->point_step ])+2 ) = std::numeric_limits<float >::quiet_NaN ();
159
164
}
165
+ else
166
+ {
167
+ memcpy (&pcl_cloud_filtered->data [nr_p * pcl_cloud_filtered->point_step ],
168
+ &pcl_cloud->data [indices[cp] * pcl_cloud_filtered->point_step ],
169
+ pcl_cloud_filtered->point_step );
170
+ }
171
+ nr_p++;
160
172
}
161
- pcl_indices_filtered->indices = indices_filtered;
162
173
}
163
174
else
164
175
{
@@ -167,9 +178,16 @@ namespace jsk_pcl_ros
167
178
sor.setMeanK (mean_k_);
168
179
sor.setStddevMulThresh (std_mul_);
169
180
sor.setNegative (negative_);
170
- sor.filter (pcl_indices_filtered-> indices );
181
+ sor.filter (*pcl_cloud_filtered );
171
182
}
172
- #else
183
+ }
184
+
185
+ void OrganizedStatisticalOutlierRemoval::filterIndices (
186
+ const pcl::PCLPointCloud2::Ptr pcl_cloud,
187
+ pcl::PointIndices::Ptr pcl_indices_filtered,
188
+ bool keep_organized)
189
+ {
190
+ #if PCL_VERSION_COMPARE (>=, 1, 9, 0)
173
191
pcl::StatisticalOutlierRemoval<pcl::PCLPointCloud2> sor;
174
192
sor.setInputCloud (pcl_cloud);
175
193
sor.setMeanK (mean_k_);
@@ -190,15 +208,15 @@ namespace jsk_pcl_ros
190
208
NODELET_ERROR (" keep_organized parameter is true, but input pointcloud is not organized." );
191
209
}
192
210
bool keep_organized = keep_organized_ && !msg->is_dense ;
211
+ // filter
212
+ #if PCL_VERSION_COMPARE (>=, 1, 9, 0)
193
213
pcl::PCLPointCloud2::Ptr pcl_cloud (new pcl::PCLPointCloud2);
194
214
pcl_conversions::toPCL (*msg, *pcl_cloud);
195
-
196
- // filter
197
215
pcl::PointIndices::Ptr pcl_indices_filtered (new pcl::PointIndices ());
198
216
pcl_indices_filtered->indices .resize (pcl_cloud->data .size ());
199
- OrganizedStatisticalOutlierRemoval::filterCloud (pcl_cloud,
200
- pcl_indices_filtered,
201
- keep_organized);
217
+ OrganizedStatisticalOutlierRemoval::filterIndices (pcl_cloud,
218
+ pcl_indices_filtered,
219
+ keep_organized);
202
220
pcl::PCLPointCloud2::Ptr pcl_cloud_filtered (new pcl::PCLPointCloud2);
203
221
pcl::ExtractIndices<pcl::PCLPointCloud2> ex;
204
222
ex.setInputCloud (pcl_cloud);
@@ -207,17 +225,22 @@ namespace jsk_pcl_ros
207
225
ex.setIndices (pcl_indices_filtered);
208
226
ex.filter (*pcl_cloud_filtered);
209
227
pcl_conversions::fromPCL (*pcl_cloud_filtered, output);
210
- #if PCL_VERSION_COMPARE (<, 1, 9, 0)
211
- if (keep_organized) {
212
- // Copy the common fields
213
- output.is_bigendian = msg->is_bigendian ;
214
- output.fields = msg->fields ;
215
- output.point_step = msg->point_step ;
216
- output.data .resize (msg->data .size ());
217
- output.width = msg->width ;
218
- output.height = msg->height ;
219
- output.row_step = msg->point_step * msg->width ;
220
- }
228
+ #else
229
+ pcl::PCLPointCloud2::Ptr pcl_cloud (new pcl::PCLPointCloud2);
230
+ pcl_conversions::toPCL (*msg, *pcl_cloud);
231
+ pcl::PCLPointCloud2::Ptr pcl_cloud_filtered (new pcl::PCLPointCloud2);
232
+ // Copy the common fields
233
+ pcl_cloud_filtered->is_bigendian = msg->is_bigendian ;
234
+ pcl_cloud_filtered->fields = msg->fields ;
235
+ pcl_cloud_filtered->point_step = msg->point_step ;
236
+ pcl_cloud_filtered->data .resize (msg->data .size ());
237
+ pcl_cloud_filtered->width = msg->width ;
238
+ pcl_cloud_filtered->height = msg->height ;
239
+ pcl_cloud_filtered->row_step = msg->point_step * msg->width ;
240
+ OrganizedStatisticalOutlierRemoval::filterCloud (pcl_cloud,
241
+ pcl_cloud_filtered,
242
+ keep_organized);
243
+ pcl_conversions::fromPCL (*pcl_cloud_filtered, output);
221
244
#endif
222
245
output.header = msg->header ;
223
246
output.is_dense = !keep_organized;
0 commit comments