通过这个案例,将会学习到:
- 如何使用PCL创建多个不同的视口展现点云
- 如何生成梯形圆柱体形状的点云
- 如何将三维点云投影到不同的平面上
- 如何将三维点云进行旋转
PCL绘制圆柱体形状的点云
- PCL中绘制指定高度的梯形圆柱体形状的点云,参考代码如下:
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/common/common_headers.h>
#include <boost/thread/thread.hpp>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/common/transforms.h>
#include <vector>
typedef pcl::PointXYZRGB PointType;
using namespace std;
struct TrapezoidalCylinder {
private:
float m_bottom_radius; // 底部半径
float m_top_radius; // 顶部半径
float m_height; // 高度
int m_r, m_g, m_b; // 颜色
public:
TrapezoidalCylinder(float bottom_radius, float top_radius, float height, int r, int g, int b) :
m_bottom_radius(bottom_radius), m_top_radius(top_radius), m_height(height), m_r(r), m_g(g), m_b(b) {
//cout << m_bottom_radius << m_top_radius << m_height << m_r << m_g << m_b << endl;
}
float get_bottom_radius()const { return m_bottom_radius; }
float get_top_radius()const { return m_top_radius; }
float get_height()const { return m_height; }
int get_r()const { return m_r; }
int get_g()const { return m_g; }
int get_b()const { return m_b; }
};
//构造梯形圆柱体点云
void create_cylinder_pointcloud(pcl::PointCloud<PointType>::Ptr& basic_cloud_ptr, const std::vector< TrapezoidalCylinder>& vec)
{
int size = vec.size();
for (int i = 0; i < size; ++i) {
float height = vec[i].get_height();
float slope = (vec[i].get_top_radius() - vec[i].get_bottom_radius()) / height; // 斜率,控制半径的变化
for (float z = 0; z <= height; z += 0.1)
{
// core
float current_radius = vec[i].get_bottom_radius() + slope * z;
for (float angle = 0.0; angle <= 360.0; angle += 5.0)
{
PointType basic_point;
basic_point.x = current_radius * cosf(pcl::deg2rad(angle)); // r *cos(angle)
basic_point.y = current_radius * sinf(pcl::deg2rad(angle)); // r *sin(angle)
basic_point.z = z;
uint32_t rgb = (static_cast<uint32_t>(vec[i].get_r()) << 16 |
static_cast<uint32_t>(vec[i].get_g()) << 8 | static_cast<uint32_t>(vec[i].get_b()));
basic_point.rgb = *reinterpret_cast<float*>(&rgb);
basic_cloud_ptr->points.push_back(basic_point);
}
basic_cloud_ptr->width = (int)basic_cloud_ptr->points.size();
basic_cloud_ptr->height = 1;
}
}
}
int main(int argc, const char** argv) {
pcl::PointCloud<PointType>::Ptr cloud(new pcl::PointCloud<PointType>);
struct TrapezoidalCylinder cylinder_layer1 = { 1.6275, 1.805, 4.05, 63, 253, 63 };
std::vector<TrapezoidalCylinder> vec;
vec.push_back(cylinder_layer1);
create_cylinder_pointcloud(cloud, vec);
// 投影到xoy平面
pcl::PointCloud<PointType>::Ptr cloud_down_projected(new pcl::PointCloud<PointType>);
*cloud_down_projected = *cloud;
int number_point = cloud_down_projected->points.size();
for (int i = 0; i < number_point; ++i) {
cloud_down_projected->points[i].z = 0;
}
// 绕x轴旋转90度
// 定义一个4*4的单位阵
Eigen::Matrix4f transform_matrix = Eigen::Matrix4f::Identity();
// 旋转PI/2
float theta = M_PI / 2;
transform_matrix(1, 1) = cos(theta);
transform_matrix(1, 2) = sin(theta);
transform_matrix(2, 1) = -sin(theta);
transform_matrix(2, 2) = cos(theta);
pcl::PointCloud<PointType>::Ptr transformed_cloud(new pcl::PointCloud<PointType>());
pcl::transformPointCloud(*cloud, *transformed_cloud, transform_matrix);
// 投影到xoy平面
pcl::PointCloud<PointType>::Ptr cloud_sideway_projected(new pcl::PointCloud<PointType>);
*cloud_sideway_projected = *transformed_cloud;
number_point = cloud_sideway_projected->points.size();
for (int i = 0; i < number_point; ++i) {
cloud_sideway_projected->points[i].z = 0;
}
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));
int v1(0), v2(1), v3(2), v4(3);
viewer->createViewPort(0.0, 0.5, 0.5, 1.0, v1); // (xmin, ymin, xmax, ymax)
viewer->createViewPort(0.5, 0.5, 1.0, 1.0, v2);
viewer->createViewPort(0.0, 0.0, 0.5, 0.5, v3);
viewer->createViewPort(0.5, 0.0, 1.0, 0.5, v4);
viewer->addCoordinateSystem();
viewer->addPointCloud<PointType>(cloud, "source point cloud", v1);
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 10, "source point cloud"); // 设置点云大小
viewer->addPointCloud<PointType>(transformed_cloud, "transform cloud", v2);
viewer->addPointCloud<PointType>(cloud_down_projected, "down xoy cloud", v3);
viewer->addPointCloud<PointType>(cloud_sideway_projected, "sideway xoy cloud", v4);
while (!viewer->wasStopped())
{
viewer->spinOnce(100);
boost::this_thread::sleep(boost::posix_time::microseconds(100000));
}
return 0;
}
结果
- 运行结果如下:
![]()

浙公网安备 33010602011771号