organized_features.hpp
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++) // iterate circles
00085     {
00086       for (it_ci = (*it_c).begin(); it_ci != (*it_c).end(); it_ci++) // iterate current circle
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++) // iterate circles
00097     {
00098       for (it_ci = (*it_c).begin(); it_ci != (*it_c).end(); it_ci++) // iterate current circle
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++) // iterate circles
00134     {
00135       for (it_ci = (*it_c).begin(); it_ci != (*it_c).end(); it_ci++) // iterate current circle
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++) // iterate circles
00149     {
00150       for (it_ci = (*it_c).begin(); it_ci != (*it_c).end(); it_ci++) // iterate current circle
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++) // iterate circles
00195     {
00196       for (it_ci = (*it_c).begin(); it_ci != (*it_c).end(); it_ci++) // iterate current circle
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++) // iterate circles
00211     {
00212       for (it_ci = (*it_c).begin(); it_ci != (*it_c).end(); it_ci++) // iterate current circle
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   // If the dataset is empty, just return
00243   if (input_->points.empty ())
00244   {
00245     PCL_ERROR ("[pcl::%s::compute] input_ is empty!\n", getClassName ().c_str ());
00246     // Cleanup
00247     deinitCompute ();
00248     return (false);
00249   }
00250 
00251   // If no search surface has been defined, use the input dataset as the search surface itself
00252   if (!surface_)
00253   {
00254     fake_surface_ = true;
00255     surface_ = input_;
00256   }
00257 
00258   // Check if input is orgnized
00259   if ( !(surface_->isOrganized () && input_->isOrganized ()) )
00260   {
00261     PCL_ERROR ("[pcl::%s::compute] input_ and surface_ is not organized!\n", getClassName ().c_str ());
00262     // Cleanup
00263     deinitCompute ();
00264     return (false);
00265   }
00266 
00267   // Do a fast check to see if the search parameters are well defined
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     // Cleanup
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       // create a new mask
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   // Reset the surface
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   // Copy the header
00331   output.header = input_->header;
00332 
00333   // Resize the output dataset
00334   if (output.points.size () != indices_->size ())
00335     output.points.resize (indices_->size ());
00336   // Check if the output will be computed for all points or only a subset
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   // Perform the actual feature computation
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   // create a new mask
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


cob_3d_features
Author(s): Georg Arbeiter
autogenerated on Wed Aug 26 2015 11:02:26