读取 .las 文件,用 PCL 处理和显示它 [英] Reading .las file, processing and displaying it with PCL

查看:188
本文介绍了读取 .las 文件,用 PCL 处理和显示它的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 libLAS 库读取了

此外,这是我使用 CloudCompare 打开点云时的样子.当我将其读入 PCL 点云变量并使用 PCL 查看器显示结果时,我期待得到相同的显示,因为我需要做进一步的处理以进行传感器融合(相机和激光雷达).

解决方案

std::cout 的默认精度为 6 位十进制数字.请添加类似

 std::cout.precision(12);

while 循环之前.

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

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

 std::cout <<压缩:"<<((header.Compressed() == true) ? "true\n" : "false\n");

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

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

I used libLAS library to read the cloud points of a .las file. Then I stored the points in a PCL point cloud variable in order to process and display the point cloud using the Point Cloud Library.

This is the code that I used:

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();
    }
}

However, the displayed cloud using the PCL viewer looks like one point. What I noticed is that when I printed out the coordinates that I read using libLAS, the x & y coordinates don't have decimal values, which is inaccurate compared to the actual coordinates stored in the las file. I got the actual point coordinates using las2txt from the command prompt. This is the txt file containing the actual coordinates. And here is an image showing the cout results:

Also, this is how the point cloud looks like when I opened it using CloudCompare. I look forward to geting the same displayed when I read it into a PCL Point Cloud variable and display the results using the PCL viewer, because I'll need to do further processing in order to make sensor fusion (Camera and Lidar).

解决方案

The default precision of std::cout is 6 decimal digits. Please add something like

    std::cout.precision(12);

before the while loop.

Also, casting p.GetX() etc. to float is pointless: if you multiply it by 0.001, the left hand side of the argument of operator* will naturally by promoted to at least double. However, float has only about 7 digits of precision, so for 9-digit integers stored inside doubles (yes!) such truncation is catastrophic.

Also there's another (minor) error, the correct line reads

    std::cout << "Compressed: " << ((header.Compressed() == true) ? "true\n" : "false\n");

Please notice the () braces surrounding the conditional expression (and \n). Please use standard compiler options that will warn against such simple issues.

Please read also https://stackoverflow.com/help/minimal-reproducible-example

这篇关于读取 .las 文件,用 PCL 处理和显示它的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆