个人记录:vs2017 opencv liblas库

一、环境:

(161条消息) vs2017配置opencv详细步骤(附详细图解)_vs2017对应的opencv版本_想成为大佬啊的博客-CSDN博客

vs2017配置liblas库+测试代码 - CodeAntenna

 第一个没问题

第二个出错

找不到 liblas.dll

添加了dll所在文件夹为环境变量,解决了。

二、代码:

 (161条消息) 点云投影至xoy平面生成强度图像_点云生成强度图像_zzu_圈圈的博客-CSDN博客

// opencv
#include <opencv2/opencv.hpp>   
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
// pcl
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
//lablas
#include <liblas/liblas.hpp>

using namespace std;
using namespace cv;

typedef  pcl::PointCloud<pcl::PointXYZI>::Ptr      pcXYZIPtr;
typedef  pcl::PointCloud<pcl::PointXYZI>           pcXYZI;

/*!
* @brief 读取las格式点云数据函数
* param[in] file_name:las文件
* param[in] point_cloud:点云指针
*/
bool readLasFile(const string &file_name, const pcXYZIPtr &point_cloud)
{
	std::ifstream ifs;
	ifs.open(file_name, std::ios::in | std::ios::binary);
	if (ifs.bad())
	{
		cout << "Failed to load las File" << endl;
	}
	liblas::ReaderFactory f;
	liblas::Reader reader = f.CreateWithStream(ifs);
	int number_points = reader.GetHeader().GetPointRecordsCount();//获取las数据点的个数
	point_cloud->width = number_points;
	point_cloud->height = 1;
	point_cloud->is_dense = false;
	point_cloud->resize(point_cloud->width * point_cloud->height);

	liblas::Header const &header = reader.GetHeader();
	int i = 0;
	while (reader.ReadNextPoint())
	{
		point_cloud->points[i].x = reader.GetPoint().GetX();
		point_cloud->points[i].y = reader.GetPoint().GetY();
		point_cloud->points[i].z = reader.GetPoint().GetZ();
		point_cloud->points[i].intensity = reader.GetPoint().GetIntensity();

		i++;
	}
	// 检查 强度信息是否存在
	if (point_cloud->points[0].intensity == 0) //check if the intensity exsit
	{
		cout << "Warning! Point cloud intensity may not be imported properly, check the scalar field's name.\n" << endl;
	}
	return 1;
}

/*!
* @brief 点云转强度图像函数
* param[in] cloud:点云指针
* param[in] resolution:点云转图像分辨率
* param[out] img: 点云生成的强度图像
*/
cv::Mat pointCloud2imgI(const pcXYZIPtr &cloud, double resolution)
{
	float minx, miny, maxx, maxy, mini, maxi;
	minx = miny = mini = FLT_MAX;
	maxx = maxy = maxi = -FLT_MAX;

	// 获取点云的最大最小 x、y点的坐标
	for (int i = 0; i < cloud->points.size(); i++)
	{
		minx = min(minx, cloud->points[i].x);
		miny = min(miny, cloud->points[i].y);
		maxx = max(maxx, cloud->points[i].x);
		maxy = max(maxy, cloud->points[i].y);
		maxi = max(maxi, cloud->points[i].intensity);
	}

	double lx = maxx - minx;					//点云长度
	double ly = maxy - miny;					//点云宽度
	int rows = round(ly / resolution);			//图像高度
	int clos = round(lx / resolution);			//图像宽度

	cv::Mat img = cv::Mat::zeros(rows, clos, CV_8UC3);

	//强度格网矩阵
	vector<vector<float>> vec_grid_intensity;

	//格网分配空间 及初始化
	vec_grid_intensity.resize(rows);
	//初始化格网
	for (int i = 0; i < rows; i++)
	{
		vec_grid_intensity[i].resize(clos);
	}

	//依次将点压入所在格网
	for (int i = 0; i < cloud->points.size(); i++)
	{
		int m = (maxy - cloud->points[i].y) / resolution;
		int n = (cloud->points[i].x - minx) / resolution;

		if (m > 0 && m < rows && n > 0 && n < clos)
		{
			// 将格网中的点云的最大强度值作为格网的强度值
			vec_grid_intensity[m][n] = max(cloud->points[i].intensity, vec_grid_intensity[m][n]);
		}
	}

	//强度拉伸到0-255之间赋值
	for (int i = 0; i < rows; i++)
	{
		uchar * data = img.ptr<uchar>(i);
		for (int j = 0; j < clos; j++)
		{
			if (vec_grid_intensity[i][j] > 0)
			{
				int pixel = (int)(vec_grid_intensity[i][j] / maxi * 255);
				//各通道像素赋值
				data[3 * j] = pixel;
				data[3 * j + 1] = pixel;
				data[3 * j + 2] = pixel;
			}
		}
	}
	return img;
}

int main()
{
	const string las_path = "D:/toWuda/lidar/lidarnew/CGdomYRJ-114(CK0-17)_D_21.las";
	const double resolution = 0.05;

	pcXYZIPtr cloud(new pcXYZI);

	readLasFile(las_path, cloud);
	Mat cloud_imgI = pointCloud2imgI(cloud, resolution);

	imwrite("cloud_img.jpg", cloud_imgI);
}

三、代码学习:

typedef  pcl::PointCloud<pcl::PointXYZI>::Ptr      pcXYZIPtr;
typedef  pcl::PointCloud<pcl::PointXYZI>           pcXYZI;
typedef type newname; 
typedef int P(); // 简单的

class X {
public:
    P(eat_shit); // 等价于声明`int eat_shit();
}

加了ptr的是指针类型

(162条消息) [PCL教程]基础数据结构 PointCloud &PointT_pcl::pointcloud_Deephome的博客-CSDN博客

数据类型是PointXYZI,I为intensity,强度

pcXYZIPtr cloud(new pcXYZI);

 PCL之指针Ptr详解 - 知乎 (zhihu.com)

bool readLasFile(const string &file_name, const pcXYZIPtr &point_cloud)
const string las_path = "D:/toWuda/lidar/lidarnew/CGdomYRJ-114(CK0-17)_D_21.las";
readLasFile(las_path, cloud);
liblas::ReaderFactory f;
//使用ReaderFactory从stream中构造Reader而不是直接调用Reader构造函数
//因为las可能是压缩的
liblas::Reader reader = f.CreateWithStream(ifs);
cv::Mat pointCloud2imgI(const pcXYZIPtr &cloud, double resolution)
Mat cloud_imgI = pointCloud2imgI(cloud, resolution);
FLT_MAX //最大的正浮点数
cv::Mat img = cv::Mat::zeros(rows, clos, CV_8UC3);
//深度8位 unsigned int–无符号整形 3通道

// opencv
#include <opencv2/opencv.hpp>   
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
// pcl
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
//lablas
#include <liblas/liblas.hpp>

using namespace std;
using namespace cv;

typedef  pcl::PointCloud<pcl::PointXYZI>::Ptr      pcXYZIPtr;
typedef  pcl::PointCloud<pcl::PointXYZI>           pcXYZI;

/*!
* @brief 读取las格式点云数据函数
* param[in] file_name:las文件
* param[in] point_cloud:点云指针
*/
bool readLasFile(const string &file_name, const pcXYZIPtr &point_cloud)
{
	std::ifstream ifs;
	ifs.open(file_name, std::ios::in | std::ios::binary);
	if (ifs.bad())
	{
		cout << "Failed to load las File" << endl;
	}
	liblas::ReaderFactory f;
	liblas::Reader reader = f.CreateWithStream(ifs);
	int number_points = reader.GetHeader().GetPointRecordsCount();//获取las数据点的个数
	point_cloud->width = number_points;
	point_cloud->height = 1;
	point_cloud->is_dense = false;
	point_cloud->resize(point_cloud->width * point_cloud->height);

	liblas::Header const &header = reader.GetHeader();
	int i = 0;
	while (reader.ReadNextPoint())
	{
		point_cloud->points[i].x = reader.GetPoint().GetX();
		point_cloud->points[i].y = reader.GetPoint().GetY();
		point_cloud->points[i].z = reader.GetPoint().GetZ();
		point_cloud->points[i].intensity = reader.GetPoint().GetIntensity();

		i++;
	}
	// 检查 强度信息是否存在
	if (point_cloud->points[0].intensity == 0) //check if the intensity exsit
	{
		cout << "Warning! Point cloud intensity may not be imported properly, check the scalar field's name.\n" << endl;
	}
	return 1;
}

/*!
* @brief 点云转强度图像函数
* param[in] cloud:点云指针
* param[in] resolution:点云转图像分辨率
* param[out] img: 点云生成的强度图像
*/
cv::Mat pointCloud2imgI(const pcXYZIPtr &cloud, double resolution)
{
	float minx, miny, maxx, maxy, mini, maxi;
	minx = miny = mini = FLT_MAX;
	maxx = maxy = maxi = -FLT_MAX;

	// 获取点云的最大最小 x、y点的坐标
	for (int i = 0; i < cloud->points.size(); i++)
	{
		minx = min(minx, cloud->points[i].x);
		miny = min(miny, cloud->points[i].y);
		maxx = max(maxx, cloud->points[i].x);
		maxy = max(maxy, cloud->points[i].y);
		maxi = max(maxi, cloud->points[i].intensity);
	}

	double lx = maxx - minx;					//点云长度
	double ly = maxy - miny;					//点云宽度
	int rows = round(ly / resolution);			//图像高度
	int clos = round(lx / resolution);			//图像宽度

	cv::Mat img = cv::Mat::zeros(rows, clos, CV_8UC3);

	//强度格网矩阵
	vector<vector<float>> vec_grid_intensity;

	//格网分配空间 及初始化
	vec_grid_intensity.resize(rows);
	//初始化格网
	for (int i = 0; i < rows; i++)
	{
		vec_grid_intensity[i].resize(clos);
	}

	//依次将点压入所在格网
	for (int i = 0; i < cloud->points.size(); i++)
	{
		int m = (maxy - cloud->points[i].y) / resolution;
		int n = (cloud->points[i].x - minx) / resolution;

		if (m > 0 && m < rows && n > 0 && n < clos)
		{
			// 将格网中的点云的最大强度值作为格网的强度值
			vec_grid_intensity[m][n] = max(cloud->points[i].intensity, vec_grid_intensity[m][n]);
		}
	}

	//强度拉伸到0-255之间赋值
	for (int i = 0; i < rows; i++)
	{
		uchar * data = img.ptr<uchar>(i);
		for (int j = 0; j < clos; j++)
		{
			if (vec_grid_intensity[i][j] > 0)
			{
				int pixel = (int)(vec_grid_intensity[i][j] / maxi * 255);
				//各通道像素赋值
				data[3 * j] = pixel;
				data[3 * j + 1] = pixel;
				data[3 * j + 2] = pixel;
			}
		}
	}
	return img;
}

int main()
{
	const string las_path = "D:/toWuda/lidar/lidarnew/CGdomYRJ-114(CK0-17)_D_21.las";
	const double resolution = 0.1;

	pcXYZIPtr cloud(new pcXYZI);

	readLasFile(las_path, cloud);
	Mat cloud_imgI = pointCloud2imgI(cloud, resolution);

	imwrite("cloud_img.jpg", cloud_imgI);
}

结果

软件处理结果对比

猜你喜欢

转载自blog.csdn.net/weixin_61235989/article/details/130288700