/** * * Copyright (C) Jacobs University Bremen * * @author Vaibhav Kumar Mehta * @author Corneliu Claudiu Prodescu * @file normals.cc */ #include #include #include "slam6d/io_types.h" #include "slam6d/globals.icc" #include "slam6d/scan.h" #include "slam6d/fbr/panorama.h" #include "slam6d/kd.h" #include #include "newmat/newmat.h" #include "newmat/newmatap.h" #include "normals/normals.h" using namespace NEWMAT; using namespace std; ////////////////////////////////////////////////////// /////////////NORMALS USING AKNN METHOD //////////////// /////////////////////////////////////////////////////// void calculateNormalsApxKNN(vector &normals, vector &points, int k, const double _rPos[3], double eps) { cout<<"Total number of points: "< &normals, vector &points, int kmin, int kmax, const double _rPos[3], double eps) { ColumnVector rPos(3); for (int i = 0; i < 3; ++i) rPos(i+1) = _rPos[i]; cout<<"Total number of points: "< 0.25 * e2) && (fabs(1.0 - (double)e2/(double)e3) < 0.25)) break; } //normal = eigenvector corresponding to lowest //eigen value that is the 1rd column of matrix U ColumnVector n(3); n(1) = U(1,1); n(2) = U(2,1); n(3) = U(3,1); ColumnVector point_vector(3); point_vector(1) = p[0] - rPos(1); point_vector(2) = p[1] - rPos(2); point_vector(3) = p[2] - rPos(3); point_vector = point_vector / point_vector.NormFrobenius(); Real angle = (n.t() * point_vector).AsScalar(); if (angle < 0) { n *= -1.0; } n = n / n.NormFrobenius(); normals.push_back(Point(n(1), n(2), n(3))); } annDeallocPts(pa); } /////////////////////////////////////////////////////// /////////////NORMALS USING AKNN METHOD //////////////// /////////////////////////////////////////////////////// void calculateNormalsKNN(vector &normals, vector &points, int k, const double _rPos[3] ) { cout<<"Total number of points: "< temp = t.kNearestNeighbors(p, nr_neighbors, numeric_limits::max()); nr_neighbors = temp.size(); Point mean(0.0,0.0,0.0); Matrix X(nr_neighbors,3); SymmetricMatrix A(3); Matrix U(3,3); DiagonalMatrix D(3); //calculate mean for all the points for (int j = 0; j < nr_neighbors; ++j) { mean.x += temp[j].x; mean.y += temp[j].y; mean.z += temp[j].z; } mean.x /= nr_neighbors; mean.y /= nr_neighbors; mean.z /= nr_neighbors; //calculate covariance = A for all the points for (int i = 0; i < nr_neighbors; ++i) { X(i+1, 1) = temp[i].x - mean.x; X(i+1, 2) = temp[i].y - mean.y; X(i+1, 3) = temp[i].z - mean.z; } A << 1.0/nr_neighbors * X.t() * X; EigenValues(A, D, U); //normal = eigenvector corresponding to lowest //eigen value that is the 1st column of matrix U ColumnVector n(3); n(1) = U(1,1); n(2) = U(2,1); n(3) = U(3,1); ColumnVector point_vector(3); point_vector(1) = p[0] - rPos(1); point_vector(2) = p[1] - rPos(2); point_vector(3) = p[2] - rPos(3); point_vector = point_vector / point_vector.NormFrobenius(); Real angle = (n.t() * point_vector).AsScalar(); if (angle < 0) { n *= -1.0; } n = n / n.NormFrobenius(); normals.push_back(Point(n(1), n(2), n(3))); } for (size_t i = 0; i < points.size(); ++i) { delete[] pa[i]; } delete[] pa; } //////////////////////////////////////////////////////////////// /////////////NORMALS USING ADAPTIVE AKNN METHOD //////////////// //////////////////////////////////////////////////////////////// void calculateNormalsAdaptiveKNN(vector &normals, vector &points, int kmin, int kmax, const double _rPos[3]) { ColumnVector rPos(3); for (int i = 0; i < 3; ++i) rPos(i+1) = _rPos[i]; cout<<"Total number of points: "< temp = t.kNearestNeighbors(p, nr_neighbors, numeric_limits::max()); nr_neighbors = temp.size(); mean.x=0,mean.y=0,mean.z=0; //calculate mean for all the points for (int j=0; j 0.25 * e2) && (fabs(1.0 - (double)e2/(double)e3) < 0.25)) break; } //normal = eigenvector corresponding to lowest //eigen value that is the 1rd column of matrix U ColumnVector n(3); n(1) = U(1,1); n(2) = U(2,1); n(3) = U(3,1); ColumnVector point_vector(3); point_vector(1) = p[0] - rPos(1); point_vector(2) = p[1] - rPos(2); point_vector(3) = p[2] - rPos(3); point_vector = point_vector / point_vector.NormFrobenius(); Real angle = (n.t() * point_vector).AsScalar(); if (angle < 0) { n *= -1.0; } n = n / n.NormFrobenius(); normals.push_back(Point(n(1), n(2), n(3))); } for (size_t i = 0; i < points.size(); ++i) { delete[] pa[i]; } delete[] pa; } /////////////////////////////////////////////////////// /////////////NORMALS USING IMAGE NEIGHBORS //////////// /////////////////////////////////////////////////////// void calculateNormalsPANORAMA(vector &normals, vector &points, vector< vector< vector< cv::Vec3f > > > extendedMap, const double _rPos[3]) { ColumnVector rPos(3); for (int i = 0; i < 3; ++i) rPos(i+1) = _rPos[i]; cout<<"Total number of points: "< neighbors; for (size_t i=0; i< extendedMap.size(); i++) { for (size_t j=0; j= 0 && x < (int)extendedMap.size() && y >= 0 && y < (int)extendedMap[x].size()) { for (unsigned int k = 0; k < extendedMap[x][y].size(); k++) { neighbors.push_back(extendedMap[x][y][k]); } } } nr_neighbors = neighbors.size(); cv::Vec3f p = extendedMap[i][j][0]; //if no neighbor point is found in the 4-neighboring pixels then normal is set to zero if (nr_neighbors < 3) { points.push_back(Point(p[0], p[1], p[2])); normals.push_back(Point(0.0,0.0,0.0)); continue; } //calculate mean for all the points Matrix X(nr_neighbors,3); SymmetricMatrix A(3); Matrix U(3,3); DiagonalMatrix D(3); //calculate mean for all the points for(int k = 0; k < nr_neighbors; k++) { cv::Vec3f pp = neighbors[k]; mean.x += pp[0]; mean.y += pp[1]; mean.z += pp[2]; } mean.x /= nr_neighbors; mean.y /= nr_neighbors; mean.z /= nr_neighbors; //calculate covariance = A for all the points for (int n = 0; n < nr_neighbors; ++n) { cv::Vec3f pp = neighbors[n]; X(n+1, 1) = pp[0] - mean.x; X(n+1, 2) = pp[1] - mean.y; X(n+1, 3) = pp[2] - mean.z; } A << 1.0/nr_neighbors * X.t() * X; EigenValues(A, D, U); //normal = eigenvector corresponding to lowest //eigen value that is the 1st column of matrix U ColumnVector n(3); n(1) = U(1,1); n(2) = U(2,1); n(3) = U(3,1); ColumnVector point_vector(3); point_vector(1) = p[0] - rPos(1); point_vector(2) = p[1] - rPos(2); point_vector(3) = p[2] - rPos(3); point_vector = point_vector / point_vector.NormFrobenius(); Real angle = (n.t() * point_vector).AsScalar(); if (angle < 0) { n *= -1.0; } n = n / n.NormFrobenius(); for (unsigned int k = 0; k < extendedMap[i][j].size(); k++) { cv::Vec3f p = extendedMap[i][j][k]; points.push_back(Point(p[0], p[1], p[2])); normals.push_back(Point(n(1), n(2), n(3))); } } } } ////////////////////////////////////////////////////////////////////////////////////////////// ///////////FAST NORMALS USING PANORAMA EQUIRECTANGULAR RANGE IMAGE ////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////// /* void calculateNormalsFAST(vector &normals,vector &points,cv::Mat &img,vector>> extendedMap) { cout<<"Total number of points: "<(i-1,j); dRdPhi += 3 *img.at(i-1,j-1); dRdPhi += 3 *img.at(i-1,j+1); dRdPhi -= 10*img.at(i+1,j); dRdPhi -= 3 *img.at(i+1,j-1); dRdPhi -= 3 *img.at(i+1,j+1); dRdTheta += 10*img.at(i,j-1); dRdTheta += 3 *img.at(i-1,j-1); dRdTheta += 3 *img.at(i+1,j-1); dRdTheta -= 10*img.at(i,j+1); dRdTheta -= 3 *img.at(i-1,j+1); dRdTheta -= 3 *img.at(i+1,j+1); n[0] = cos(theta) * sin(phi) - sin(theta) * dRdTheta / rho / sin(phi) + cos(theta) * cos(phi) * dRdPhi / rho; n[1] = sin(theta) * sin(phi) + cos(theta) * dRdTheta / rho / sin(phi) + sin(theta) * cos(phi) * dRdPhi / rho; n[2] = cos(phi) - sin(phi) * dRdPhi / rho; //n[2] = -n[2]; m = sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]); n[0] /= m; n[1] /= m; n[2] /= m; points.push_back(Point(x, y, z)); normals.push_back(Point(n[0],n[1],n[2])); } } } } */