21 #include <pcl/common/time.h>    22 #include <pcl/filters/voxel_grid.h>   171     out << v3normal(0) << v3normal(1) << v3normal(2);
   172     out << v3center(0) << v3center(1) << v3center(2);
   173     out << v3PpalDir(0) << v3PpalDir(1) << v3PpalDir(2);
   174     out << v3colorNrgb(0) << v3colorNrgb(1) << v3colorNrgb(2);
   176     out << dominantIntensity;
   177     out << bDominantColor;
   188     out << label_context;
   202     out << (
uint32_t)polygonContourPtr->size();
   203     for (
uint32_t i=0; i < polygonContourPtr->size(); i++)
   204       out << polygonContourPtr->points[i].x << polygonContourPtr->points[i].y << polygonContourPtr->points[i].z;
   266                         in >> v3normal(0) >> v3normal(1) >> v3normal(2);
   267                         in >> v3center(0) >> v3center(1) >> v3center(2);
   268                         in >> v3PpalDir(0) >> v3PpalDir(1) >> v3PpalDir(2);
   269                         d = -v3normal.dot(v3center);
   270                         in >> v3colorNrgb(0) >> v3colorNrgb(1) >> v3colorNrgb(2);
   272       in >> dominantIntensity;
   273       in >> bDominantColor;
   305                         polygonContourPtr->resize(
n);
   306       for (
unsigned i=0; i < 
n; i++)
   307         in >> polygonContourPtr->points[i].x >> polygonContourPtr->points[i].y >> polygonContourPtr->points[i].z;
   324   const double D = -(v3normal.dot(v3center));
   325   for(
unsigned i = 0; i < planePointCloudPtr->size(); i++)
   327     double dist = v3normal[0]*planePointCloudPtr->points[i].x + v3normal[1]*planePointCloudPtr->points[i].y + v3normal[2]*planePointCloudPtr->points[i].z + D;
   328     planePointCloudPtr->points[i].x -= v3normal[0] * dist;
   329     planePointCloudPtr->points[i].y -= v3normal[1] * dist;
   330     planePointCloudPtr->points[i].z -= v3normal[2] * dist;
   333   for(
unsigned i = 0; i < polygonContourPtr->size(); i++)
   335     double dist = v3normal[0]*polygonContourPtr->points[i].x + v3normal[1]*polygonContourPtr->points[i].y + v3normal[2]*polygonContourPtr->points[i].z + D;
   336     polygonContourPtr->points[i].x -= v3normal[0] * dist;
   337     polygonContourPtr->points[i].y -= v3normal[1] * dist;
   338     polygonContourPtr->points[i].z -= v3normal[2] * dist;
   350   k0 = (fabs (v3normal[0] ) > fabs (v3normal[1])) ? 0  : 1;
   351   k0 = (fabs (v3normal[k0]) > fabs (v3normal[2])) ? k0 : 2;
   356   float ct = fabs ( v3normal[k0] );
   358   float p_i[3], p_j[3];
   360   for (
unsigned int i = 0; i < polygonContourPtr->points.size (); i++)
   362     p_i[0] = polygonContourPtr->points[i].x; p_i[1] = polygonContourPtr->points[i].y; p_i[2] = polygonContourPtr->points[i].z;
   363     int j = (i + 1) % polygonContourPtr->points.size ();
   364     p_j[0] = polygonContourPtr->points[j].x; p_j[1] = polygonContourPtr->points[j].y; p_j[2] = polygonContourPtr->points[j].z;
   366     AreaX2 += p_i[k1] * p_j[k2] - p_i[k2] * p_j[k1];
   368   AreaX2 = fabs (AreaX2) / (2 * ct);
   380   k0 = (fabs (v3normal[0] ) > fabs (v3normal[1])) ? 0  : 1;
   381   k0 = (fabs (v3normal[k0]) > fabs (v3normal[2])) ? k0 : 2;
   386   float ct = fabs ( v3normal[k0] );
   388   Eigen::Vector3f massCenter = Eigen::Vector3f::Zero();
   389   float p_i[3], p_j[3];
   391   for (
unsigned int i = 0; i < polygonContourPtr->points.size (); i++)
   393     p_i[0] = polygonContourPtr->points[i].x; p_i[1] = polygonContourPtr->points[i].y; p_i[2] = polygonContourPtr->points[i].z;
   394     int j = (i + 1) % polygonContourPtr->points.size ();
   395     p_j[0] = polygonContourPtr->points[j].x; p_j[1] = polygonContourPtr->points[j].y; p_j[2] = polygonContourPtr->points[j].z;
   396     double cross_segment = p_i[k1] * p_j[k2] - p_i[k2] * p_j[k1];
   398     AreaX2 += cross_segment;
   399     massCenter[k1] += (p_i[k1] + p_j[k1]) * cross_segment;
   400     massCenter[k2] += (p_i[k2] + p_j[k2]) * cross_segment;
   402   areaHull = fabs (AreaX2) / (2 * ct);
   404   massCenter[k1] /= (3*AreaX2);
   405   massCenter[k2] /= (3*AreaX2);
   406   massCenter[k0] = (v3normal.dot(v3center) - v3normal[k1]*massCenter[k1] - v3normal[k2]*massCenter[k2]) / v3normal[k0];
   408   v3center = massCenter;
   410   d = -(v3normal. dot (v3center));
   415   pcl::PCA< PointT > pca;
   416   pca.setInputCloud(planePointCloudPtr);
   417   Eigen::VectorXf eigenVal = pca.getEigenValues();
   420     elongation = sqrt(eigenVal[0] / eigenVal[1]);
   421     Eigen::MatrixXf eigenVect = pca.getEigenVectors();
   423     v3PpalDir[0] = eigenVect(0,0);
   424     v3PpalDir[1] = eigenVect(1,0);
   425     v3PpalDir[2] = eigenVect(2,0);
   433   assert( planePointCloudPtr->size() > 0);
   435   r.resize(planePointCloudPtr->size());
   436   g.resize(planePointCloudPtr->size());
   437   b.resize(planePointCloudPtr->size());
   438   intensity.resize(planePointCloudPtr->size());
   441   for(
size_t i=0; i < planePointCloudPtr->size(); i++)
   443     float sumRGB = (float)planePointCloudPtr->points[i].r + planePointCloudPtr->points[i].g + planePointCloudPtr->points[i].b;
   444     intensity[i] = sumRGB;
   447       r[countPix] = planePointCloudPtr->points[i].r / sumRGB;
   448       g[countPix] = planePointCloudPtr->points[i].g / sumRGB;
   449       b[countPix] = planePointCloudPtr->points[i].b / sumRGB;
   456   intensity.resize(countPix);
   461   c1.resize(planePointCloudPtr->size());
   462   c2.resize(planePointCloudPtr->size());
   463   c3.resize(planePointCloudPtr->size());
   465   for(
unsigned i=0; i < planePointCloudPtr->size(); i++)
   467     c1[i] = atan2((
double) planePointCloudPtr->points[i].r, (
double) max(planePointCloudPtr->points[i].g,planePointCloudPtr->points[i].b));
   468     c2[i] = atan2((
double) planePointCloudPtr->points[i].g, (
double) max(planePointCloudPtr->points[i].r,planePointCloudPtr->points[i].b));
   469     c3[i] = atan2((
double) planePointCloudPtr->points[i].b, (
double) max(planePointCloudPtr->points[i].r,planePointCloudPtr->points[i].g));
   478   const float FLOAT_TO_BYTE = 255.0f;
   479   const float BYTE_TO_FLOAT = 1.0f / FLOAT_TO_BYTE;
   483   for(
unsigned i=0; i < planePointCloudPtr->size(); i++)
   486     fR = planePointCloudPtr->points[i].r * BYTE_TO_FLOAT;
   487     fG = planePointCloudPtr->points[i].g * BYTE_TO_FLOAT;
   488     fB = planePointCloudPtr->points[i].b * BYTE_TO_FLOAT;
   494     if (planePointCloudPtr->points[i].b < planePointCloudPtr->points[i].g) {
   495       if (planePointCloudPtr->points[i].b < planePointCloudPtr->points[i].r) {
   497         if (planePointCloudPtr->points[i].r > planePointCloudPtr->points[i].g) {
   498           iMax = planePointCloudPtr->points[i].r;
   502           iMax = planePointCloudPtr->points[i].g;
   509         iMax = planePointCloudPtr->points[i].g;
   513       if (planePointCloudPtr->points[i].g < planePointCloudPtr->points[i].r) {
   515         if (planePointCloudPtr->points[i].b > planePointCloudPtr->points[i].r) {
   517           iMax = planePointCloudPtr->points[i].b;
   521           iMax = planePointCloudPtr->points[i].r;
   527         iMax = planePointCloudPtr->points[i].b;
   530     fDelta = fMax - fMin;
   550       float ANGLE_TO_UNIT = 12.0f / fDelta;     
   551       if (iMax == planePointCloudPtr->points[i].r) {            
   552         fH = (fG - fB) * ANGLE_TO_UNIT;
   554       else if (iMax == planePointCloudPtr->points[i].g) {               
   555         fH = (2.0f/6.0f) + ( fB - fR ) * ANGLE_TO_UNIT;
   558         fH = (4.0f/6.0f) + ( fR - fG ) * ANGLE_TO_UNIT;
   572   for(
unsigned i=0; i < H.size(); i++)
   575   for(
unsigned i=0; i < H.size(); i++)
   576     hist_H[i] = H[i]/numPixels;
   585   assert( planePointCloudPtr->size() > 0);
   589   std::vector<Eigen::Vector4f> 
color(planePointCloudPtr->size());
   592   size_t stepColor = std::max(planePointCloudPtr->size() / 2000, 
static_cast<size_t>(1)); 
   593   for(
size_t i=0; i < planePointCloudPtr->size(); i+=stepColor)
   595     float sumRGB = (float)planePointCloudPtr->points[i].r + planePointCloudPtr->points[i].g + planePointCloudPtr->points[i].b;
   598       color[countPix][0] = planePointCloudPtr->points[i].r / sumRGB;
   599       color[countPix][1] = planePointCloudPtr->points[i].g / sumRGB;
   600       color[countPix][2] = planePointCloudPtr->points[i].b / sumRGB;
   601       color[countPix][3] = sumRGB;
   607   color.resize(countPix);
   608   intensity.resize(countPix);
   610   float concentration, histStdDev;
   613   v3colorNrgb = dominantColor.head(3);
   614   dominantIntensity = dominantColor(3);
   617     bDominantColor = 
true;
   619     bDominantColor = 
false;
   656   dominantIntensity = 0;
   657   int countFringe05 = 0;
   658   for(
unsigned i=0; i < 
r.size(); i++)
   659     if(fabs(
r[i] - v3colorNrgb(0)) < 0.05 && fabs(
g[i] - v3colorNrgb(1)) < 0.05 && fabs(
b[i] - v3colorNrgb(2)) < 0.05)
   661       dominantIntensity += intensity[i];
   664   assert(countFringe05 > 0);
   665   dominantIntensity /= countFringe05;
   666   float concentration05 = 
static_cast<float>(countFringe05) / 
r.size();
   673   if(concentration05 > 0.5)
   674     bDominantColor = 
true;
   676     bDominantColor = 
false;
   705         return x < 
p.x || (
x == 
p.x && 
y < 
p.y);
   711     return (A.
x - O.
x) * (B.
y - O.
y) - (A.
y - O.
y) * (B.
x - O.
x);
   788   k0 = (fabs (v3normal(0) ) > fabs(v3normal[1])) ? 0  : 1;
   789   k0 = (fabs (v3normal(k0) ) > fabs(v3normal(2))) ? k0 : 2;
   791   std::vector<mPointHull> P;
   792   P.resize(pointCloud->size() );
   794     for(
size_t i=0; i < pointCloud->size(); i++)
   796       P[i].x = pointCloud->points[i].y;
   797       P[i].y = pointCloud->points[i].z;
   801     for(
size_t i=0; i < pointCloud->size(); i++)
   803       P[i].x = pointCloud->points[i].x;
   804       P[i].y = pointCloud->points[i].z;
   808     for(
size_t i=0; i < pointCloud->size(); i++)
   810       P[i].x = pointCloud->points[i].x;
   811       P[i].y = pointCloud->points[i].y;
   815   int n = P.size(), k = 0;
   816   std::vector<mPointHull> H(2*
n);
   819   std::sort(P.begin(), P.end());
   822   for (
int i = 0; i < 
n; i++)
   824     while (k >= 2 && 
cross(H[k-2], H[k-1], P[i]) <= 0)
   828         assert(H[k-1].
id != H[k-2].
id);
   832   for (
int i = 
n-2, 
t = k+1; i >= 0; i--)
   834     while (k >= 
t && 
cross(H[k-2], H[k-1], P[i]) <= 0)
   840   size_t hull_noRep = k-1; 
   842   polygonContourPtr->resize(hull_noRep);
   845   for(
size_t i=0; i < hull_noRep; i++)
   847     polygonContourPtr->points[i] = pointCloud->points[ H[i].id ];
   858   k0 = (fabs (v3normal(0) ) > fabs(v3normal[1])) ? 0  : 1;
   859   k0 = (fabs (v3normal(k0) ) > fabs(v3normal(2))) ? k0 : 2;
   863   std::vector<mPointHull> P;
   864   P.resize(pointCloud->size() );
   866     for(
size_t i=0; i < pointCloud->size(); i++)
   868       P[i].x = pointCloud->points[i].y;
   869       P[i].y = pointCloud->points[i].z;
   873     for(
size_t i=0; i < pointCloud->size(); i++)
   875       P[i].x = pointCloud->points[i].z;
   876       P[i].y = pointCloud->points[i].x;
   880     for(
size_t i=0; i < pointCloud->size(); i++)
   882       P[i].x = pointCloud->points[i].x;
   883       P[i].y = pointCloud->points[i].y;
   887   int n = P.size(), k = 0;
   888   std::vector<mPointHull> H(2*
n);
   891   std::sort(P.begin(), P.end());
   894   for (
int i = 0; i < 
n; i++)
   896     while (k >= 2 && 
cross(H[k-2], H[k-1], P[i]) <= 0)
   900         assert(H[k-1].
id != H[k-2].
id);
   904   for (
int i = 
n-2, 
t = k+1; i >= 0; i--)
   906     while (k >= 
t && 
cross(H[k-2], H[k-1], P[i]) <= 0)
   912   size_t hull_noRep = k-1; 
   914   polygonContourPtr->resize(hull_noRep);
   917   for(
size_t i=0; i < hull_noRep; i++)
   919     polygonContourPtr->points[i] = pointCloud->points[ H[i].id ];
   924   float ct = fabs ( v3normal[k0] );
   926   Eigen::Vector3f massCenter = Eigen::Vector3f::Zero();
   927   for(
size_t i=0, j=1; i < hull_noRep; i++, j++)
   929     float cross_segment = H[i].x * H[j].y - H[i].y * H[j].x;
   931     AreaX2 += cross_segment;
   932     massCenter[k1] += (H[i].x + H[j].x) * cross_segment;
   933     massCenter[k2] += (H[i].y + H[j].y) * cross_segment;
   935   areaHull = fabs (AreaX2) / (2 * ct);
   937   v3center[k1] /= (3*AreaX2);
   938   v3center[k2] /= (3*AreaX2);
   939   v3center[k0] = (-d - v3normal[k1]*massCenter[k1] - v3normal[k2]*massCenter[k2]) / v3normal[k0];
   941   d = -v3normal .dot( v3center );
   944   Eigen::Matrix2f covariances = Eigen::Matrix2f::Zero();
   945   Eigen::Vector2f p1, p2;
   946   p2[0] = H[0].x-massCenter[k1]; p2[1] = H[0].y-massCenter[k2];
   948   for(
size_t i=1; i < hull_noRep; i++)
   951     p2[0] = H[i].x-massCenter[k1]; p2[1] = H[i].y-massCenter[k2];
   952     float lenght_side = (p1 - p2).
norm();
   954     covariances += lenght_side * (p1*p1.transpose() + p2*p2.transpose());
   959   Eigen::SelfAdjointEigenSolver<Eigen::Matrix2f> evd (covariances);
   961   for (
int i = 0; i < 2; ++i)
   963     std::cout << 
"Eig " << evd.eigenvalues()[i] << 
" v " << evd.eigenvectors().col(i).transpose() << 
"\n";
   965   if( evd.eigenvalues()[0] > 2 * evd.eigenvalues()[1] )
   967     elongation = sqrt(evd.eigenvalues()[0] / evd.eigenvalues()[1]);
   968     v3PpalDir[k1] = evd.eigenvectors()(0,0);
   969     v3PpalDir[k2] = evd.eigenvectors()(1,0);
   970     v3PpalDir[k0] = (-d - v3normal[k1]*v3PpalDir[k1] - v3normal[k2]*v3PpalDir[k2]) / v3normal[k0];
   971     v3PpalDir /= v3PpalDir.norm();
   978   float distThres2 = distThreshold * distThreshold;
   981   if( (v3center - plane_nearby.
v3center).squaredNorm() < distThres2 )
   984   for(
unsigned i=1; i < polygonContourPtr->size(); i++)
   992   for(
unsigned i=1; i < polygonContourPtr->size(); i++)
  1000   for(
unsigned i=1; i < polygonContourPtr->size(); i++)
  1010 bool Plane::isSamePlane(
Plane &plane_nearby, 
const float &cosAngleThreshold, 
const float ¶llelDistThres, 
const float &proxThreshold)
  1013   if( v3normal .dot (plane_nearby.
v3normal) < cosAngleThreshold )
  1017   float dist_normal = v3normal .dot (plane_nearby.
v3center - v3center);
  1018   if(fabs(dist_normal) > parallelDistThres ) 
  1022   if( !isPlaneNearby(plane_nearby, proxThreshold) )
  1030 bool Plane::isSamePlane(Eigen::Matrix4f &Rt, 
Plane &plane_, 
const float &cosAngleThreshold, 
const float ¶llelDistThres, 
const float &proxThreshold)
  1032   Plane plane = plane_;
  1037   if(fabs(d - plane.
d) > parallelDistThres )
  1041   if( v3normal.dot(plane.
v3normal) < cosAngleThreshold )
  1054   return isPlaneNearby(plane, proxThreshold);
  1060      (fabs(v3colorNrgb[0] - plane.
v3colorNrgb[0]) > colorThreshold ||
  1061       fabs(v3colorNrgb[1] - plane.
v3colorNrgb[1]) > colorThreshold )
  1077   assert(inliers.size() > 0 && same_plane_patch.
inliers.size() > 0);
  1078   v3normal = (inliers.size()*v3normal + same_plane_patch.
inliers.size()*same_plane_patch.
v3normal);
  1079   v3normal = v3normal / v3normal.norm();
  1086   static pcl::VoxelGrid<pcl::PointXYZRGBA> merge_grid;
  1087   merge_grid.setLeafSize(0.05,0.05,0.05);
  1088   pcl::PointCloud<pcl::PointXYZRGBA> mergeCloud;
  1089   merge_grid.setInputCloud (planePointCloudPtr);
  1090   merge_grid.filter (mergeCloud);
  1091   planePointCloudPtr->clear();
  1092   *planePointCloudPtr = mergeCloud;
  1097   inliers.insert(inliers.end(), same_plane_patch.
inliers.begin(), same_plane_patch.
inliers.end());
  1101   computeMassCenterAndArea();
  1103   d = -v3normal .dot( v3center );
  1106   forcePtsLayOnPlane();
  1111   areaVoxels= planePointCloudPtr->size() * 0.0025;
  1119 assert(inliers.size() > 0 && same_plane_patch.
inliers.size() > 0);
  1120   v3normal = (inliers.size()*v3normal + same_plane_patch.
inliers.size()*same_plane_patch.
v3normal);
  1121   v3normal = v3normal / v3normal.norm();
  1126   inliers.insert(inliers.end(), same_plane_patch.
inliers.begin(), same_plane_patch.
inliers.end());
  1132   computeMassCenterAndArea();
  1134   calcElongationAndPpalDir();
  1136   d = -v3normal .dot( v3center );
  1142   for(
size_t i=0; i < hist_H.size(); i++)
  1144     hist_H[i] += same_plane_patch.
hist_H[i];
  1153   v3normal = Rt.block(0,0,3,3) * v3normal;
  1154   v3PpalDir = Rt.block(0,0,3,3) * v3PpalDir;
  1157   v3center = Rt.block(0,0,3,3) * v3center + Rt.block(0,3,3,1);
  1159   d = -(v3normal. dot (v3center));
  1162   pcl::transformPointCloud(*polygonContourPtr, *polygonContourPtr, Rt);
  1164   pcl::transformPointCloud(*planePointCloudPtr, *planePointCloudPtr, Rt);
 
Eigen::Vector4f getMultiDimMeanShift_color(std::vector< Eigen::Vector4f > &data, dataType &stdDevHist, dataType &concentration)
 
Eigen::Vector3f diffPoints(const POINT &P1, const POINT &P2)
 
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL. 
 
pcl::PointCloud< pcl::PointXYZRGBA >::Ptr polygonContourPtr
 
void readFromStream(mrpt::utils::CStream &in, int version)
Introduces a pure virtual method responsible for loading from a CStream This can not be used directly...
 
void transform(Eigen::Matrix4f &Rt)
 
The virtual base class which provides a unified interface for all persistent objects in MRPT...
 
A class used to store a planar feature (Plane for short). 
 
#define IMPLEMENTS_SERIALIZABLE(class_name, base, NameSpace)
This must be inserted in all CSerializable classes implementation files. 
 
void mergePlane2(Plane &plane)
 
GLuint GLuint GLsizei GLenum const GLvoid * indices
 
void mergePlane(Plane &plane)
 
Eigen::Vector3f v3colorNrgb
! Radiometric description 
 
void calcConvexHullandParams(pcl::PointCloud< pcl::PointXYZRGBA >::Ptr &pointCloud, std::vector< size_t > &indices=DEFAULT_VECTOR)
 
void calcElongationAndPpalDir()
 
! mPointHull serves to calculate the convex hull of a set of points in 2D, which are defined by its p...
 
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
 
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations. 
 
pcl::PointCloud< pcl::PointXYZRGBA >::Ptr planePointCloudPtr
 
dataType getHistogramMeanShift(std::vector< dataType > &data, double range, dataType &stdDevHist_out)
 
void forcePtsLayOnPlane()
 
float cross(const mPointHull &O, const mPointHull &A, const mPointHull &B)
 
bool isSamePlane(Plane &plane, const float &cosAngleThreshold, const float &distThreshold, const float &proxThreshold)
 
bool isPlaneNearby(Plane &plane, const float distThreshold)
 
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries. 
 
float compute2DPolygonalArea()
Compute the area of a 2D planar polygon patch - using a given normal. 
 
float PBMAP_IMPEXP dist3D_Segment_to_Segment2(Segment S1, Segment S2)
 
GLdouble GLdouble GLdouble r
 
void computeMassCenterAndArea()
Compute the patch's convex-hull area and mass center. 
 
std::vector< int32_t > inliers
! Convex Hull 
 
std::vector< float > hist_H
 
bool operator<(const CPoint< DERIVEDCLASS > &a, const CPoint< DERIVEDCLASS > &b)
Used by STL algorithms. 
 
Eigen::Vector3f v3center
! Geometric description 
 
typedef void(APIENTRYP PFNGLBLENDCOLORPROC)(GLclampf red
 
float concentrationThreshold
 
unsigned __int32 uint32_t
 
bool hasSimilarDominantColor(Plane &plane, const float colorThreshold)
 
void calcConvexHull(pcl::PointCloud< pcl::PointXYZRGBA >::Ptr &pointCloud, std::vector< size_t > &indices=DEFAULT_VECTOR)
! Calculate the plane's convex hull with the monotone chain algorithm. 
 
CONTAINER::Scalar norm(const CONTAINER &v)
 
Eigen::Vector3f getVector3fromPointXYZ(pointPCL &pt)