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).