.dat文件三維點雲可視化

我們做點雲重建,很多情況下激光掃描儀回傳的點雲數據是保存爲.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;
}

效果如下:這裏寫圖片描述
重建效果:
這裏寫圖片描述

發佈了47 篇原創文章 · 獲贊 32 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章