KPConv cpp_wrappers c++ 代码

关于 KPConv 内Python使用的C++扩展代码

这两个工具的C++部分代码解析

cpp_neighbors


实际上在C++内使用的只是一个函数:
 

void batch_nanoflann_neighbors( vector<PointXYZ>& queries, vector<PointXYZ>& supports, vector<int>& q_batches, vector<int>& s_batches,
                                vector<int>& neighbors_indices, float radius ) {

    // Initialize variables
    // ******************

    // indices
    int i0 = 0;

    // Square radius
    float r2 = radius * radius;

    // Counting vector
    int                                 max_count = 0;
    float                               d2;
    vector<vector<pair<size_t, float>>> all_inds_dists( queries.size() );

    // batch index
    int b      = 0;
    int sum_qb = 0;
    int sum_sb = 0;

    // Nanoflann related variables
    // ***************************

    // CLoud variable
    PointCloud current_cloud;

    // Tree parameters
    nanoflann::KDTreeSingleIndexAdaptorParams tree_params( 10 /* max leaf */ );

    // KDTree type definition
    typedef nanoflann::KDTreeSingleIndexAdaptor<nanoflann::L2_Simple_Adaptor<float, PointCloud>, PointCloud, 3> my_kd_tree_t;

    // Pointer to trees
    my_kd_tree_t* index;

    // Build KDTree for the first batch element
    current_cloud.pts = vector<PointXYZ>( supports.begin() + sum_sb, supports.begin() + sum_sb + s_batches[ b ] );
    index             = new my_kd_tree_t( 3, current_cloud, tree_params );
    index->buildIndex();

    // Search neigbors indices
    // ***********************

    // Search params
    nanoflann::SearchParams search_params;
    search_params.sorted = true;

    for ( auto& p0 : queries ) {

        // Check if we changed batch
        if ( i0 == sum_qb + q_batches[ b ] ) {
            sum_qb += q_batches[ b ];
            sum_sb += s_batches[ b ];
            b++;

            // Change the points
            current_cloud.pts.clear();
            current_cloud.pts = vector<PointXYZ>( supports.begin() + sum_sb, supports.begin() + sum_sb + s_batches[ b ] );

            // Build KDTree of the current element of the batch
            delete index;
            index = new my_kd_tree_t( 3, current_cloud, tree_params );
            index->buildIndex();
        }

        // Initial guess of neighbors size
        all_inds_dists[ i0 ].reserve( max_count );

        // Find neighbors
        float  query_pt[ 3 ] = { p0.x, p0.y, p0.z };
        size_t nMatches      = index->radiusSearch( query_pt, r2, all_inds_dists[ i0 ], search_params );

        // Update max count
        if ( nMatches > max_count )
            max_count = nMatches;

        // Increment query idx
        i0++;
    }

    // Reserve the memory
    neighbors_indices.resize( queries.size() * max_count );
    i0     = 0;
    sum_sb = 0;
    sum_qb = 0;
    b      = 0;
    for ( auto& inds_dists : all_inds_dists ) {
        // Check if we changed batch
        if ( i0 == sum_qb + q_batches[ b ] ) {
            sum_qb += q_batches[ b ];
            sum_sb += s_batches[ b ];
            b++;
        }

        for ( int j = 0; j < max_count; j++ ) {
            if ( j < inds_dists.size() )
                neighbors_indices[ i0 * max_count + j ] = inds_dists[ j ].first + sum_sb;
            else
                neighbors_indices[ i0 * max_count + j ] = supports.size();
        }
        i0++;
    }

    delete index;

    return;
}

实际上这个函数的功能就是搜索xyz点云数组内每个点的邻近点,
假设 输入数组为:Nx3 ,
这时候执行邻近点搜索,但是,每个点的邻近点数量是不一致的,
在执行邻近搜索时,会得到每个点的邻近点个数,那么就以这个每个邻近点个数的最大值最为输出的第二个维度,如果最大邻近点个数表示为L,即最后的结果就是 NxL。
可以看到:

for ( int j = 0; j < max_count; j++ ) {
    if ( j < inds_dists.size() )
        neighbors_indices[ i0 * max_count + j ] = inds_dists[ j ].first + sum_sb;
    else
        neighbors_indices[ i0 * max_count + j ] = supports.size();
}

这里就是在填充邻近点索引,max_count就是得到的最大邻近点个数,假如实际搜索到的邻近点个数为 5,那么,在max_count个索引数组内,前5个就是得到的邻近点索引,而后面的都用supports.size填充了。

cpp_subsimling

不贴代码了,也比较简单,就是以一个 距离 sampleDl ,对整个点云数据划分为一个一个的立体方格,对每个方格内的所有点求平均值,最后得到输出点。

这里所有的解析都是不包括 特征和类别的,因为我没用到,我只是拿已经训练好的模型部署,实际上部署时,没有使用到这里的特征和类别。

这里给出我已经编译好的 Python3.8版本的,编译应该不难的:
https://download.csdn.net/download/m0_55630410/89630013

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值