Understanding pcl::getMinMax3D()

4.3k Views Asked by At

I have a point cloud data with wide range in all 3 dimensions. I have filtered it using pcl::ConditionalRemoval::filter() in range -20 >= x >= 20, -20 >= y >= 20 and -2 >= z >= 2. Now I want to have min and max values in each dimension, so I searched online for nay PCL function. I got pcl::getMinMax3D. I used it and to verify I also manually searched in the cloud data. The code is as below:

float xmin = 10000, xmax=-10000;

cout << "Manual Search Result:"<<endl;

for(unsigned int i = 0; i < filtered_data->size(); i++)
{
    if(filtered_data->at(i)._PointXYZ::x > xmax)
        xmax = filtered_data->at(i)._PointXYZ::x;
    if(filtered_data->at(i)._PointXYZ::x < xmin)
        xmin = filtered_data->at(i)._PointXYZ::x;
}

cout << "Xmin: " << xmin << "\t\tXmax: " << xmax << endl;

float ymin = 10000, ymax=-10000;

for(unsigned int i = 0; i < filtered_data->size(); i++)
{
    if(filtered_data->at(i)._PointXYZ::y > ymax)
        ymax = filtered_data->at(i)._PointXYZ::y;
    if(filtered_data->at(i)._PointXYZ::y < ymin)
        ymin = filtered_data->at(i)._PointXYZ::y;
}
cout << "Ymin: " << ymin << "\t\tYmax: " << ymax << endl;

float zmin = 10000, zmax=-10000;

for(unsigned int i = 0; i < filtered_data->size(); i++)
{
    if(filtered_data->at(i)._PointXYZ::z > zmax)
        zmax = filtered_data->at(i)._PointXYZ::z;
    if(filtered_data->at(i)._PointXYZ::z < zmin)
        zmin = filtered_data->at(i)._PointXYZ::z;
}
cout << "Zmin: " << zmin << "\t\tZmax: " << zmax << endl;

pcl::PointXYZ minPt, maxPt;
pcl::getMinMax3D (*filtered_data, minPt, maxPt);

cout << "getMinMax3D Search Result:"<<endl;

std::cout << "Min x: " << minPt.x << "\t\tMax x: " << maxPt.x << std::endl;
std::cout << "Min y: " << minPt.y << "\t\tMax y: " << maxPt.y << std::endl;
std::cout << "Min z: " << minPt.z << "\t\tMax z: " << maxPt.z << std::endl;

The output I m getting is:

Manual Search Result:
Xmin: -19.992       Xmax: 19.915
Ymin: -19.75        Ymax: 19.982
Zmin: -1.999        Zmax: 1.059
getMinMax3D Search Result: 
Min x: -3.895       Max x: 3.967
Min y: -4.238       Max y: 4.291
Min z: -1.887       Max z: 0

Is my understanding wrong about the usage of getMinMax3D()?

1

There are 1 best solutions below

0
On

If the input cloud has NAN point, make sure you set cloud.is_dense as false, otherwise the function pcl::getMinMax3D would not check for NaN.

Here is original implementation from https://pointclouds.org/documentation/common_2include_2pcl_2common_2impl_2common_8hpp_source.html


 template <typename PointT> inline void
 pcl::getPointsInBox (const pcl::PointCloud<PointT> &cloud, 
                      Eigen::Vector4f &min_pt, Eigen::Vector4f &max_pt,
                      Indices &indices)
 {
   indices.resize (cloud.size ());
   int l = 0;
  
   // If the data is dense, we don't need to check for NaN
   if (cloud.is_dense)
   {
     for (std::size_t i = 0; i < cloud.size (); ++i)
     {
       // Check if the point is inside bounds
       if (cloud[i].x < min_pt[0] || cloud[i].y < min_pt[1] || cloud[i].z < min_pt[2])
         continue;
       if (cloud[i].x > max_pt[0] || cloud[i].y > max_pt[1] || cloud[i].z > max_pt[2])
         continue;
       indices[l++] = int (i);
     }
   }
   // NaN or Inf values could exist => check for them
   else
   {
     for (std::size_t i = 0; i < cloud.size (); ++i)
     {
       // Check if the point is invalid
       if (!std::isfinite (cloud[i].x) || 
           !std::isfinite (cloud[i].y) || 
           !std::isfinite (cloud[i].z))
         continue;
       // Check if the point is inside bounds
       if (cloud[i].x < min_pt[0] || cloud[i].y < min_pt[1] || cloud[i].z < min_pt[2])
         continue;
       if (cloud[i].x > max_pt[0] || cloud[i].y > max_pt[1] || cloud[i].z > max_pt[2])
         continue;
       indices[l++] = int (i);
     }
   }
   indices.resize (l);
 }