PointCloudLibrary/pcl

Cropbox filter strangely returns 0 points

pendar747 opened this issue · 31 comments

This is how I am using cropbox:

    Vector4f minVec;
    Vector4f maxVec;
    getMinMax3D<PointT>(*input_, minVec, maxVec);

    PointCloudPtr filteredCloud(new PointCloud<PointT>());
    vector<int> filteredIndices;

    CropBox<PointT> cropper;
    cropper.setMax(maxVec);
    cropper.setMin(minVec);
    cropper.setInputCloud(input_);
    cropper.filter(*filteredCloud);
    cropper.filter(filteredIndices);

This produces very strange behaviour, which is when I only filter with a pointcloud it works, but when I use the indices vector both cases fail and when I remove the indices case the pointcloud case also fails!

I'm no sure what could cause this. I am using pcl 1.8.0 on ubuntu.

Update

When I use CropBox<PointT> cropper(true); instead this works, Although I'm not sure why should extract_removed_indices be set to true here since I didn't remove any indices previously.

But this still doesn't work when I use it on a cloud that's been transformed before.

I am facing exact the same problem .

pcl::CropBox<PointNT> cropBox;
cropBox.setInputCloud(scene);
cropBox.setTranslation(averageV);
cropBox.setMin(minV);
cropBox.setMax(maxV);
cropBox.filter(*cropedPC);

CropedPC result is not as expected

Any cloud with any indices? Can you construct a small hand crafted point cloud in which you verify the behavior, so we can have a look at it later?

Hi I figure out the reason.

I removed setTranslation(averageV). I have already calculated the cropBox translation in min vector and max vector.

Thanks for your support!

When I use CropBox cropper(true); instead this works,

This does not work for me either. I am still getting 0 points if I check the indices that have been generated. Any other possibility?

I had same problem with both 16.04+PCL1.8.0 and 16.04+PCL1.8.1.
I solved this issue by -DPCL_ENABLE_SSE:BOOL=FALSE flag for PCL build.

mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release -DPCL_ENABLE_SSE:BOOL=FALSE ..
make -j $(nproc)
sudo make install

I am using the PCL that comes with ROS Kinetic. It still has this problem.

If you are using PCL debian package in Kinetic, it must be PCL 1.7 version, so you may not have this issue.
If you are using PCL 1.8 from source, you should carefully build it with sse flag as above.

@knorth55
Thanks for the reply. I am using the 1.7 version (PCL_VERSION gives me 100702) that comes with ROS. I never built PCL from source.

@TixiaoShan In that case, I have no idea, sorry.

I can confirm I get this issue with PCL 1.11.1 building it like so along with ros perception_pcl:

    wget \
        --directory-prefix="/opt/" \
        https://github.com/PointCloudLibrary/pcl/archive/pcl-1.11.1.tar.gz && \
    mkdir \
        --parents "/opt/pcl-1.11.1" && \
    tar \
        --extract \
        --file "/opt/pcl-1.11.1.tar.gz" \
        -C "/opt/pcl-1.11.1" \
        --strip-components 1 && \
    rm "/opt/pcl-1.11.1.tar.gz" && \
    cd "/opt/pcl-1.11.1" && \
    mkdir build && \
    cd build && \
    cmake -DCMAKE_BUILD_TYPE=Release .. && \
    make -j2 && \
    make -j2 install

    wget \
        --directory-prefix="$ROS_WS/src" \
        https://github.com/ros-perception/perception_pcl/archive/1.7.2.tar.gz && \
    mkdir \
        --parents "$ROS_WS/src/perception_pcl" && \
    tar \
        --extract \
        --file "$ROS_WS/src/1.7.2.tar.gz" \
        -C "$ROS_WS/src/perception_pcl" \
        --strip-components 1 && \
    rm "$ROS_WS/src/1.7.2.tar.gz"

Here is how I use cropbox:

        pcl::CropBox<pcl::PointXYZ> crop(false);
        crop.setKeepOrganized(false);
        crop.setNegative(false);
        crop.setMin(Eigen::Vector4f(xmin, ymin, zmin, 1));
        crop.setMax(Eigen::Vector4f(xmax, ymax, zmax, 1));
        crop.setInputCloud(in_cloud);
        crop.filter(*out_cloud);

cloud.pcd.gz

Here is how I call it:

xmin, xmax = 0.37763, 0.73757
ymin, ymax = 1.2728, 2.002
zmin, zmax = 8.203, 8.8283

and it incorrectly returns 354 nan values on the attached cloud.

If instead I just use ros-melodic built-in ros_pcl then it correctly returns 354 non-nan values.

@zoombinis Can you test what happens if you do it like this instead (similar for max):
Eigen::Vector4f min_pt(xmin, ymin, zmin, 1); crop.setMin(min_pt);
Can you also test what crop.getMin() returns?
Did you test the suggested solution above (with -DPCL_ENABLE_SSE:BOOL=FALSE)?

I get this problem using ubuntu 16.04 + pcl 1.8.1, I did what you mentioned and found that my cropbox can return points being set but it just cannot crop a cloud based on these points. Extraordinary.

@zoombinis Can you test what happens if you do it like this instead (similar for max):
Eigen::Vector4f min_pt(xmin, ymin, zmin, 1); crop.setMin(min_pt);
Can you also test what crop.getMin() returns?
Did you test the suggested solution above (with -DPCL_ENABLE_SSE:BOOL=FALSE)?

@Ice833 What is your problem exactly? That CropBox returns 0 points? Or that it returns points where x, y, z are nan?

@mvieth No point was returned, I printed the min_pt, max_pt I've input, find they have been set correctly but the output cloud remain empty as its size is 0. Strangely, sometimes it has some points as I set the box as same as the default size claimed in the CropBox's constructor. It seems that the change on min_pt and max_pt of the box are restricted.

@mvieth No point was returned, I printed the min_pt, max_pt I've input, find they have been set correctly but the output cloud remain empty as its size is 0. Strangely, sometimes it has some points as I set the box as same as the default size claimed in the CropBox's constructor. It seems that the change on min_pt and max_pt of the box are restricted.

@Ice833 Could you create a very simple code example where the problem occurs? Maybe just a point cloud with two points (one inside the box, one outside) that is filtered with CropBox? The problem seems to be so specific that every aspect of the code matters.

I have the same problem about pcl::CropBox, I find a bug. My program is is very simple.

#include
#include <pcl/point_types.h>
#include <pcl/filters/crop_box.h>

int main()
{
pcl::PointCloudpcl::PointXYZ::Ptr cloud(new pcl::PointCloudpcl::PointXYZ);
pcl::PointCloudpcl::PointXYZ::Ptr cloud_filtered(new pcl::PointCloudpcl::PointXYZ);

 // Fill in the cloud data
 cloud->width = 5;
 cloud->height = 1;
 cloud->points.resize(cloud->width * cloud->height);

 for (auto& point : *cloud)
 {
      point.x = 1024 * rand() / (RAND_MAX + 1.0f);
      point.y = 1024 * rand() / (RAND_MAX + 1.0f);
      point.z = 1024 * rand() / (RAND_MAX + 1.0f);
 }

 std::cerr << "Cloud before filtering: " << std::endl;
 for (const auto& point : *cloud)
      std::cerr << "    " << point.x << " "
      << point.y << " "
      << point.z << std::endl;

 pcl::CropBox<pcl::PointXYZ> cropbox;
 cropbox.setMin(Eigen::Vector4f(0, 0, 0, 1));
 cropbox.setMax(Eigen::Vector4f(700, 700, 700, 1));
 //cropbox.setNegative(false);                
 cropbox.setInputCloud(cloud);
 cropbox.filter(*cloud_filtered);

 std::cerr << "Cloud after filtering: " << std::endl;
 for (const auto& point : *cloud_filtered)
      std::cerr << "    " << point.x << " "
      << point.y << " "
      << point.z << std::endl;


 return (0);

}

Compile successfully, but the running results are inconsistent, sometimes it's right, sometimes it doesn't find the point.

Is it a bug?

@155cannon What do you mean with "right results"? Since the input point cloud is random, it can happen that no point is within the box from 0 to 700. But that does not necessarily mean that the CropBox is the problem. What results would you expect?

@155cannon What do you mean with "right results"? Since the input point cloud is random, it can happen that no point is within the box from 0 to 700. But that does not necessarily mean that the CropBox is the problem. What results would you expect?

In my computer(win10+visual studio 2019 community+ pcl 1.12.0), the cloud is always constant ,the 5 points are
Cloud before filtering:
1.28125 577.094 197.938
828.125 599.031 491.375
358.688 917.438 842.563
764.5 178.281 879.531
727.531 525.844 311.281

@155cannon So all except the first point should be filtered out? But sometimes there is no point in the output cloud? Is there anything you change between successful and unsuccessful runs? Or do you just run it several times (without changing anything and without recompiling) and sometimes it returns one point, sometimes no points?

Please replicate with non-random points. We can trust the report unless the random is removed. I don't think windows' random API guarantees that the data would be bit-by-bit replayable.

#include
#include <pcl/point_types.h>
#include <pcl/filters/crop_box.h>

int main()
{
pcl::PointCloudpcl::PointXYZ::Ptr cloud(new pcl::PointCloudpcl::PointXYZ);
pcl::PointCloudpcl::PointXYZ::Ptr cloud_filtered(new pcl::PointCloudpcl::PointXYZ);
cloud->width = 5;
cloud->height = 1;
cloud->points.resize(cloud->width * cloud->height);

 cloud->points[0].x = 23;
 cloud->points[0].y = 23;
 cloud->points[0].z = 23;

 cloud->points[1].x = 400;
 cloud->points[1].y = 701;
 cloud->points[1].z = 230;

 cloud->points[2].x = 900;
 cloud->points[2].y = 23;
 cloud->points[2].z = 523;

 cloud->points[3].x = 623;
 cloud->points[3].y = 723;
 cloud->points[3].z = 223;

 cloud->points[4].x = 230;
 cloud->points[4].y = 423;
 cloud->points[4].z = 123;

 std::cerr << "Cloud before filtering: " << std::endl;
 for (const auto& point : *cloud)
      std::cerr << "    " << point.x << " "
      << point.y << " "
      << point.z << std::endl;

 pcl::CropBox<pcl::PointXYZ> cropbox;
 cropbox.setMin(Eigen::Vector4f(0, 0, 0, 1));
 cropbox.setMax(Eigen::Vector4f(700, 700, 700, 1));             
 cropbox.setInputCloud(cloud);
 cropbox.filter(*cloud_filtered);

 std::cerr << "Cloud after filtering: " << std::endl;
 for (const auto& point : *cloud_filtered)
      std::cerr << "    " << point.x << " "
      << point.y << " "
      << point.z << std::endl;

 return (0);

}
@mvieth @kunaltyagi you can test the above program. Thank you!

@mvieth @kunaltyagi I run the above program in Ubuntu Linux with pcl-1.10, the output result is always right. But in my environment(win10+visual studio 2019 community+ pcl 1.12.0), sometimes there is no point in the output result.

@155cannon How did you install PCL 1.12.0 on your Windows? Do you use SIMD instructions (e.g. SSE, AVX) when compiling the sample program you posted?

@mvieth @kunaltyagi
I find the problem,it's about eigen memory. In Debug,the output result is always right with a memory fault in the code below:
EIGEN_DEVICE_FUNC inline void aligned_free(void *ptr)
{
#if (EIGEN_DEFAULT_ALIGN_BYTES==0) || EIGEN_MALLOC_ALREADY_ALIGNED
std::free(ptr);
#else
handmade_aligned_free(ptr);
#endif
}
In release, sometimes there is no point in the output result with no eigen memory fault, sometimes there is the right point in the output result with the same eigen memory fault as in debug.
So what's wrong with eigen?

@155cannon Yes, I suspected that it has something to do with Eigen's memory management. That is why I asked: How did you install PCL 1.12.0 on your Windows? Do you use SIMD instructions (e.g. SSE, AVX) when compiling the sample program you posted?
If SIMD instructions are used in one case, but not the other, that could lead to this problem.

I just install the "PCL-1.12.0-AllInOne-msvc2019-win64.exe" and download the "pcl-1.12.0-rc1-pdb-msvc2019-win64.zip". Then unzip the pcl-1.12.0-rc1-pdb-msvc2019-win64.zip and put the pdb files in C:\Program Files\PCL 1.12.0\bin. Then I configurate the visual studio 2019(VC++ include, lib path and linker->input->Additional dependencies ). That's all.

@mvieth I dont' know how to check if I use SIMD instructions (e.g. SSE, AVX).

See project configuration window like here: https://stackoverflow.com/questions/20169064/does-archavx-enable-avx2.

However it ask a bit different question, it shows where you can set it for your project. Assuming you don't use Cmake to create your solution.

I get the same problem in Release with debug. But In release I get filtered points, in RelWDebug I get no points. I use all ine one installer 1.13.0

Just use pcl-1.10.1, cropbox works correctly! Both pcl-1.11.1 and 1.12.0 has the eigen memory fault.

Since pull request #4962 is now merged, I am confident that this issue is fixed. However, if anyone still has this problem with the current master branch or future PCL releases (at least 1.13) please comment/reopen