RANSAC Sphere can't find distant objects

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

RANSAC Sphere can't find distant objects

Lacha
I have point cloud consisting of sphere and some outliers. If points are near the origin, RANSAC can find sphere, but if points are far from origin (Z about 100 in my case), algorithm find no inliers. What could be the problem? Is there any fix?

My code:
    pcl::search::KdTree<PointXYZ>::Ptr kdtree (new pcl::search::KdTree<PointXYZ> ());
    pcl::NormalEstimation<PointXYZ, pcl::Normal> ne;
    ne.setSearchMethod (kdtree);
    ne.setInputCloud (cloud);
    ne.setKSearch (50);
    ne.compute (*normals);

    pcl::SACSegmentationFromNormals<PointXYZ, pcl::Normal> seg;
    seg.setOptimizeCoefficients (false);
    seg.setModelType (pcl::SACMODEL_NORMAL_SPHERE);
    seg.setMethodType (pcl::SAC_RANSAC);
    seg.setMaxIterations (900);
    seg.setDistanceThreshold (0.01);
    seg.setNormalDistanceWeight (0.1);
    seg.setSamplesMaxDist(0.1, kdtree);
    seg.setRadiusLimits(0.03, 0.1);

    seg.setInputCloud (cloud);
    seg.setInputNormals (normals);
    seg.segment (*inliers, *sphereCoefficient);
PCL 1.8, VTK 7.0, Qt 5.7.0, Ubuntu 16.04 64bit
Reply | Threaded
Open this post in threaded view
|

Re: RANSAC Sphere can't find distant objects

james
Administrator
I can confirm this is the case for me too on PCL 1.8.0

With a translation of 100, no sphere is found, however, changing the translation to 0.1 works as expected.

                //generate points in searchCloud
        cout << "generating cloud" << endl;
                searchCloud->width = 480;
                searchCloud->height = 240;
                searchCloud->resize(searchCloud->width*searchCloud->height);
                for (size_t i = 0; i < searchCloud->points.size(); i++)
                {
                        searchCloud->points[i].x = 1 * rand() / (RAND_MAX + 1.0f);
                        searchCloud->points[i].y = 1 * rand() / (RAND_MAX + 1.0f);
                        searchCloud->points[i].z = 1 * rand() / (RAND_MAX + 1.0f);
                }

        //transform cloud
        cout << "transforming cloud" << endl;
        Eigen::Affine3f transform = Eigen::Affine3f::Identity();
        transform.translation() << 100, 100, 100;
        pcl::transformPointCloud(*searchCloud, *searchCloud, transform);


                //find sphere
        cout << "finding sphere" << endl;
                IndicesPtr sphereInliers(new Indices);
                CoefficientsPtr sphereCoefficients(new Coefficients);
                find_sphere(searchCloud, sphereCoefficients, sphereInliers, 1000, 100, 800, 900);
                cout << "found sphere with " << sphereInliers->indices.size() << " points" << endl;
                pcl::copyPointCloud(*searchCloud, *sphereInliers, *sphereCloud);