• 一种点云快速法线估计方法


    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 估计法线
    int TopographyMesh::normalEstimation(
        std::vector<PointType>& in_points,
        std::vector<PCTTM_TriangleFace>& face_vect, 
        std::vector<Normal>& out_normals_face,
        std::vector<Normal>& out_normals_point,
        const int& k)
    {
        if (in_points.size() <= 3)
        {
            std::cout << "pointVect <= 3 ..." << std::endl;
            return -1;
        }
    
        if (k<3)
        {
            std::cout << "'K' input must >= 3 ..." << std::endl;
            return -1;
        }
        int dataSize = in_points.size();
    
        std::vector<Vector3d> n_vect(face_vect.size());
        std::vector<PointType> mid_vect(face_vect.size());
        for (size_t i = 0; i < face_vect.size(); i++)
        {
            Vector3d v(
                in_points[face_vect[i].p_index_1].x - in_points[face_vect[i].p_index_0].x,
                in_points[face_vect[i].p_index_1].y - in_points[face_vect[i].p_index_0].y,
                in_points[face_vect[i].p_index_1].z - in_points[face_vect[i].p_index_0].z);
            Vector3d w(
                in_points[face_vect[i].p_index_2].x - in_points[face_vect[i].p_index_0].x,
                in_points[face_vect[i].p_index_2].y - in_points[face_vect[i].p_index_0].y,
                in_points[face_vect[i].p_index_2].z - in_points[face_vect[i].p_index_0].z);
    
             // Normal n(0.0, 0.0, 100.0);
             //法线方向矫正
             Eigen::Vector3d v1= v.cross(w);
             Eigen::Vector3d v2(0.0, 0.0, 100.0);
             if (atan2(v1.cross(v2).norm(), v1.transpose() * v2) > 0.5*M_PI)   //判断点的法线  与 固定法线的夹角
             {
                 n_vect[i] = (-1)*v1;
             }
             else
             {
                 n_vect[i] = v1;
             }
        
            //三角形几何中心
            mid_vect[i].x = (in_points[face_vect[i].p_index_2].x + in_points[face_vect[i].p_index_1].x + in_points[face_vect[i].p_index_0].x) / 3.0;
            mid_vect[i].y = (in_points[face_vect[i].p_index_2].y + in_points[face_vect[i].p_index_1].y + in_points[face_vect[i].p_index_0].y) / 3.0;
            mid_vect[i].z = (in_points[face_vect[i].p_index_2].z + in_points[face_vect[i].p_index_1].z + in_points[face_vect[i].p_index_0].z) / 3.0;
        }
    
        out_normals_face = n_vect;
    
        //kdtree “k临近”
        KDT::KDTree skdtree;
        skdtree.setNumOfLeafData(100);   //20-200  叶子存储数据数阈值
        skdtree.setInputPointCloud(mid_vect);
        skdtree.buildKDTree();
    
        out_normals_point.resize(dataSize);
        for (size_t j = 0; j < dataSize; j++)
        {
            std::vector<size_t> searchIndex(k);
            std::vector<float> searchDistance(k);
            skdtree.runKNNSearchK(in_points[j], k, &(searchIndex[0]), &(searchDistance[0]));
        
            Eigen::Vector3d xyz(0.0,0.0,0.0);
            for (size_t i = 0; i < k; i++)
            {
                xyz += n_vect[searchIndex[i]];
            }
            out_normals_point[j] = xyz / (1.0*k);
        }
        
    
        return 0;
    }
  • 相关阅读:
    BZOJ1093: [ZJOI2007]最大半连通子图
    BZOJ4033: [HAOI2015]树上染色
    BZOJ1977: [BeiJing2010组队]次小生成树 Tree
    BZOJ4944: [Noi2017]泳池
    BZOJ1269: [AHOI2006]文本编辑器editor
    BZOJ4596: [Shoi2016]黑暗前的幻想乡
    BZOJ1815: [Shoi2006]color 有色图
    BZOJ1488: [HNOI2009]图的同构
    BZOJ3527: [Zjoi2014]力
    Salazar Slytherin's Locket CodeForces
  • 原文地址:https://www.cnblogs.com/lovebay/p/12370003.html
Copyright © 2020-2023  润新知