|
Point Cloud Library (PCL)
1.5.1
|
00001 /* 00002 * Software License Agreement (BSD License) 00003 * 00004 * Point Cloud Library (PCL) - www.pointclouds.org 00005 * Copyright (c) 2010-2011, Willow Garage, Inc. 00006 * 00007 * All rights reserved. 00008 * 00009 * Redistribution and use in source and binary forms, with or without 00010 * modification, are permitted provided that the following conditions 00011 * are met: 00012 * 00013 * * Redistributions of source code must retain the above copyright 00014 * notice, this list of conditions and the following disclaimer. 00015 * * Redistributions in binary form must reproduce the above 00016 * copyright notice, this list of conditions and the following 00017 * disclaimer in the documentation and/or other materials provided 00018 * with the distribution. 00019 * * Neither the name of Willow Garage, Inc. nor the names of its 00020 * contributors may be used to endorse or promote products derived 00021 * from this software without specific prior written permission. 00022 * 00023 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00024 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00025 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00026 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00027 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00028 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00029 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00030 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00031 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00032 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00033 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00034 * POSSIBILITY OF SUCH DAMAGE. 00035 * 00036 * $Id: organized.h 4504 2012-02-17 00:47:06Z gedikli $ 00037 * 00038 */ 00039 00040 #ifndef PCL_SEARCH_ORGANIZED_NEIGHBOR_SEARCH_H_ 00041 #define PCL_SEARCH_ORGANIZED_NEIGHBOR_SEARCH_H_ 00042 00043 #include <pcl/point_cloud.h> 00044 #include <pcl/point_types.h> 00045 #include <pcl/search/search.h> 00046 #include <pcl/common/eigen.h> 00047 00048 #include <algorithm> 00049 #include <queue> 00050 #include <vector> 00051 00052 namespace pcl 00053 { 00054 namespace search 00055 { 00060 template<typename PointT> 00061 class OrganizedNeighbor : public pcl::search::Search<PointT> 00062 { 00063 00064 public: 00065 // public typedefs 00066 typedef pcl::PointCloud<PointT> PointCloud; 00067 typedef boost::shared_ptr<PointCloud> PointCloudPtr; 00068 00069 typedef boost::shared_ptr<const PointCloud> PointCloudConstPtr; 00070 typedef boost::shared_ptr<const std::vector<int> > IndicesConstPtr; 00071 00072 typedef boost::shared_ptr<pcl::search::OrganizedNeighbor<PointT> > Ptr; 00073 typedef boost::shared_ptr<const pcl::search::OrganizedNeighbor<PointT> > ConstPtr; 00074 00075 using pcl::search::Search<PointT>::indices_; 00076 using pcl::search::Search<PointT>::sorted_results_; 00077 using pcl::search::Search<PointT>::input_; 00078 00080 OrganizedNeighbor (bool sorted_results = false) 00081 : Search<PointT> ("OrganizedNeighbor", sorted_results) 00082 , projection_matrix_ (Eigen::Matrix<float, 3, 4, Eigen::RowMajor>::Zero ()) 00083 , eps_ (1e-4) 00084 { 00085 } 00086 00088 virtual ~OrganizedNeighbor () {} 00089 00095 bool isValid () const 00096 { 00097 // determinant (KR) = determinant (K) * determinant (R) = determinant (K) = f_x * f_y. 00098 // If we expect at max an opening angle of 170degree in x-direction -> f_x = 2.0 * width / tan (85 degree); 00099 // 2 * tan (85 degree) ~ 22.86 00100 float min_f = 0.043744332 * input_->width; 00101 //std::cout << "isValid: " << determinant3x3Matrix<Eigen::Matrix3f> (KR_ / sqrt (KR_KRT_.coeff (8))) << " >= " << (min_f * min_f) << std::endl; 00102 return (determinant3x3Matrix<Eigen::Matrix3f> (KR_ / sqrt (KR_KRT_.coeff (8))) >= (min_f * min_f)); 00103 } 00104 00105 void computeCameraMatrix (Eigen::Matrix3f& camera_matrix) const; 00110 virtual void 00111 setInputCloud (const PointCloudConstPtr& cloud, const IndicesConstPtr &indices = IndicesConstPtr ()) 00112 { 00113 bool input_changed = false; 00114 if (input_ != cloud) 00115 { 00116 input_ = cloud; 00117 input_changed = true; 00118 mask_.resize (input_->size ()); 00119 } 00120 00121 if (indices_ != indices) 00122 { 00123 indices_ = indices; 00124 input_changed = true; 00125 } 00126 00127 if (input_changed) 00128 { 00129 if (indices_.get () != NULL && indices_->size () != 0) 00130 { 00131 mask_.assign (input_->size (), false); 00132 for (std::vector<int>::const_iterator iIt = indices_->begin (); iIt != indices_->end (); ++iIt) 00133 mask_[*iIt] = true; 00134 } 00135 else 00136 mask_.assign (input_->size (), true); 00137 00138 estimateProjectionMatrix (); 00139 } 00140 } 00141 00152 int 00153 radiusSearch (const PointT &p_q, 00154 const double radius, 00155 std::vector<int> &k_indices, 00156 std::vector<float> &k_sqr_distances, 00157 unsigned int max_nn = 0) const; 00158 00161 void estimateProjectionMatrix (); 00162 00172 int 00173 nearestKSearch (const PointT &p_q, 00174 int k, 00175 std::vector<int> &k_indices, 00176 std::vector<float> &k_sqr_distances) const; 00177 00178 protected: 00179 00180 struct Entry 00181 { 00182 Entry (int idx, float dist) : index (idx), distance (dist) {} 00183 Entry () {} 00184 unsigned index; 00185 float distance; 00186 bool operator < (const Entry& other) const 00187 { 00188 return distance < other.distance; 00189 } 00190 }; 00191 00199 inline bool testPoint (const PointT& query, unsigned k, std::priority_queue<Entry>& queue, unsigned index) const 00200 { 00201 const PointT& point = input_->points [index]; 00202 if (mask_ [index] && pcl_isfinite (point.x)) 00203 { 00204 float squared_distance = (point.getVector3fMap () - query.getVector3fMap ()).squaredNorm (); 00205 if (queue.size () < k) 00206 queue.push (Entry (index, squared_distance)); 00207 else if (queue.top ().distance > squared_distance) 00208 { 00209 queue.pop (); 00210 queue.push (Entry (index, squared_distance)); 00211 return true; // top element has changed! 00212 } 00213 } 00214 return false; 00215 } 00216 00217 inline void 00218 clipRange (int& begin, int &end, int min, int max) const 00219 { 00220 begin = std::max (std::min (begin, max), min); 00221 end = std::min (std::max (end, min), max); 00222 } 00231 void 00232 getProjectedRadiusSearchBox (const PointT& point, float squared_radius, unsigned& minX, unsigned& minY, 00233 unsigned& maxX, unsigned& maxY) const; 00234 00235 00237 template <typename MatrixType> void 00238 makeSymmetric (MatrixType& matrix, bool use_upper_triangular = true) const; 00239 00241 Eigen::Matrix<float, 3, 4, Eigen::RowMajor> projection_matrix_; 00242 00244 Eigen::Matrix<float, 3, 3, Eigen::RowMajor> KR_; 00245 00247 Eigen::Matrix<float, 3, 3, Eigen::RowMajor> KR_KRT_; 00248 00250 float eps_; 00251 00253 std::vector<bool> mask_; 00254 public: 00255 EIGEN_MAKE_ALIGNED_OPERATOR_NEW 00256 }; 00257 } 00258 } 00259 00260 #endif 00261
1.8.0