一、原理
孤立庞杂的点转成栅格图像,其实就是矢量数据转栅格数据,算法在教材里写的清清楚楚。
二、实现
这里只是简单的实现,是根据我个人的需求写的代码。原理是参照上述文档的,不管转出的栅格属性值有啥要求变化,转化的过程应该是万变不离其宗的
#include <iostream>
#include <pcl/io/io.h>
#include <pcl/io/pcd_io.h>
#include<pcl/point_types.h>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
using namespace std;
using namespace pcl;
void point2picture(string name)
{
string s = "D:/AAAA/BBBB/CCCC/DDDD/" + name + ".pcd";
pcl::PointCloud<pcl::PointXYZI>::Ptr inputcloud(new pcl::PointCloud<pcl::PointXYZI>);
if (pcl::io::loadPCDFile<pcl::PointXYZI>(s, *inputcloud) == -1)
{
PCL_ERROR("加载pcd文件失败");
}
double m = 1000;//二值化阈值
double cellsize = 0.05;//栅格单元边长
pcl::PointXYZI min, max;
pcl::getMinMax3D(*inputcloud, min, max);//获取该片点云中的最大、最小的xyz值
int Prow,Pcol;//点云转图像的总行列数
Prow = ceil((max.y - min.y) / cellsize);//行数
Pcol = ceil((max.x - min.x) / cellsize);//向上取整,列数
cv::Mat image(Prow ,Pcol , CV_8UC1, cv::Scalar(0));//创建一个由点云块大小确定行列的灰度图像,每个像元初始属性值为0
int temprow, tempcol;
for (int i = 0; i < inputcloud->points.size(); i++)
{
temprow = floor((max.y - inputcloud->points[i].y) / cellsize);
tempcol = floor((inputcloud->points[i].x - min.x) / cellsize);
if (inputcloud->points[i].intensity>m)//如果大于二值化阈值
{
image.at<uchar>(temprow, tempcol) = 255;//将预设属性值从0改为255
}
}
string out = "D:/AAAA/BBBB/CCCC/EEEE/" + name + ".tif";
imwrite(out, image);
}
输入点云数据:
依据反射强度转成二值图像: