00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef PCL_COMMON_VECTOR_AVERAGE_IMPL_HPP_
00039 #define PCL_COMMON_VECTOR_AVERAGE_IMPL_HPP_
00040
00041 namespace pcl
00042 {
00043 template <typename real, int dimension>
00044 VectorAverage<real, dimension>::VectorAverage () :
00045 noOfSamples_ (0), accumulatedWeight_ (0),
00046 mean_ (Eigen::Matrix<real, dimension, 1>::Identity ()),
00047 covariance_ (Eigen::Matrix<real, dimension, dimension>::Identity ())
00048 {
00049 reset();
00050 }
00051
00052 template <typename real, int dimension>
00053 inline void VectorAverage<real, dimension>::reset()
00054 {
00055 noOfSamples_ = 0;
00056 accumulatedWeight_ = 0.0;
00057 mean_.fill(0);
00058 covariance_.fill(0);
00059 }
00060
00061 template <typename real, int dimension>
00062 inline void VectorAverage<real, dimension>::add(const Eigen::Matrix<real, dimension, 1>& sample, real weight) {
00063 if (weight == 0.0f)
00064 return;
00065
00066 ++noOfSamples_;
00067 accumulatedWeight_ += weight;
00068 real alpha = weight/accumulatedWeight_;
00069
00070 Eigen::Matrix<real, dimension, 1> diff = sample - mean_;
00071 covariance_ = (covariance_ + (diff * diff.transpose())*alpha)*(1.0f-alpha);
00072
00073 mean_ += (diff)*alpha;
00074
00075
00076
00077
00078
00079
00080 }
00081
00082 template <typename real, int dimension>
00083 inline void VectorAverage<real, dimension>::doPCA(Eigen::Matrix<real, dimension, 1>& eigen_values, Eigen::Matrix<real, dimension, 1>& eigen_vector1,
00084 Eigen::Matrix<real, dimension, 1>& eigen_vector2, Eigen::Matrix<real, dimension, 1>& eigen_vector3) const
00085 {
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097 Eigen::SelfAdjointEigenSolver<Eigen::Matrix<real, dimension, dimension> > ei_symm(covariance_);
00098 eigen_values = ei_symm.eigenvalues();
00099 Eigen::Matrix<real, dimension, dimension> eigen_vectors = ei_symm.eigenvectors();
00100
00101 eigen_vector1 = eigen_vectors.col(0);
00102 eigen_vector2 = eigen_vectors.col(1);
00103 eigen_vector3 = eigen_vectors.col(2);
00104 }
00105
00106 template <typename real, int dimension>
00107 inline void VectorAverage<real, dimension>::doPCA(Eigen::Matrix<real, dimension, 1>& eigen_values) const
00108 {
00109
00110
00111
00112
00113
00114
00115 Eigen::SelfAdjointEigenSolver<Eigen::Matrix<real, dimension, dimension> > ei_symm(covariance_, false);
00116 eigen_values = ei_symm.eigenvalues();
00117 }
00118
00119 template <typename real, int dimension>
00120 inline void VectorAverage<real, dimension>::getEigenVector1(Eigen::Matrix<real, dimension, 1>& eigen_vector1) const
00121 {
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133 Eigen::SelfAdjointEigenSolver<Eigen::Matrix<real, dimension, dimension> > ei_symm(covariance_);
00134 Eigen::Matrix<real, dimension, dimension> eigen_vectors = ei_symm.eigenvectors();
00135 eigen_vector1 = eigen_vectors.col(0);
00136 }
00137
00138
00140
00143
00145 template <>
00146 inline void VectorAverage<float, 3>::doPCA(Eigen::Matrix<float, 3, 1>& eigen_values, Eigen::Matrix<float, 3, 1>& eigen_vector1,
00147 Eigen::Matrix<float, 3, 1>& eigen_vector2, Eigen::Matrix<float, 3, 1>& eigen_vector3) const
00148 {
00149
00150 Eigen::Matrix<float, 3, 3> eigen_vectors;
00151 eigen33(covariance_, eigen_vectors, eigen_values);
00152 eigen_vector1 = eigen_vectors.col(0);
00153 eigen_vector2 = eigen_vectors.col(1);
00154 eigen_vector3 = eigen_vectors.col(2);
00155 }
00156 template <>
00157 inline void VectorAverage<float, 3>::doPCA(Eigen::Matrix<float, 3, 1>& eigen_values) const
00158 {
00159
00160 computeRoots (covariance_, eigen_values);
00161 }
00162 template <>
00163 inline void VectorAverage<float, 3>::getEigenVector1(Eigen::Matrix<float, 3, 1>& eigen_vector1) const
00164 {
00165
00166 Eigen::Vector3f::Scalar eigen_value;
00167 Eigen::Vector3f eigen_vector;
00168 eigen33(covariance_, eigen_value, eigen_vector);
00169 eigen_vector1 = eigen_vector;
00170 }
00171
00173
00175 template <>
00176 inline void VectorAverage<double, 3>::doPCA(Eigen::Matrix<double, 3, 1>& eigen_values, Eigen::Matrix<double, 3, 1>& eigen_vector1,
00177 Eigen::Matrix<double, 3, 1>& eigen_vector2, Eigen::Matrix<double, 3, 1>& eigen_vector3) const
00178 {
00179
00180 Eigen::Matrix<double, 3, 3> eigen_vectors;
00181 eigen33(covariance_, eigen_vectors, eigen_values);
00182 eigen_vector1 = eigen_vectors.col(0);
00183 eigen_vector2 = eigen_vectors.col(1);
00184 eigen_vector3 = eigen_vectors.col(2);
00185 }
00186 template <>
00187 inline void VectorAverage<double, 3>::doPCA(Eigen::Matrix<double, 3, 1>& eigen_values) const
00188 {
00189
00190 computeRoots (covariance_, eigen_values);
00191 }
00192 template <>
00193 inline void VectorAverage<double, 3>::getEigenVector1(Eigen::Matrix<double, 3, 1>& eigen_vector1) const
00194 {
00195
00196 Eigen::Vector3d::Scalar eigen_value;
00197 Eigen::Vector3d eigen_vector;
00198 eigen33(covariance_, eigen_value, eigen_vector);
00199 eigen_vector1 = eigen_vector;
00200 }
00201 }
00202
00203 #endif
00204