C++激光雷达点云过滤循环与条件判断性能优化
激光雷达点云过滤脚本性能优化咨询
我目前正在优化一款激光雷达点云过滤脚本,该脚本需处理约1.75亿个lidar点,按照x、y、z三个维度的上下边界范围,筛选出落入指定区间的点。
现有脚本的逻辑为:遍历每个点后,再遍历所有边界条件(存在多个边界区间),通过if语句判断点是否落在当前边界范围内,初始实现代码如下:
namespace filtering{ std::vector<points_by_roof> filter_by_roof (std::vector<pointcloud::xyzfloats>& coordinates, const std::vector<roof_bounds>& bounds){ //create filtered structure - roof_id, vector with all coordinates that will fall in that slice std::vector<points_by_roof> filtered (bounds.size()); for (int i=0; i < bounds.size(); i++){ filtered[i].id = bounds[i].id; } //Filtering points by roof slice for (int i=0; i < coordinates.size(); i++){ for (int j=0; j < bounds.size(); j++){ if (coordinates[i].z > bounds[j].z_range[0] && coordinates[i].z < bounds[j].z_range[1] && coordinates[i].x > bounds[j].x_range[0] && coordinates[i].x < bounds[j].x_range[1] && coordinates[i].y > bounds[j].y_range[0] && coordinates[i].y < bounds[j].y_range[1]){ filtered[j].points.push_back({coordinates[i].x, coordinates[i].y, coordinates[i].z}); break; } } } return filtered; } }
该代码处理1.75亿个点初始耗时约20秒,我将if语句中的z轴边界判断调整到最优先执行后,耗时下降到约17秒。
我了解C++会对if语句做短路求值优化,会将如下形式的代码:
if (a==b && c==d){}
转换为嵌套判断形式:
if (a==b) { if (c==d){} }
但我认为将z轴边界判断前置只是这类优化的一个基础应用,现咨询是否有其他方案可以进一步提升代码运行速度。
我主观感觉for循环是耗时的主要来源,但我接触C++时间不长,该判断可能不准确。
非常感谢任何形式的帮助。
补充说明
很抱歉之前没有提供足够的代码与说明信息,我意识到信息不足会提升问题解答的难度(我是C++新手)。
- 边界匹配规则:不存在任何点同时落入两个边界框的情况
- 项目整体流程:从.las格式文件(激光雷达点云文件)中读取点数据,将点过滤到对应屋顶截面的边界框内,针对每个边界框内的点做最佳平面拟合,计算屋顶厚度。
涉及的自定义数据类型定义
定义在point_cloud.h头文件的pointcloud命名空间下:
struct xyzfloats { float x, y, z; xyzfloats(float x_val, float y_val, float z_val) : x(x_val), y(y_val), z(z_val){} };
定义在filtering.h头文件的filtering命名空间下:
struct points_by_roof { std::string id; std::vector<pointcloud::xyzfloats> points; }; struct roof_bounds { std::string id; int x_range[2], y_range[2], z_range[2]; };
我接触C的时间不长,对C性能优化的经验非常少,如果优化方案涉及不同数据类型、函数的选型,请说明其差异与原理。如果有必要我可以补充更多(或全部)项目代码,但我无法提供测试用的.las点云文件。
内容的提问来源于stack exchange,提问作者Thomas K
相关产品推荐
相关产品推荐

