$search
00001 /********************************************************************* 00002 * Software License Agreement (BSD License) 00003 * 00004 * Copyright (c) 2009, Willow Garage 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 the Willow Garage 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 #include <ias_descriptors_3d/descriptor_3d.h> 00036 00037 using namespace std; 00038 00039 // -------------------------------------------------------------- 00040 /* See function definition */ 00041 // -------------------------------------------------------------- 00042 Descriptor3D::Descriptor3D() 00043 { 00044 result_size_ = 0; 00045 result_size_defined_ = false; 00046 debug_ = false; 00047 } 00048 00049 // -------------------------------------------------------------- 00050 /* See function definition */ 00051 // -------------------------------------------------------------- 00052 Descriptor3D::~Descriptor3D() 00053 { 00054 } 00055 00056 00057 // -------------------------------------------------------------- 00058 /* See function definition */ 00059 // -------------------------------------------------------------- 00060 void Descriptor3D::compute(const sensor_msgs::PointCloud& data, 00061 cloud_kdtree::KdTree& data_kdtree, 00062 const std::vector<const geometry_msgs::Point32*>& interest_pts, 00063 std::vector<std::vector<float> >& results) 00064 { 00065 // ---------------------------------------- 00066 // Allocate the results to be 0 vectors for each interest point 00067 unsigned int nbr_interest_pts = interest_pts.size(); 00068 results.clear(); 00069 results.resize(nbr_interest_pts); 00070 00071 if (result_size_defined_ == false) 00072 { 00073 ROS_ERROR("Descriptor3D::compute result size not defined yet"); 00074 return; 00075 } 00076 00077 if (precompute(data, data_kdtree, interest_pts) < 0) 00078 { 00079 return; 00080 } 00081 00082 return doComputation(data, data_kdtree, interest_pts, results); 00083 } 00084 00085 // -------------------------------------------------------------- 00086 /* See function definition */ 00087 // -------------------------------------------------------------- 00088 void Descriptor3D::compute(const sensor_msgs::PointCloud& data, 00089 cloud_kdtree::KdTree& data_kdtree, 00090 const std::vector<const vector<int>*>& interest_region_indices, 00091 std::vector<std::vector<float> >& results) 00092 { 00093 // ---------------------------------------- 00094 // Allocate the results to be 0 vectors for each interest region 00095 unsigned int nbr_interest_regions = interest_region_indices.size(); 00096 results.clear(); 00097 results.resize(nbr_interest_regions); 00098 00099 if (result_size_defined_ == false) 00100 { 00101 ROS_ERROR("Descriptor3D::compute result size not defined yet"); 00102 return; 00103 } 00104 00105 if (precompute(data, data_kdtree, interest_region_indices) < 0) 00106 { 00107 return; 00108 } 00109 00110 return doComputation(data, data_kdtree, interest_region_indices, results); 00111 } 00112 00113 // -------------------------------------------------------------- 00114 /* See function definition */ 00115 // -------------------------------------------------------------- 00116 void Descriptor3D::concatenateFeatures(const vector<std::vector<std::vector<float> > >& all_descriptor_results, 00117 const unsigned int nbr_samples, 00118 const unsigned int nbr_concatenated_vals, 00119 vector<boost::shared_array<const float> >& concatenated_features) 00120 { 00121 concatenated_features.assign(nbr_samples, boost::shared_array<const float>(NULL)); 00122 unsigned int nbr_descriptors = all_descriptor_results.size(); 00123 00124 // ---------------------------------------------- 00125 // Iterate over each interest point and compute all feature descriptors 00126 // If all descriptor computations are successful, then concatenate all values into 1 array 00127 int int_nbr_samples = static_cast<int> (nbr_samples); 00128 #pragma omp parallel for 00129 for (int i = 0 ; i < int_nbr_samples ; i++) 00130 { 00131 // -------------------------------- 00132 // Verify all features for the point were computed successfully 00133 bool all_features_success = true; // flag if all descriptors were computed correctly 00134 for (unsigned int j = 0 ; all_features_success && j < nbr_descriptors ; j++) 00135 { 00136 // Get the computed features vector for all interest samples 00137 const std::vector<std::vector<float> >& curr_descriptor_for_cloud = all_descriptor_results[j]; 00138 00139 // Get the computed feature for current sample 00140 const std::vector<float>& curr_feature_vals = 00141 curr_descriptor_for_cloud[static_cast<size_t> (i)]; 00142 00143 // non-zero descriptor length indicates computed successfully 00144 unsigned int curr_nbr_feature_vals = curr_feature_vals.size(); 00145 all_features_success = curr_nbr_feature_vals != 0; 00146 } 00147 00148 // -------------------------------- 00149 // If all successful, then concatenate feature values into one vector 00150 if (all_features_success) 00151 { 00152 // allocate 00153 float* curr_sample_concat_feats = new float[nbr_concatenated_vals]; 00154 00155 // concatenate each descriptors' values together 00156 unsigned int prev_val_idx = 0; // offset when copying into concat_features 00157 for (unsigned int j = 0 ; j < nbr_descriptors ; j++) 00158 { 00159 // retrieve descriptor values for current point 00160 const std::vector<std::vector<float> >& curr_descriptor_for_cloud = all_descriptor_results[j]; 00161 const std::vector<float>& curr_sample_descriptor_vals = 00162 curr_descriptor_for_cloud[static_cast<size_t> (i)]; 00163 unsigned int curr_nbr_feature_vals = curr_sample_descriptor_vals.size(); 00164 00165 // copy descriptor values into concatenated vector at correct location 00166 memcpy(curr_sample_concat_feats + prev_val_idx, &*curr_sample_descriptor_vals.begin(), 00167 sizeof(float) * curr_nbr_feature_vals); 00168 00169 // skip over all computed features so far 00170 prev_val_idx += curr_nbr_feature_vals; 00171 } 00172 00173 // Save it 00174 concatenated_features[i].reset(static_cast<const float*> (curr_sample_concat_feats)); 00175 } 00176 // Otherwise features not successful 00177 else 00178 { 00179 ROS_DEBUG("Descriptor3D::concatenateFeatures() skipping sample %u", i); 00180 } 00181 } 00182 00183 return; 00184 } 00185 00186 // -------------------------------------------------------------- 00187 /* See function definition */ 00188 // -------------------------------------------------------------- 00189 unsigned int Descriptor3D::computeAndConcatFeatures(const sensor_msgs::PointCloud& data, 00190 cloud_kdtree::KdTree& data_kdtree, 00191 const std::vector<const geometry_msgs::Point32*>& interest_pts, 00192 vector<Descriptor3D*>& descriptors_3d, 00193 vector<boost::shared_array<const float> >& concatenated_features) 00194 00195 { 00196 // ---------------------------------------------- 00197 // Clear out any shared information from previous compute() calls 00198 unsigned int nbr_descriptors = descriptors_3d.size(); 00199 for (unsigned int i = 0 ; i < nbr_descriptors ; i++) 00200 { 00201 if (descriptors_3d[i] == NULL) 00202 { 00203 ROS_ERROR("Descriptor3D::computeAndConcatFeatures() gave NULL descriptor for interest points"); 00204 return 0; 00205 } 00206 descriptors_3d[i]->clearShared(); 00207 } 00208 00209 // ---------------------------------------------- 00210 // Iterate over each descriptor and compute features for each point in the point cloud 00211 vector<std::vector<std::vector<float> > > all_descriptor_results(nbr_descriptors); 00212 unsigned int nbr_concatenated_vals = 0; 00213 for (unsigned int i = 0 ; i < nbr_descriptors ; i++) 00214 { 00215 descriptors_3d[i]->compute(data, data_kdtree, interest_pts, all_descriptor_results[i]); 00216 00217 nbr_concatenated_vals += (descriptors_3d[i])->getResultSize(); 00218 00219 ROS_DEBUG("Interest point descriptor has %u values", descriptors_3d[i]->getResultSize()); 00220 } 00221 00222 concatenateFeatures(all_descriptor_results, interest_pts.size(), nbr_concatenated_vals, 00223 concatenated_features); 00224 return nbr_concatenated_vals; 00225 } 00226 00227 // -------------------------------------------------------------- 00228 /* See function definition */ 00229 // -------------------------------------------------------------- 00230 unsigned int Descriptor3D::computeAndConcatFeatures(const sensor_msgs::PointCloud& data, 00231 cloud_kdtree::KdTree& data_kdtree, 00232 const std::vector<const vector<int>*>& interest_region_indices, 00233 vector<Descriptor3D*>& descriptors_3d, 00234 vector<boost::shared_array<const float> >& concatenated_features) 00235 00236 { 00237 // ---------------------------------------------- 00238 // Clear out any shared information from previous compute() calls 00239 unsigned int nbr_descriptors = descriptors_3d.size(); 00240 for (unsigned int i = 0 ; i < nbr_descriptors ; i++) 00241 { 00242 if (descriptors_3d[i] == NULL) 00243 { 00244 ROS_ERROR("Descriptor3D::computeAndConcatFeatures() gave NULL descriptor for interest points"); 00245 return 0; 00246 } 00247 descriptors_3d[i]->clearShared(); 00248 } 00249 00250 // ---------------------------------------------- 00251 // Iterate over each descriptor and compute features for each point in the point cloud 00252 vector<std::vector<std::vector<float> > > all_descriptor_results(nbr_descriptors); 00253 unsigned int nbr_concatenated_vals = 0; 00254 for (unsigned int i = 0 ; i < nbr_descriptors ; i++) 00255 { 00256 descriptors_3d[i]->compute(data, data_kdtree, interest_region_indices, 00257 all_descriptor_results[i]); 00258 00259 nbr_concatenated_vals += (descriptors_3d[i])->getResultSize(); 00260 00261 ROS_DEBUG("Interest region descriptor has %u values", descriptors_3d[i]->getResultSize()); 00262 } 00263 00264 concatenateFeatures(all_descriptor_results, interest_region_indices.size(), 00265 nbr_concatenated_vals, concatenated_features); 00266 return nbr_concatenated_vals; 00267 } 00268