Point Cloud Library (PCL)  1.5.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
shot_omp.hpp
Go to the documentation of this file.
00001 /*
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Copyright (c) 2009, Willow Garage, Inc.
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions
00009  *  are met:
00010  *
00011  *   * Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *   * Redistributions in binary form must reproduce the above
00014  *     copyright notice, this list of conditions and the following
00015  *     disclaimer in the documentation and/or other materials provided
00016  *     with the distribution.
00017  *   * Neither the name of Willow Garage, Inc. nor the names of its
00018  *     contributors may be used to endorse or promote products derived
00019  *     from this software without specific prior written permission.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032  *  POSSIBILITY OF SUCH DAMAGE.
00033  *
00034  *
00035  */
00036 
00037 #ifndef PCL_FEATURES_IMPL_SHOT_OMP_H_
00038 #define PCL_FEATURES_IMPL_SHOT_OMP_H_
00039 
00040 #include "pcl/features/shot_omp.h"
00041 
00043 template<typename PointInT, typename PointNT, typename PointOutT> void
00044 pcl::SHOTEstimationOMP<PointInT, PointNT, PointOutT>::computeFeature (PointCloudOut &output)
00045 {
00046   if (threads_ < 0)
00047     threads_ = 1;
00048 
00049   descLength_ = nr_grid_sector_ * (nr_shape_bins_ + 1);
00050 
00051   sqradius_ = search_radius_ * search_radius_;
00052   radius3_4_ = (search_radius_ * 3) / 4;
00053   radius1_4_ = search_radius_ / 4;
00054   radius1_2_ = search_radius_ / 2;
00055 
00056   if (output.points[0].descriptor.size () != (size_t)descLength_)
00057     for (size_t idx = 0; idx < indices_->size (); ++idx)
00058       output.points[idx].descriptor.resize (descLength_);
00059 
00060   int data_size = indices_->size ();
00061   Eigen::VectorXf *shot = new Eigen::VectorXf[threads_];
00062   std::vector<std::vector<Eigen::Vector4f, Eigen::aligned_allocator<Eigen::Vector4f> > > rfs (threads_);
00063   for (size_t i = 0; i < rfs.size (); ++i)
00064     rfs[i].resize (3);
00065 
00066   for (int i = 0; i < threads_; i++)
00067     shot[i].setZero (descLength_);
00068 
00069   // Iterating over the entire index vector
00070   #pragma omp parallel for num_threads(threads_)
00071   for (int idx = 0; idx < data_size; ++idx)
00072   {
00073    // Allocate enough space to hold the results
00074     // \note This resize is irrelevant for a radiusSearch ().
00075     std::vector<int> nn_indices (k_);
00076     std::vector<float> nn_dists (k_);
00077 
00078     this->searchForNeighbors ((*indices_)[idx], search_parameter_, nn_indices, nn_dists);
00079 
00080   // Estimate the SHOT at each patch
00081 #ifdef _OPENMP
00082     int tid = omp_get_thread_num ();
00083 #else
00084     int tid = 0;
00085 #endif
00086   this->computePointSHOT ((*indices_)[idx], nn_indices, nn_dists, shot[tid], rfs[tid]);
00087 
00088   // Copy into the resultant cloud
00089     for (int d = 0; d < shot[tid].size (); ++d)
00090       output.points[idx].descriptor[d] = shot[tid][d];
00091     for (int d = 0; d < 9; ++d)
00092       output.points[idx].rf[d] = rfs[tid][d/3][d % 3];
00093   }
00094   delete[] shot;
00095 }
00096 
00098 template<typename PointNT, typename PointOutT> void
00099 pcl::SHOTEstimationOMP<pcl::PointXYZRGBA, PointNT, PointOutT>::computeFeature (PointCloudOut &output)
00100 {
00101   if (threads_ < 0)
00102     threads_ = 1;
00103 
00104   descLength_ = (b_describe_shape_) ? nr_grid_sector_ * (nr_shape_bins_ + 1) : 0;
00105   descLength_ += (b_describe_color_) ? nr_grid_sector_ * (nr_color_bins_ + 1) : 0;
00106 
00107   sqradius_ = search_radius_ * search_radius_;
00108   radius3_4_ = (search_radius_ * 3) / 4;
00109   radius1_4_ = search_radius_ / 4;
00110   radius1_2_ = search_radius_ / 2;
00111 
00112   if (output.points[0].descriptor.size () != (size_t)descLength_)
00113     for (size_t idx = 0; idx < indices_->size (); ++idx)
00114       output.points[idx].descriptor.resize (descLength_);
00115 
00116   int data_size = indices_->size ();
00117   Eigen::VectorXf *shot = new Eigen::VectorXf[threads_];
00118   std::vector<std::vector<Eigen::Vector4f, Eigen::aligned_allocator<Eigen::Vector4f> > > rfs (threads_);
00119   for (size_t i = 0; i < rfs.size (); ++i)
00120     rfs[i].resize (3);
00121 
00122   for (int i = 0; i < threads_; i++)
00123     shot[i].setZero (descLength_);
00124 
00125   // Iterating over the entire index vector
00126 #pragma omp parallel for num_threads(threads_)
00127   for (int idx = 0; idx < data_size; ++idx)
00128   {
00129     // Allocate enough space to hold the results
00130     // \note This resize is irrelevant for a radiusSearch ().
00131     std::vector<int> nn_indices (k_);
00132     std::vector<float> nn_dists (k_);
00133 
00134     this->searchForNeighbors ((*indices_)[idx], search_parameter_, nn_indices, nn_dists);
00135 
00136     // Estimate the SHOT at each patch
00137 #ifdef _OPENMP
00138     int tid = omp_get_thread_num ();
00139 #else
00140     int tid = 0;
00141 #endif
00142     this->computePointSHOT ((*indices_)[idx], nn_indices, nn_dists, shot[tid], rfs[tid]);
00143 
00144     // Copy into the resultant cloud
00145     for (int d = 0; d < shot[tid].size (); ++d)
00146       output.points[idx].descriptor[d] = shot[tid][d];
00147     for (int d = 0; d < 9; ++d)
00148       output.points[idx].rf[d] = rfs[tid][d / 3][d % 3];
00149   }
00150 
00151   delete[] shot;
00152 }
00153 
00154 #define PCL_INSTANTIATE_SHOTEstimationOMP(T,NT,OutT) template class PCL_EXPORTS pcl::SHOTEstimationOMP<T,NT,OutT>;
00155 
00156 #endif    // PCL_FEATURES_IMPL_SHOT_OMP_H_