.dat文件三维点云可视化

来源:互联网 发布:java singleton模式 编辑:程序博客网 时间:2024/05/18 02:45

我们做点云重建,很多情况下激光扫描仪回传的点云数据是保存为.txt或者.dat的,而并非PCL所支持的PCD格式,这个时候就需要我们自行写代码进行读取

.dat文件读取

我们的点云数据文件如下所示,为二进制.dat文件,其中每一行是二维扫描仪线扫的数据,这么多行是因为云台转动得到的三维扫描数据。其中每一行的前52个字节是一些校验码等无效数据,我们需要自己写代码进行读取。
这里写图片描述
C++读取.dat文件没什么难度,重点是有个技巧需要知道,就是这个数据每4个字节是一个int型数据代表了点距离扫描仪的距离,因此我读取的时候必须每次读取4字节的16进制数存入一个int型变量。采用的方法如下:

int dst_temp;for (int m = 0; m < 4; m++){    char *p = (char *)&dst_temp;    dataFile.read(p + 3 - m, sizeof(char));}

思路就是,对一个int变量进行取址,将其地址强制转成char*,那么,这个指针char* p指向的就是int的首地址,我们每次读取一位,读四次刚好存满这个int。由于int存储的时候是先低位后高位,因此我们需要将先读的放到后面,后读的放到前面。上程序就是完成这个读取。
完整代码如下:

#include <pcl/visualization/cloud_viewer.h>#include <iostream>#include <pcl/io/io.h>#include <pcl/io/pcd_io.h>#include <fstream>#include <queue>#include <sstream>#include <stack>#include <string>#include <math.h>using namespace std;int user_data;int main(){    ifstream dataFile;    pcl::PointCloud<pcl::PointXYZ>::Ptr pointcloud(new pcl::PointCloud<pcl::PointXYZ>);    pcl::PointXYZ point_temp;       //上一点    pcl::PointXYZ point_3D;         //当前点    int dstOri, plsOri;             //原始距离值和反射率    double pls, dst;                //处理后距离值和反射率    dataFile.open("201715172734.dat",ios::binary); //以二进制形式打开文件    if (dataFile)    {        for (int i = 0; i < 600; i++)        //600行数据        {             dataFile.seekg(52 + i * 8056);   //不读无效数据            for (int j = 0; j < 1000; j++)   //每行1000个点            {                int dst_temp = 0;            //距离                int pls_temp=0;              //反射率                float theta, alpha;          //坐标变换的角度                for (int m = 0; m < 4; m++)       //读取距离                {                    char *p = (char *)&dst_temp;                    dataFile.read(p + 3 - m, sizeof(char));                }                for (int m = 0; m < 4; m++)       //读取反射率                {                    char *p = (char *)&pls_temp;                    dataFile.read(p + 3 - m, sizeof(char));                }                dstOri = dst_temp;                plsOri = pls_temp;                if (dstOri == -2147483648 || dstOri == 2147483647)                    point_3D = point_temp;                else                {                    dst = dstOri / 10000.0;      //进行坐标变换                    theta = (500 * M_PI - j*M_PI) / 1998;                    alpha = -0.3 + i*0.001;                    point_3D.x = dst*sin(theta);                    point_3D.y = dst*cos(theta)*sin(alpha);                    point_3D.z = -dst*cos(theta)*cos(alpha);                }                point_temp = point_3D;                pointcloud->push_back(point_3D);//将点存入pointcloud            }        }        cout << pointcloud->size() << endl;        pcl::visualization::CloudViewer viewer("Cloud Viewer");//点云可视化        //blocks until the cloud is actually rendered        viewer.showCloud(pointcloud);        while (!viewer.wasStopped())        {            //you can also do cool processing here            //FIXME: Note that this is running in a separate thread from viewerPsycho            //and you should guard against race conditions yourself...            user_data++;        }    }    else    {        cout << "No datafile";    }    dataFile.close();    return 0;}

效果如下:这里写图片描述
重建效果:
这里写图片描述

0 0
原创粉丝点击