前言
点云文件具有三维空间的坐标,可以投影至任何需要的平面。得到二维图像。这里以投影到xoy平面为例。其进行投影的步骤如下:
(1)确定所要投影的平面,将点云投影至该平面,得到二维点坐标;
(2)求得二维点云所在平面的极值,即x_max,x_min,y_max,y_min,;
(3)根据x_max - x_min,y_max - y_min和x方向的采样精度,y方向的采样精度,确定二维图像的坐标范围;
(4)遍历点云,将点的坐标与极小值点的坐标做差之后乘以采样精度,即为该点在图像中的像素坐标;
(5)将点的RGB信息或者填充到对应的像素内。
示例程序
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include "opencv2/opencv.hpp"
#include <pcl/common/common.h>
int main()
{
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointXYZ p_max, p_min;
pcl::io::loadPCDFile("lucy.pcd", *cloud);
//这里向xoy平面投影
pcl::getMinMax3D(*cloud, p_min, p_max);
float xScale = 2, yScale = 2;
auto rows = static_cast<int>(round(yScale*(p_max.y - p_min.y)));
auto cols = static_cast<int>(round(xScale*(p_max.x - p_min.x)));
if (rows < 1 || cols < 1)
{
return -1;
}
cv::Mat img = cv::Mat::zeros(rows, cols, CV_8UC1);
for ( auto& p : cloud->points)
{
int r = static_cast<int>(round(yScale*(p.y - p_min.y)));
if (r < 0 || r >=img.rows)
continue;
int c = static_cast<int>(round(xScale*(p.x -p_min.x)));
if (c < 0 || c >=img.cols)
continue;
img.at<uchar>(r, c) = 255;
}
cv::imwrite("result.png",img);
return 0;
}