kdtree_ann.h
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2008 Radu Bogdan Rusu <rusu -=- cs.tum.edu>
00003  *
00004  * All rights reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions are met:
00008  *
00009  *     * Redistributions of source code must retain the above copyright
00010  *       notice, this list of conditions and the following disclaimer.
00011  *     * Redistributions in binary form must reproduce the above copyright
00012  *       notice, this list of conditions and the following disclaimer in the
00013  *       documentation and/or other materials provided with the distribution.
00014  *
00015  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00016  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00017  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00018  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00019  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00020  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00021  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00022  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00023  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00024  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00025  * POSSIBILITY OF SUCH DAMAGE.
00026  *
00027  * $Id$
00028  *
00029  */
00030 
00033 #ifndef _CLOUD_KDTREE_KDTREE_ANN_H_
00034 #define _CLOUD_KDTREE_KDTREE_ANN_H_
00035 
00036 #include "door_handle_detector/kdtree/kdtree.h"
00037 
00038 #include <boost/thread/mutex.hpp>
00039 
00040 #include <ANN/ANN.h>
00041 
00042 namespace cloud_kdtree
00043 {
00044   class KdTreeANN : public KdTree
00045   {
00046     public:
00047 
00049 
00052       KdTreeANN (const sensor_msgs::PointCloud &points)
00053       {
00054         ann_kd_tree_ = NULL; // To avoid a bad delete in the destructor.
00055         epsilon_     = 0.0;   // default error bound value
00056         dim_         = 3;     // default number of dimensions (3 = xyz)
00057         bucket_size_ = std::min (30, (int)points.points.size ());    // default bucket size value
00058 
00059         // Allocate enough data
00060         nr_points_ = convertCloudToArray (points);
00061         if (nr_points_ == 0)
00062         {
00063           ROS_ERROR ("[KdTreeANN] Could not create kD-tree for %d points!", nr_points_);
00064           return;
00065         }
00066 
00067         // Create the kd_tree representation
00068         m_lock_.lock ();
00069         ann_kd_tree_ = new ANNkd_tree (points_, nr_points_, dim_, bucket_size_);
00070         m_lock_.unlock ();
00071       }
00072 
00074 
00081       KdTreeANN (const sensor_msgs::PointCloud &points, const std::vector<int> &indices)
00082       {
00083         ann_kd_tree_ = NULL; // To avoid a bad delete in the destructor.
00084         epsilon_     = 0.0;   // default error bound value
00085         dim_         = 3;     // default number of dimensions (3 = xyz)
00086         bucket_size_ = std::min (30, (int)indices.size ());    // default bucket size value
00087 
00088         // Allocate enough data
00089         nr_points_ = convertCloudToArray (points, indices);
00090         if (nr_points_ == 0)
00091         {
00092           ROS_ERROR ("[KdTreeANN] Could not create kD-tree for %d points!", nr_points_);
00093           return;
00094         }
00095 
00096         // Create the kd_tree representation
00097         m_lock_.lock ();
00098         ann_kd_tree_ = new ANNkd_tree (points_, nr_points_, dim_, bucket_size_);
00099         m_lock_.unlock ();
00100       }
00101 
00103 
00104       virtual ~KdTreeANN ()
00105       {
00106         m_lock_.lock ();
00107 
00108         // Data array cleanup
00109         if (points_ != NULL && nr_points_ != 0)
00110           annDeallocPts (points_);
00111 
00112         // ANN Cleanup
00113         if (ann_kd_tree_ != NULL) delete ann_kd_tree_;
00114         ann_kd_tree_ = NULL;
00115         annClose ();
00116 
00117         m_lock_.unlock ();
00118       }
00119 
00120       virtual void nearestKSearch (const geometry_msgs::Point32 &p_q, int k, std::vector<int> &k_indices, std::vector<float> &k_distances);
00121       virtual void nearestKSearch (const sensor_msgs::PointCloud &points, int index, int k, std::vector<int> &k_indices, std::vector<float> &k_distances);
00122 
00124 
00130       virtual inline void
00131         nearestKSearch (int index, int k, std::vector<int> &k_indices, std::vector<float> &k_distances)
00132       {
00133         if (index >= nr_points_)
00134           return;
00135 
00136         k_indices.resize (k);
00137         k_distances.resize (k);
00138 
00139         m_lock_.lock ();
00140         ann_kd_tree_->annkSearch (points_[index], k, &k_indices[0], &k_distances[0], epsilon_);
00141         m_lock_.unlock ();
00142         return;
00143       }
00144 
00145       virtual bool radiusSearch (const geometry_msgs::Point32 &p_q, double radius, std::vector<int> &k_indices, std::vector<float> &k_distances, int max_nn = INT_MAX);
00146       virtual bool radiusSearch (const sensor_msgs::PointCloud &points, int index, double radius, std::vector<int> &k_indices, std::vector<float> &k_distances, int max_nn = INT_MAX);
00147 
00149 
00156       virtual inline bool
00157         radiusSearch (int index, double radius, std::vector<int> &k_indices, std::vector<float> &k_distances,
00158                       int max_nn = INT_MAX)
00159       {
00160         radius *= radius;
00161 
00162         m_lock_.lock ();
00163         int neighbors_in_radius_ = ann_kd_tree_->annkFRSearch (points_[index], radius, 0, NULL, NULL, epsilon_);
00164         m_lock_.unlock ();
00165 
00166         // No neighbors found ? Return false
00167         if (neighbors_in_radius_ == 0)
00168           return (false);
00169 
00170         if (neighbors_in_radius_  > max_nn) neighbors_in_radius_  = max_nn;
00171         k_indices.resize (neighbors_in_radius_);
00172         k_distances.resize (neighbors_in_radius_);
00173 
00174         m_lock_.lock ();
00175         ann_kd_tree_->annkFRSearch (points_[index], radius, neighbors_in_radius_, &k_indices[0], &k_distances[0], epsilon_);
00176         m_lock_.unlock ();
00177 
00178         return (true);
00179       }
00180 
00181     private:
00182 
00183       int convertCloudToArray (const sensor_msgs::PointCloud &ros_cloud);
00184       int convertCloudToArray (const sensor_msgs::PointCloud &ros_cloud, const std::vector<int> &indices);
00185 
00186     private:
00187 
00188       boost::mutex m_lock_;
00189 
00191       ANNkd_tree* ann_kd_tree_;
00192 
00194       double bucket_size_;
00195 
00197       ANNpointArray points_;
00198 
00200       int nr_points_;
00202       int dim_;
00203   };
00204 
00205 }
00206 
00207 #endif


door_handle_detector
Author(s): Radu Bogdan Rusu, Marius
autogenerated on Wed Dec 11 2013 14:17:00