.las数据转.pcd格式是参考这里点击打开链接,很容易能够得到正确的.pcd格式文件;
但是,当用PCL库读取并显示的时候,却看不到图形,我是用的PCL的第一种显示方法CloudViewer显示的,也是用的官网示例代码
#include <pcl/visualization/cloud_viewer.h>
#include <iostream>
#include <pcl/io/io.h>
#include <pcl/io/pcd_io.h>
int user_data;
void
viewerOneOff (pcl::visualization::PCLVisualizer& viewer)
{
viewer.setBackgroundColor (1.0, 0.5, 1.0);
pcl::PointXYZ o;
o.x = 1.0;
o.y = 0;
o.z = 0;
viewer.addSphere (o, 0.25, "sphere", 0);
std::cout << "i only run once" << std::endl;
}
void
viewerPsycho (pcl::visualization::PCLVisualizer& viewer)
{
static unsigned count = 0;
std::stringstream ss;
ss << "Once per viewer loop: " << count++;
viewer.removeShape ("text", 0);
viewer.addText (ss.str(), 200, 300, "text", 0);
//FIXME: possible race condition here:
user_data++;
}
int
main ()
{
pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZRGBA>);
pcl::io::loadPCDFile ("my_point_cloud.pcd", *cloud);
pcl::visualization::CloudViewer viewer("Cloud Viewer");
//blocks until the cloud is actually rendered
viewer.showCloud(cloud);
//use the following functions to get access to the underlying more advanced/powerful
//PCLVisualizer
//This will only get called once
viewer.runOnVisualizationThreadOnce (viewerOneOff);
//This will get called once per visualization iteration
viewer.runOnVisualizationThread (viewerPsycho);
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++;
}
return 0;
}
于是查找原因,准备换一种显示方法,就是比较复杂的PCLVisualizer,但是代码有点多,也是第一次学习使用PCL,就没有立刻写代码,而是分析了一下源代码中的示例数据,bunny.pcd;这只兔子的数据都是小于1的,猜测应该是归一化之后得到的坐标,所以,网上找相关内容,但没有得到肯定的答案,因为也担心归一化的效率问题,想看看有没有更好的办法啊,最终,没有找到更好的办法来保留原始坐标系统,通过修改.las转.pcd格式的代码,也就是增加了一个归一化步骤,之后得到数据,居然能够正常显示了,也算是有点收获;
// LASlib_3DlasTo2D.cpp: 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "lasreader.hpp"
#include "laswriter.hpp"
#include <pcl/visualization/cloud_viewer.h>
#include <iostream>
#include <pcl/io/io.h>
#include <pcl/io/pcd_io.h>
#include <GL/glut.h>
#include "stdafx.h"
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <string>
#include <vector>
#include <fstream>
#include <ios>
#include <iostream>
//#include <glut.h>
#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL);
VTK_MODULE_INIT(vtkInteractionStyle);
/*
将'/'格式的文件路径转换成 '\\';
*/
static std::string convertFilePath(const std::string& file)
{
int i = 0;
std::string s(file);
for (i = 0; i < s.size(); ++i)
{
if (s[i] == '/')
s[i] = '\\';
}
return s;
}
int main()
{
/*
LASreadOpener lasreadopener;
lasreadopener.set_file_name("1.las");
LASreader* lasreader = lasreadopener.open();
LASwriteOpener laswriteopener;
laswriteopener.set_file_name("2.laz");
LASwriter* laswriter = laswriteopener.open(&lasreader->header);
while (lasreader->read_point())
laswriter->write_point(&lasreader->point);
laswriter->close();
delete laswriter;
lasreader->close();
delete lasreader;
*/
const char* your_las_file_path = "D:\\任务:点云和影像配准\\data\\LIDAR\\4test_60km.las";
const char* your_pcd_out_file_path = "XX.pcd";
//laslib只允许'\\'格式的文件路径。
std::string lasFile = convertFilePath(your_las_file_path);
//打开las文件
LASreadOpener lasreadopener;
lasreadopener.set_file_name(lasFile.c_str());
LASreader* lasreader = lasreadopener.open();
size_t count = lasreader->header.number_of_point_records;
pcl::PointCloud<pcl::PointXYZ>::Ptr pointCloudPtr(new pcl::PointCloud<pcl::PointXYZ>);
pointCloudPtr->resize(count);
pointCloudPtr->width = 1;
pointCloudPtr->height = count;
pointCloudPtr->is_dense = false;
size_t i = 0;
int maxX = -9999, minX = 9999999999, MaxY = -999999999, minY = 9999999999, maxZ = -999999999, minZ=999999999;
/*int x, y, z;*/
maxX = lasreader->get_max_x();
minX = lasreader->get_min_x();
MaxY = lasreader->get_max_y();
minY = lasreader->get_min_y();
maxZ = lasreader->get_max_z();
minZ = lasreader->get_min_z();
double dx = maxX - minX;
double dy = MaxY - minY;
double dz = maxZ - minZ;
double maxd = dx > dy ? (dx > dz ? dx : dz) : (dy > dz ? dy : dz);
/*double maxd,mind,Dd;
dx > dy ? (dx > dz ? (maxd = maxX, mind = minX, Dd = dx) : (maxd = maxZ, mind = minZ, Dd = dz)) : (dy > dz ? (maxd = MaxY, mind = minY, Dd = dy) : (maxd = maxZ, mind = minZ, Dd = dz));
*/
printf( "%f",maxd);
size_t j = 0;
while (lasreader->read_point() && j < count)
{
pointCloudPtr->points[j].x = (lasreader->point.get_x() - minX)/maxd;
pointCloudPtr->points[j].y = (lasreader->point.get_y() - minY)/maxd;
pointCloudPtr->points[j].z = (lasreader->point.get_z() - minZ)/maxd;
/*pointCloudPtr->points[j].x = (lasreader->point.get_x()) / 1;
pointCloudPtr->points[j].y = (lasreader->point.get_y()) / 1;
pointCloudPtr->points[j].z = (lasreader->point.get_z()) / 1;*/
++j;
}
pcl::io::savePCDFileASCII(your_pcd_out_file_path, *pointCloudPtr);
getchar();
return 0;
}
这是CloudViewer显示结果,没有添加渲染效果;
这是原始.las数据,ENVILiDar软件显示: