Go to the documentation of this file.00001
00063 #ifndef __IMPL_ORGANIZED_FEATURES_H__
00064 #define __IMPL_ORGANIZED_FEATURES_H__
00065
00066 template <typename PointInT, typename PointOutT> int
00067 cob_3d_features::OrganizedFeatures<PointInT,PointOutT>::searchForNeighbors(
00068 int index,
00069 std::vector<int>& indices)
00070 {
00071 int idx;
00072 int idx_x = index % surface_->width;
00073 int idx_y = index * inv_width_;
00074
00075 std::vector<std::vector<int> >::iterator it_c;
00076 std::vector<int>::iterator it_ci;
00077
00078 indices.clear();
00079 indices.reserve((int)(pixel_search_radius_ * pixel_search_radius_));
00080
00081 if (idx_y >= pixel_search_radius_ && idx_y < (int)surface_->height - pixel_search_radius_ &&
00082 idx_x >= pixel_search_radius_ && idx_x < (int)surface_->width - pixel_search_radius_)
00083 {
00084 for (it_c = mask_.begin(); it_c != mask_.end(); it_c++)
00085 {
00086 for (it_ci = (*it_c).begin(); it_ci != (*it_c).end(); it_ci++)
00087 {
00088 idx = index + *it_ci;
00089 if (pcl_isnan(surface_->points[idx].z) ) continue;
00090 indices.push_back(idx);
00091 }
00092 }
00093 }
00094 else
00095 {
00096 for (it_c = mask_.begin(); it_c != mask_.end(); it_c++)
00097 {
00098 for (it_ci = (*it_c).begin(); it_ci != (*it_c).end(); it_ci++)
00099 {
00100 idx = index + *it_ci;
00101 if ( idx < 0 || idx >= (int)surface_->points.size() ) continue;
00102 int v = idx * inv_width_;
00103 if (v < 0 || v >= (int)surface_->height) continue;
00104 if (pcl_isnan(surface_->points[idx].z)) continue;
00105 indices.push_back(idx);
00106 }
00107 }
00108 }
00109 return 1;
00110 }
00111
00112 template <typename PointInT, typename PointOutT> int
00113 cob_3d_features::OrganizedFeatures<PointInT,PointOutT>::searchForNeighborsInRange(
00114 int index,
00115 std::vector<int>& indices)
00116 {
00117 int idx;
00118 int idx_x = index % surface_->width;
00119 int idx_y = index * inv_width_;
00120 const PointInT* p = &(surface_->points[index]);
00121 const PointInT* p_i;
00122 float distance_threshold = skip_distant_point_threshold_ * 0.003 * p->z * p->z;
00123
00124 std::vector<std::vector<int> >::iterator it_c;
00125 std::vector<int>::iterator it_ci;
00126
00127 indices.clear();
00128 indices.reserve(n_points_);
00129
00130 if (idx_y >= pixel_search_radius_ && idx_y < (int)surface_->height - pixel_search_radius_ &&
00131 idx_x >= pixel_search_radius_ && idx_x < (int)surface_->width - pixel_search_radius_)
00132 {
00133 for (it_c = mask_.begin(); it_c != mask_.end(); it_c++)
00134 {
00135 for (it_ci = (*it_c).begin(); it_ci != (*it_c).end(); it_ci++)
00136 {
00137 idx = index + *it_ci;
00138 p_i = &(surface_->points[idx]);
00139 if ( pcl_isnan(p_i->z) ) continue;
00140 if ( fabs(p_i->z - p->z) > distance_threshold ) continue;
00141
00142 indices.push_back(idx);
00143 }
00144 }
00145 }
00146 else
00147 {
00148 for (it_c = mask_.begin(); it_c != mask_.end(); it_c++)
00149 {
00150 for (it_ci = (*it_c).begin(); it_ci != (*it_c).end(); it_ci++)
00151 {
00152 idx = index + *it_ci;
00153 if ( idx < 0 || idx >= (int)surface_->points.size() ) continue;
00154 int v = idx * inv_width_;
00155 if (v < 0 || v >= (int)surface_->height) continue;
00156 p_i = &(surface_->points[idx]);
00157 if ( pcl_isnan(p_i->z) ) continue;
00158 if ( fabs(p_i->z - p->z) > distance_threshold ) continue;
00159
00160 indices.push_back(idx);
00161 }
00162 }
00163 }
00164 if (indices.size() > 1)
00165 return 1;
00166 else
00167 return -1;
00168 }
00169
00170
00171 template <typename PointInT, typename PointOutT> int
00172 cob_3d_features::OrganizedFeatures<PointInT,PointOutT>::searchForNeighborsInRange(
00173 int index,
00174 std::vector<int>& indices,
00175 std::vector<float>& sqr_distances)
00176 {
00177 int idx;
00178 int idx_x = index % surface_->width;
00179 int idx_y = index * inv_width_;
00180 const PointInT* p = &(surface_->points[index]);
00181 const PointInT* p_i;
00182 float distance_threshold = skip_distant_point_threshold_ * 0.003 * p->z * p->z, d_z;
00183 std::vector<std::vector<int> >::iterator it_c;
00184 std::vector<int>::iterator it_ci;
00185
00186 indices.clear();
00187 indices.reserve(n_points_);
00188 sqr_distances.clear();
00189 sqr_distances.reserve(n_points_);
00190
00191 if (idx_y >= pixel_search_radius_ && idx_y < (int)surface_->height - pixel_search_radius_ &&
00192 idx_x >= pixel_search_radius_ && idx_x < (int)surface_->width - pixel_search_radius_)
00193 {
00194 for (it_c = mask_.begin(); it_c != mask_.end(); it_c++)
00195 {
00196 for (it_ci = (*it_c).begin(); it_ci != (*it_c).end(); it_ci++)
00197 {
00198 idx = index + *it_ci;
00199 p_i = &(surface_->points[idx]);
00200 if ( pcl_isnan(p_i->z) ) continue;
00201 if ( (d_z = fabs(p_i->z - p->z)) > distance_threshold ) continue;
00202
00203 indices.push_back(idx);
00204 sqr_distances.push_back(pow(p_i->x - p->x, 2) + pow(p_i->y - p->y, 2) + pow(d_z, 2));
00205 }
00206 }
00207 }
00208 else
00209 {
00210 for (it_c = mask_.begin(); it_c != mask_.end(); it_c++)
00211 {
00212 for (it_ci = (*it_c).begin(); it_ci != (*it_c).end(); it_ci++)
00213 {
00214 idx = index + *it_ci;
00215 if ( idx < 0 || idx >= (int)surface_->points.size() ) continue;
00216 int v = idx * inv_width_;
00217 if (v < 0 || v >= (int)surface_->height) continue;
00218 p_i = &(surface_->points[idx]);
00219 if ( pcl_isnan(p_i->z) ) continue;
00220 if ( (d_z = fabs(p_i->z - p->z)) > distance_threshold ) continue;
00221
00222 indices.push_back(idx);
00223 sqr_distances.push_back(pow(p_i->x - p->x, 2) + pow(p_i->y - p->y, 2) + pow(d_z, 2));
00224 }
00225 }
00226 }
00227 if (indices.size() > 1)
00228 return 1;
00229 else
00230 return -1;
00231 }
00232
00233 template <typename PointInT, typename PointOutT> bool
00234 cob_3d_features::OrganizedFeatures<PointInT,PointOutT>::initCompute()
00235 {
00236 if (!pcl::PCLBase<PointInT>::initCompute ())
00237 {
00238 PCL_ERROR ("[pcl::%s::initCompute] Init failed.\n", getClassName ().c_str ());
00239 return (false);
00240 }
00241
00242
00243 if (input_->points.empty ())
00244 {
00245 PCL_ERROR ("[pcl::%s::compute] input_ is empty!\n", getClassName ().c_str ());
00246
00247 deinitCompute ();
00248 return (false);
00249 }
00250
00251
00252 if (!surface_)
00253 {
00254 fake_surface_ = true;
00255 surface_ = input_;
00256 }
00257
00258
00259 if ( !(surface_->isOrganized () && input_->isOrganized ()) )
00260 {
00261 PCL_ERROR ("[pcl::%s::compute] input_ and surface_ is not organized!\n", getClassName ().c_str ());
00262
00263 deinitCompute ();
00264 return (false);
00265 }
00266
00267
00268 if (pixel_search_radius_ == 0 || pixel_steps_ == 0 || circle_steps_ == 0)
00269 {
00270 PCL_ERROR ("[pcl::%s::compute] Radius not defined! ", getClassName ().c_str ());
00271
00272 deinitCompute ();
00273 return (false);
00274 }
00275 else
00276 {
00277 inv_width_ = 1.0f / surface_->width;
00278 if (mask_changed_)
00279 {
00280 int num_circles = std::floor(pixel_search_radius_ / circle_steps_);
00281 n_points_ = pow(2 * pixel_search_radius_ + 1, 2);
00282
00283 mask_.clear();
00284 for (int circle = 0; circle < num_circles; circle++)
00285 {
00286 int circle_size = pixel_search_radius_ - (circle*circle_steps_);
00287 int dy = circle_size * surface_->width;
00288
00289 std::vector<int> new_circle;
00290
00291 for (int x = circle_size; x >= -circle_size; x -= pixel_steps_)
00292 new_circle.push_back( x - dy );
00293 for (int y = -circle_size+pixel_steps_; y <= circle_size-pixel_steps_; y += pixel_steps_)
00294 new_circle.push_back( -circle_size + y * surface_->width );
00295 for (int x = -circle_size; x <= +circle_size; x += pixel_steps_)
00296 new_circle.push_back( x + dy );
00297 for (int y = circle_size-pixel_steps_; y >= -circle_size+pixel_steps_; y -= pixel_steps_)
00298 new_circle.push_back( circle_size + y * surface_->width );
00299
00300 mask_.push_back(new_circle);
00301 }
00302 }
00303 }
00304
00305 return (true);
00306 }
00307
00308 template <typename PointInT, typename PointOutT> bool
00309 cob_3d_features::OrganizedFeatures<PointInT,PointOutT>::deinitCompute()
00310 {
00311
00312 if (fake_surface_)
00313 {
00314 surface_.reset ();
00315 fake_surface_ = false;
00316 }
00317 return (true);
00318 }
00319
00320 template <typename PointInT, typename PointOutT> void
00321 cob_3d_features::OrganizedFeatures<PointInT,PointOutT>::compute(PointCloudOut &output)
00322 {
00323 if (!initCompute ())
00324 {
00325 output.width = output.height = 0;
00326 output.points.clear ();
00327 return;
00328 }
00329
00330
00331 output.header = input_->header;
00332
00333
00334 if (output.points.size () != indices_->size ())
00335 output.points.resize (indices_->size ());
00336
00337 if (indices_->size () != input_->points.size ())
00338 {
00339 output.width = (int) indices_->size ();
00340 output.height = 1;
00341 }
00342 else
00343 {
00344 output.width = input_->width;
00345 output.height = input_->height;
00346 }
00347 output.is_dense = input_->is_dense;
00348
00349
00350 computeFeature (output);
00351
00352 deinitCompute ();
00353 }
00354
00355 template <typename PointInT, typename PointOutT> void
00356 cob_3d_features::OrganizedFeatures<PointInT,PointOutT>::computeMaskManually(int cloud_width)
00357 {
00358 int num_circles = std::floor(pixel_search_radius_ / circle_steps_);
00359 n_points_ = pow(2 * pixel_search_radius_ + 1, 2);
00360
00361 mask_.clear();
00362 for (int circle = 0; circle < num_circles; circle++)
00363 {
00364 int circle_size = pixel_search_radius_ - (circle*circle_steps_);
00365 int dy = circle_size * cloud_width;
00366
00367 std::vector<int> new_circle;
00368
00369 for (int x = circle_size; x >= -circle_size; x -= pixel_steps_)
00370 new_circle.push_back( x - dy );
00371 for (int y = -circle_size+pixel_steps_; y <= circle_size-pixel_steps_; y += pixel_steps_)
00372 new_circle.push_back( -circle_size + y * cloud_width );
00373 for (int x = -circle_size; x <= +circle_size; x += pixel_steps_)
00374 new_circle.push_back( x + dy );
00375 for (int y = circle_size-pixel_steps_; y >= -circle_size+pixel_steps_; y -= pixel_steps_)
00376 new_circle.push_back( circle_size + y * cloud_width );
00377
00378 mask_.push_back(new_circle);
00379 }
00380 mask_changed_ = false;
00381 }
00382
00383 #endif