读取点云数据并将其投影在模型上,如平面、球。设置coefficients参数即可,其代码如下:
#include <iostream>
#include<pcl/io/pcd_io.h>
#include <pcl/point_cloud.h>
#include <pcl/correspondence.h>
#include <pcl/features/normal_3d_omp.h>
#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/kdtree/impl/kdtree_flann.hpp>
#include<fstream>
#include<iostream>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/ModelCoefficients.h>
#include <pcl/filters/project_inliers.h>
#include <pcl/filters/extract_indices.h>
#include <pcl/point_types.h>
using namespace std;
double computerCloudResolution(const pcl::PointCloud<pcl::PointXYZ>::ConstPtr cloud) {
double res = 0.0;
int n_points = 0;
int nres;
std::vector<int> indices(2);
std::vector<float> sqr_distances(2);
pcl::search::KdTree<pcl::PointXYZ> tree;
tree.setInputCloud(cloud);
for (size_t i = 0; i < cloud->size(); ++i)
{
if (!std::isfinite((*cloud)[i].x))
{
continue;
}
nres = tree.nearestKSearch(i, 2, indices, sqr_distances);
if (nres == 2)
{
res += sqrt(sqr_distances[1]);
++n_points;
}
}
if (n_points != 0)
{
res /= n_points;
}
return res;
}
int main()
{
ifstream data;
data.open("knee_piece.TXT", ios::in);
int rows = -1;
char buf[200];
while (!data.eof()) {
data.getline(buf, sizeof(buf));
rows++;
}
data.clear();
data.seekg(0, ios::beg);
//pcl::PointCloud<pcl::PointXYZ>cloud;
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
cloud->width = rows;
cloud->height = 1;
cloud->is_dense = false;
cloud->resize(cloud->width*cloud->height);
for (int i = 0; i < rows; i++) {
double num[3];
data >> num[0];
data >> num[1];
data >> num[2];
cloud->points[i].x = num[0];
cloud->points[i].y = num[1];
cloud->points[i].z = num[2];
}
double res = computerCloudResolution(cloud);
cout << "distance=" << res << endl << "rows=" << rows;
std::cerr << "cloud before projection: " << std::endl;
for (size_t i = 0; i < cloud->points.size(); ++i)
{
std::cerr << " " << cloud->points[i].x << " "
<< cloud->points[i].y << " " << cloud->points[i].y << " \n";
}
/*投影*/
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_projected(new pcl::PointCloud<pcl::PointXYZ>);
//create a set of planar coefficients with X=Y=0, Z = 1
pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients());
coefficients->values.resize(4);
coefficients->values[0] = coefficients->values[1] = 0;
coefficients->values[2] = 1.0;
coefficients->values[3] = 0;
//create the filtering object
pcl::ProjectInliers<pcl::PointXYZ> proj;
proj.setModelType(pcl::SACMODEL_PLANE);
proj.setInputCloud(cloud);
proj.setModelCoefficients(coefficients);
proj.filter(*cloud_projected);
std::cerr << "cloud after projection: " << std::endl;
for (size_t i = 0; i < cloud_projected->points.size(); ++i)
{
std::cerr << " " << cloud_projected->points[i].x << " "
<< cloud_projected->points[i].y << " " << cloud_projected->points[i].z << std::endl;;
}
//Display
pcl::visualization::PCLVisualizer Viewer;
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ>C_B_P(cloud, 255, 0, 0); //C_B_P=cloud before projection首字母简写
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ>C_A_P(cloud_projected, 0, 255, 0); //C_A_P=cloud after projection首字母简写 //C_A_P=cloud after projection首字母简写
Viewer.addPointCloud(cloud, C_B_P, "cloud before projection");
Viewer.addPointCloud(cloud_projected, C_A_P, "cloud after projection");
Viewer.spin();
getchar(); //防止窗口闪退
return true;
}
其屏幕上显示的红色点云为原始点云数据,绿色的为投影的点云数据。
参考博文