|
Point Cloud Library (PCL)
1.6.0
|
00001 /* 00002 * Software License Agreement (BSD License) 00003 * 00004 * Point Cloud Library (PCL) - www.pointclouds.org 00005 * Copyright (c) 2010-2012, 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 00037 namespace pcl 00038 { 00039 template <typename real, int dimension> 00040 VectorAverage<real, dimension>::VectorAverage () : 00041 noOfSamples_ (0), accumulatedWeight_ (0), 00042 mean_ (Eigen::Matrix<real, dimension, 1>::Identity ()), 00043 covariance_ (Eigen::Matrix<real, dimension, dimension>::Identity ()) 00044 { 00045 reset(); 00046 } 00047 00048 template <typename real, int dimension> 00049 inline void VectorAverage<real, dimension>::reset() 00050 { 00051 noOfSamples_ = 0; 00052 accumulatedWeight_ = 0.0; 00053 mean_.fill(0); 00054 covariance_.fill(0); 00055 } 00056 00057 template <typename real, int dimension> 00058 inline void VectorAverage<real, dimension>::add(const Eigen::Matrix<real, dimension, 1>& sample, real weight) { 00059 if (weight == 0.0f) 00060 return; 00061 00062 ++noOfSamples_; 00063 accumulatedWeight_ += weight; 00064 real alpha = weight/accumulatedWeight_; 00065 00066 Eigen::Matrix<real, dimension, 1> diff = sample - mean_; 00067 covariance_ = (1.0f-alpha)*(covariance_ + alpha * (diff * diff.transpose())); 00068 00069 mean_ += alpha*(diff); 00070 00071 //if (pcl_isnan(covariance_(0,0))) 00072 //{ 00073 //cout << PVARN(weight); 00074 //exit(0); 00075 //} 00076 } 00077 00078 template <typename real, int dimension> 00079 inline void VectorAverage<real, dimension>::doPCA(Eigen::Matrix<real, dimension, 1>& eigen_values, Eigen::Matrix<real, dimension, 1>& eigen_vector1, 00080 Eigen::Matrix<real, dimension, 1>& eigen_vector2, Eigen::Matrix<real, dimension, 1>& eigen_vector3) const 00081 { 00082 // The following step is necessary for cases where the values in the covariance matrix are small 00083 // In this case float accuracy is nor enough to calculate the eigenvalues and eigenvectors. 00084 //Eigen::Matrix<double, dimension, dimension> tmp_covariance = covariance_.template cast<double>(); 00085 //Eigen::SelfAdjointEigenSolver<Eigen::Matrix<double, dimension, dimension> > ei_symm(tmp_covariance); 00086 //eigen_values = ei_symm.eigenvalues().template cast<real>(); 00087 //Eigen::Matrix<real, dimension, dimension> eigen_vectors = ei_symm.eigenvectors().template cast<real>(); 00088 00089 //cout << "My covariance is \n"<<covariance_<<"\n"; 00090 //cout << "My mean is \n"<<mean_<<"\n"; 00091 //cout << "My Eigenvectors \n"<<eigen_vectors<<"\n"; 00092 00093 Eigen::SelfAdjointEigenSolver<Eigen::Matrix<real, dimension, dimension> > ei_symm(covariance_); 00094 eigen_values = ei_symm.eigenvalues(); 00095 Eigen::Matrix<real, dimension, dimension> eigen_vectors = ei_symm.eigenvectors(); 00096 00097 eigen_vector1 = eigen_vectors.col(0); 00098 eigen_vector2 = eigen_vectors.col(1); 00099 eigen_vector3 = eigen_vectors.col(2); 00100 } 00101 00102 template <typename real, int dimension> 00103 inline void VectorAverage<real, dimension>::doPCA(Eigen::Matrix<real, dimension, 1>& eigen_values) const 00104 { 00105 // The following step is necessary for cases where the values in the covariance matrix are small 00106 // In this case float accuracy is nor enough to calculate the eigenvalues and eigenvectors. 00107 //Eigen::Matrix<double, dimension, dimension> tmp_covariance = covariance_.template cast<double>(); 00108 //Eigen::SelfAdjointEigenSolver<Eigen::Matrix<double, dimension, dimension> > ei_symm(tmp_covariance, false); 00109 //eigen_values = ei_symm.eigenvalues().template cast<real>(); 00110 00111 Eigen::SelfAdjointEigenSolver<Eigen::Matrix<real, dimension, dimension> > ei_symm(covariance_, false); 00112 eigen_values = ei_symm.eigenvalues(); 00113 } 00114 00115 template <typename real, int dimension> 00116 inline void VectorAverage<real, dimension>::getEigenVector1(Eigen::Matrix<real, dimension, 1>& eigen_vector1) const 00117 { 00118 // The following step is necessary for cases where the values in the covariance matrix are small 00119 // In this case float accuracy is nor enough to calculate the eigenvalues and eigenvectors. 00120 //Eigen::Matrix<double, dimension, dimension> tmp_covariance = covariance_.template cast<double>(); 00121 //Eigen::SelfAdjointEigenSolver<Eigen::Matrix<double, dimension, dimension> > ei_symm(tmp_covariance); 00122 //eigen_values = ei_symm.eigenvalues().template cast<real>(); 00123 //Eigen::Matrix<real, dimension, dimension> eigen_vectors = ei_symm.eigenvectors().template cast<real>(); 00124 00125 //cout << "My covariance is \n"<<covariance_<<"\n"; 00126 //cout << "My mean is \n"<<mean_<<"\n"; 00127 //cout << "My Eigenvectors \n"<<eigen_vectors<<"\n"; 00128 00129 Eigen::SelfAdjointEigenSolver<Eigen::Matrix<real, dimension, dimension> > ei_symm(covariance_); 00130 Eigen::Matrix<real, dimension, dimension> eigen_vectors = ei_symm.eigenvectors(); 00131 eigen_vector1 = eigen_vectors.col(0); 00132 } 00133 00134 00136 // Special cases for real=float & dimension=3 -> Partial specialization does not work with class templates. :( // 00139 // float // 00141 template <> 00142 inline void VectorAverage<float, 3>::doPCA(Eigen::Matrix<float, 3, 1>& eigen_values, Eigen::Matrix<float, 3, 1>& eigen_vector1, 00143 Eigen::Matrix<float, 3, 1>& eigen_vector2, Eigen::Matrix<float, 3, 1>& eigen_vector3) const 00144 { 00145 //cout << "Using specialized 3x3 version of doPCA!\n"; 00146 Eigen::Matrix<float, 3, 3> eigen_vectors; 00147 eigen33(covariance_, eigen_vectors, eigen_values); 00148 eigen_vector1 = eigen_vectors.col(0); 00149 eigen_vector2 = eigen_vectors.col(1); 00150 eigen_vector3 = eigen_vectors.col(2); 00151 } 00152 template <> 00153 inline void VectorAverage<float, 3>::doPCA(Eigen::Matrix<float, 3, 1>& eigen_values) const 00154 { 00155 //cout << "Using specialized 3x3 version of doPCA!\n"; 00156 computeRoots (covariance_, eigen_values); 00157 } 00158 template <> 00159 inline void VectorAverage<float, 3>::getEigenVector1(Eigen::Matrix<float, 3, 1>& eigen_vector1) const 00160 { 00161 //cout << "Using specialized 3x3 version of doPCA!\n"; 00162 Eigen::Vector3f::Scalar eigen_value; 00163 Eigen::Vector3f eigen_vector; 00164 eigen33(covariance_, eigen_value, eigen_vector); 00165 eigen_vector1 = eigen_vector; 00166 } 00167 00169 // double // 00171 template <> 00172 inline void VectorAverage<double, 3>::doPCA(Eigen::Matrix<double, 3, 1>& eigen_values, Eigen::Matrix<double, 3, 1>& eigen_vector1, 00173 Eigen::Matrix<double, 3, 1>& eigen_vector2, Eigen::Matrix<double, 3, 1>& eigen_vector3) const 00174 { 00175 //cout << "Using specialized 3x3 version of doPCA!\n"; 00176 Eigen::Matrix<double, 3, 3> eigen_vectors; 00177 eigen33(covariance_, eigen_vectors, eigen_values); 00178 eigen_vector1 = eigen_vectors.col(0); 00179 eigen_vector2 = eigen_vectors.col(1); 00180 eigen_vector3 = eigen_vectors.col(2); 00181 } 00182 template <> 00183 inline void VectorAverage<double, 3>::doPCA(Eigen::Matrix<double, 3, 1>& eigen_values) const 00184 { 00185 //cout << "Using specialized 3x3 version of doPCA!\n"; 00186 computeRoots (covariance_, eigen_values); 00187 } 00188 template <> 00189 inline void VectorAverage<double, 3>::getEigenVector1(Eigen::Matrix<double, 3, 1>& eigen_vector1) const 00190 { 00191 //cout << "Using specialized 3x3 version of doPCA!\n"; 00192 Eigen::Vector3d::Scalar eigen_value; 00193 Eigen::Vector3d eigen_vector; 00194 eigen33(covariance_, eigen_value, eigen_vector); 00195 eigen_vector1 = eigen_vector; 00196 } 00197 } // END namespace 00198
1.7.6.1