Go to the documentation of this file.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 #ifndef NORMAL_ESTIMATION_VALUE_CLASS_H_
00037 #define NORMAL_ESTIMATION_VALUE_CLASS_H_
00038
00039 #include <Eigen/Core>
00040 #include <Eigen/Eigen>
00041 #include <octreelib/spatialaggregate/octree.h>
00042 #include <octreelib/algorithm/downsample.h>
00043 #include <pcl/point_types.h>
00044 #include <pcl/point_cloud.h>
00045 #include <pcl/common/vector_average.h>
00046 #include <limits.h>
00047
00048 class NormalEstimationValueClass {
00049 public:
00050 typedef Eigen::Matrix3f Mat3;
00051 typedef Eigen::Vector3f Vec3;
00052
00053 Mat3 summedSquares;
00054 Vec3 summedPos;
00055 Vec3 meanPos;
00056
00057 Vec3 normal;
00058 float curv;
00059 float curv2;
00060 bool stable;
00061 bool segmented;
00062 unsigned int id;
00063 unsigned int numPoints;
00064 bool nodeQuerried;
00065
00066 NormalEstimationValueClass(const unsigned int) :
00067 id(std::numeric_limits<unsigned int>::max()) {
00068 clear();
00069 }
00070
00071 NormalEstimationValueClass() :
00072 id(std::numeric_limits<unsigned int>::max()) {
00073 clear();
00074 }
00075
00076 void clear() {
00077 summedSquares.setZero();
00078 summedPos.setZero();
00079 meanPos.setZero();
00080 normal.setZero();
00081 numPoints = 0;
00082 curv = -1.f;
00083 curv2 = -1.f;
00084 segmented = false;
00085 stable = false;
00086 nodeQuerried = false;
00087 }
00088
00089 NormalEstimationValueClass& operator+(const NormalEstimationValueClass& rhs) {
00090 summedSquares += rhs.summedSquares;
00091 summedPos += rhs.summedPos;
00092 numPoints += rhs.numPoints;
00093 if (rhs.id < id)
00094 id = rhs.id;
00095 return *this;
00096 }
00097
00098 NormalEstimationValueClass& operator+=(const NormalEstimationValueClass& rhs) {
00099 summedSquares += rhs.summedSquares;
00100 summedPos += rhs.summedPos;
00101 numPoints += rhs.numPoints;
00102 if (rhs.id < id)
00103 id = rhs.id;
00104 return *this;
00105 }
00106 };
00107
00109 template<typename CoordType, typename ValueType>
00110 bool calculateNormal(spatialaggregate::OcTreeNode<CoordType, ValueType>* treenode, const Eigen::Vector3f& viewPort,
00111 const int& minimumPointsForNormal, const float& curv_threshold, const float& curv2_threshold,
00112 const float& minPrincipleVariance) {
00113 int count = treenode->value_.numPoints;
00114 Eigen::Vector3f summedPos(treenode->value_.summedPos);
00115 summedPos *= 1.f / (float) count;
00116 treenode->value_.meanPos = summedPos;
00117 if (count < minimumPointsForNormal) {
00118 return false;
00119 }
00120
00121 Eigen::Matrix3f summedSquares(treenode->value_.summedSquares);
00122 summedSquares *= 1.f / (float) count;
00123 summedSquares -= summedPos * summedPos.transpose();
00124
00125
00126
00127
00128 Eigen::SelfAdjointEigenSolver<Eigen::Matrix3f> es;
00129 es.compute(summedSquares);
00130 const Eigen::Matrix<float, 3, 1>& eigen_values = es.eigenvalues();
00131 const Eigen::Matrix<float, 3, 3>& eigen_vectors = es.eigenvectors();
00132
00133 treenode->value_.curv = eigen_values(0, 0) / eigen_values(2, 0);
00134 if(eigen_values(0, 0) > eigen_values(2, 0)) std::cout << "ERROR while calculating curv: eigenvalues were not sorted ascendingly" << std::endl;
00135 treenode->value_.curv2 = eigen_values(1, 0) / eigen_values(2, 0);
00136 treenode->value_.normal = eigen_vectors.col(0);
00137 if (eigen_vectors.col(0).dot((summedPos / treenode->value_.numPoints) - viewPort) > 0)
00138 treenode->value_.normal = -treenode->value_.normal;
00139 if ((treenode->value_.curv > curv_threshold) || (treenode->value_.curv2 < curv2_threshold)
00140 || (eigen_values(2, 0) < minPrincipleVariance)) {
00141 treenode->value_.stable = false;
00142 return false;
00143 }
00144 treenode->value_.stable = true;
00145 return true;
00146 }
00147
00148 template<typename CoordType, typename ValueType>
00149 void calculateNormalsOnOctreeLayer(std::vector<spatialaggregate::OcTreeNode<CoordType, ValueType>*>& layer,
00150 Eigen::Vector3f viewPort, int minimumPointsForNormal) {
00151 for (unsigned int i = 0; i < layer.size(); i++) {
00152 if (!(layer[i]->value_.stable)) {
00153 layer[i]->value_.stable = calculateNormal(layer[i], layer[i]->value_.normal, viewPort,
00154 minimumPointsForNormal);
00155 }
00156 }
00157 }
00158
00159 #endif
00160