Point cloud clustering and region boundary estimation

Point cloud clustering and region boundary estimation

  Point cloud data for the certain features and regular division clustering, the paper proposes a method of clustering and spatial characteristics of the fusion, and the detection region of the boundary on the basis of clustering (on one side of the article which is mentioned method), the specific idea of ​​the algorithm is as follows:

(1) point cloud pretreatment , pumping Greek, and the like to dry .

(2) can not be removed divided areas;

(3) The following is the remaining area of the cluster dividing, selecting x maximum surface as a seed face search began , the search for the adjacent radius, a radius is R , when the radius R searched within n the triangles, these triangles Comparative surface weighted mean mid_d difference threshold is set delta_d, if the difference is less than the distance threshold value delta_d , then the search to be a cluster triangular face custer integration, otherwise, no fusion; then there is a new incoming surface seed face, continue to search for the above, and calculates a new weighted average pitch mid_d . This iteration until all the complete division of all the clusters.

 

schematic diagram

(4) can be obtained by the third step many clustering Custers , through all clusters Custers , provided the minimum number of points or area threshold A3 , excluding an area less than A3 clustering custer ; each custer triangulate surface boundary detection and integration.

(5) for detecting a boundary of the fourth step, serration treatment, mainly boundary smoothing processing, there is a smoothing intensity threshold dis_threshold , as an area boundary ; return those data area boundary.

(Note: The third major step is to divide the two-step, one-step Cluster Theory)

 

Part of the code:

int Division(
    std::vector<PointType>& in_points,
    std::vector<PCTTM_TriangleFace>& face_vect,
    std::vector<double>& distance_vect,
    std::vector<PointType>& face_center_points2,
    std::vector<std::vector<int>>& region_vector, 
    const double& d_threshold, 
    const int& num_threshold) {

    if (in_points.size()<3 || face_vect.size()==0|| distance_vect.size()==0)
    {
        std::cout << "in_points.size()<3 || face_vect.size()==0|| distance_vect.size()==0" << std::endl;
        return -1;
    }

    std::vector<PointType> face_center_points;
    //std::vector<point3f_rgba> face_center_points2;
    //计算三角面几何中心 
    std::vector<double> distance_vect2;     //剔除灰色
    std::vector<int> out_index(face_vect.size());
    for (size_t i = 0; i < face_vect.size(); i++)
    {
        PointType pt2 = calculateFaceCenter(in_points[face_vect[i].p_index_0], in_points[face_vect[i].p_index_1], in_points[face_vect[i].p_index_2]);

        int d_index = static_cast<int>(10.0*d_threshold / 5.0);
        int index = static_cast<int>(10.0*distance_vect[i] / 5.0);
        if (distance_vect[i] <= d_threshold)
        {
            face_center_points2.push_back(pt2);
            distance_vect2.push_back(distance_vect[i]);
        }
        else
        {
            out_index[i] = -1;
        }
        face_center_points.push_back(pt2);
    }

    / * Zoning **************** discrete points ************************ * /
    KDT::KDTree tree;
    tree.setInputPointCloud(face_center_points2);
    tree.setNumOfLeafData ( 100 );
    tree.buildKDTree();

    double density = 0.0;
    if (caculateDensity(face_center_points2, density) == -1) {
        std::cout << "caculateDensity() failed !!! " << std::endl;
        return -1;
    }

    const  Double delta_threshold = 1.49999 ;   // 0.3-3.0 
    const  a float searchRadius = 3.0 * Density;    // point cloud 1-3 times the average density

    //std::vector<std::vector<int>> region_vector;
    std::vector<int> index_(face_center_points2.size());
    for (size_t i = 0; i < face_center_points2.size(); i++)
    {
        if (index_[i] == -1)
        {
            continue;
        }

        std::vector<int> region_;
        double mid_d = 0.0;

        / * **************** iteration loop search ************************************************************ * /
        region_.push_back(i);
        index_[i] = -1;
        int t = 0;
        mid_d = distance_vect2[i];
        while (t < region_.size())
        {
            //mid_d = distance_vect2[region_[t]];
            const PointType searchPoint2 = face_center_points2[region_[t]];
            std::vector<size_t> searchIndex2;
            std::vector<float> searchDistance2;
            double dis = 0.0;
            int num = 0;
            if (tree.runKNNSearchRadius(searchPoint2, searchRadius, searchIndex2, searchDistance2) > 1) {
                for (size_t n = 0; n < searchIndex2.size(); n++)
                {
                    if (index_[searchIndex2[n]] != -1 && abs(distance_vect2[searchIndex2[n]] - mid_d) < delta_threshold)
                    {
                        region_.push_back(searchIndex2[n]);
                        index_[searchIndex2[n]] = -1;
                        dis += distance_vect2[searchIndex2[n]];
                        a ++ ;
                    }
                }
            }

            mid_d = (dis + mid_d*(region_.size() - num)) / region_.size();
            t++;
        }
        // access greater than Fenwick 
        IF (region_.size ()> num_threshold)
        {
            region_vector.push_back(region_);
        }
    }

    return 0;
}

 

effect:

 

 

Guess you like

Origin www.cnblogs.com/lovebay/p/12545370.html