首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >.las文件的读取、处理和显示

.las文件的读取、处理和显示
EN

Stack Overflow用户
提问于 2021-02-04 04:19:43
回答 1查看 307关注 0票数 0

我使用libLAS库来读取.las file的云点。然后,我将点存储在PCL点云变量中,以便使用点云库处理和显示点云。

这是我使用的代码:

代码语言:javascript
运行
复制
class PointCloud
{
    public:
        //PointCloud(const std::string& path);

        uint32_t getVertsCount();
        float4* getVertsData();

        template<typename PointT>
        typename pcl::PointCloud<PointT>::Ptr read(const std::string& path);//void read(const std::string &path);
}

template<typename PointT>
typename pcl::PointCloud<PointT>::Ptr PointCloud::read(const string& path)
{
    typename pcl::PointCloud<PointT>::Ptr lasCloud(new pcl::PointCloud<PointT>);

    std::ifstream ifs;
    ifs.open(path, std::ios::in | std::ios::binary);
    //std::ifstream inf(path, std::ios::in | std::ios::binary);

    liblas::ReaderFactory f;
    liblas::Reader reader = f.CreateWithStream(ifs);
    liblas::Header const& header = reader.GetHeader();

    std::cout << "Compressed: " << (header.Compressed() == true) ? "true" : "false";
    std::cout << "Signature: " << header.GetFileSignature() << '\n';
    std::cout << "Points count: " << header.GetPointRecordsCount() << '\n';

    while (reader.ReadNextPoint())
    {
        liblas::Point const& p = reader.GetPoint();

        PointT cloudPoint;
        cloudPoint.x = float(p.GetX()) * 0.001 + 590284.000; // (double)(x * scaleX) + offsetX;
        cloudPoint.y = float(p.GetY()) * 0.001 + 4339456.000; // (double)(y * scaleY) + offsetY;
        cloudPoint.z = float(p.GetZ()) * 0.001 + 157.000; // (double)(z * scaleZ) + offsetZ;
        std::cout << p.GetX() << ", " << p.GetY() << ", " << p.GetZ() << "\n";
        //cloudPoint.intensity = p.GetIntensity(); // (double)(intensity) / 65536.0;
        lasCloud->points.push_back(cloudPoint);
    }

    if (!ifs.good())
        throw runtime_error("Reading went wrong!");
        
    
    lasCloud->width = lasCloud->points.size();
    lasCloud->height = 1;
    lasCloud->is_dense = true;
    std::cout << "Cloud size = " << lasCloud->points.size() << endl;
    return lasCloud;
    

}

int main (int argc, char** argv)
{
    
    std::cout << "starting enviroment" << std::endl;
    pcl::visualization::PCLVisualizer::Ptr viewer (new pcl::visualization::PCLVisualizer ("3D Viewer"));
    CameraAngle setAngle = FPS; //XY, FPS, Side, TopDown
    initCamera(setAngle, viewer);
    pcl::PointCloud<pcl::PointXYZ>::Ptr inputCloudI; //
    inputCloudI = pcd.read<pcl::PointXYZ>("C:/Users/hedey/OneDrive/Documents/Research_papers/STDF/10_4231_MFQF-Q141/I-65/LiDAR/RoadSurface/NB/20180524_I65_NB_RoadSurface_1_50.5.las");
    std::cout << "Cloud size = " << inputCloudI->points.size() << endl;
    renderPointCloud(viewer, inputCloudI, "lasCloud");
    while (!viewer->wasStopped())
    {
        viewer->spinOnce();
    }
}

但是,使用PCL查看器显示的云看起来像一个点。我注意到的是,当我打印出使用libLAS读取的坐标时,x&y坐标没有十进制值,这与las文件中存储的实际坐标相比是不准确的。我在命令提示符下使用las2txt获得了实际的点坐标。包含实际坐标的This is the txt file。下面是显示cout结果的图像:

此外,这也是我使用CloudCompare打开点云时的外观。我期待着在将其读取到PCL点云变量中并使用PCL查看器显示结果时显示相同的结果,因为我需要做进一步的处理才能进行传感器融合(相机和激光雷达)。

EN

回答 1

Stack Overflow用户

发布于 2021-02-04 05:46:59

std::cout的默认精度为6位十进制数字。请添加如下内容

代码语言:javascript
运行
复制
    std::cout.precision(12);

while循环之前。

此外,将p.GetX()等转换为float是没有意义的:如果将其与0.001相乘,运算符*的参数左侧自然会被提升为至少double。然而,float只有大约7位的精度,所以对于存储在双精度中的9位整数(是的!)这样的截断是灾难性的。

还有另一个(小)错误,正确的行为

代码语言:javascript
运行
复制
    std::cout << "Compressed: " << ((header.Compressed() == true) ? "true\n" : "false\n");

请注意条件表达式(和\n)周围的()大括号。请使用标准的编译器选项,这些选项将对这些简单的问题发出警告。

请同时阅读https://stackoverflow.com/help/minimal-reproducible-example

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66035067

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档