PCL_5---可视化
标题
- 1、简单点云可视化
- 代码
- 实验结果
- 2、可视化深度图像
- 代码
- 实验结果
- 3、PCL Visualizer 可视化类
- 代码
- 实验结果
- 4、PCLPlotter可视化特征直方图
- 代码
- 实验结果
- 5、PCL结合Qt使用框架
1、简单点云可视化
CloudViewer类
:visualization命名空间中一种简单简单的点云可视化类。
代码
#include <pcl/visualization/cloud_viewer.h>
#include <iostream>
#include <pcl/io/io.h>
#include <pcl/io/pcd_io.h>int user_data;
//可视化对象的一些简单操作 放入的线程只调用一次
void
viewerOneOff (pcl::visualization::PCLVisualizer& viewer)
{viewer.setBackgroundColor (1.0, 0.5, 1.0); //设置背景颜色pcl::PointXYZ o;o.x = 1.0;o.y = 0;o.z = 0;viewer.addSphere (o, 0.25, "sphere", 0); //添加圆球几何对象 (1.0, 0, 0) r=0.25std::cout << "i only run once" << std::endl;}
//可视化对象添加一个字符串 放入的线程每次都调用
void
viewerPsycho (pcl::visualization::PCLVisualizer& viewer)
{static unsigned count = 0;std::stringstream ss;ss << "Once per viewer loop: " << count++;viewer.removeShape ("text", 0);viewer.addText (ss.str(), 200, 300, "text", 0);//FIXME: possible race condition here:user_data++;
}int
main ()
{//加载点云文件到点云对象pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZRGBA>);pcl::io::loadPCDFile ("maize.pcd", *cloud);//创建可视化viewer对象pcl::visualization::CloudViewer viewer("Cloud Viewer"); viewer.showCloud(cloud);//showCloud函数是同步的,在此处等待直到渲染显示为止 viewer.runOnVisualizationThreadOnce (viewerOneOff);//该注册函数在可视化时只调用一次viewer.runOnVisualizationThread (viewerPsycho);//该注册函数在渲染输出时每次都调用while (!viewer.wasStopped ()){//在此处可以添加其他处理user_data++;}return 0;
}
实验结果
2、可视化深度图像
代码
#include <iostream>#include <pcl/common/common_headers.h>
#include <pcl/range_image/range_image.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/range_image_visualizer.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/console/parse.h>typedef pcl::PointXYZ PointType;// --------------------
// -----Parameters-----
// --------------------
float angular_resolution_x = 0.5f,angular_resolution_y = angular_resolution_x;
pcl::RangeImage::CoordinateFrame coordinate_frame = pcl::RangeImage::CAMERA_FRAME;
bool live_update = false;// --------------
// -----Help-----
// --------------
void
printUsage (const char* progName)
{std::cout << "\n\nUsage: "<<progName<<" [options] <scene.pcd>\n\n"<< "Options:\n"<< "-------------------------------------------\n"<< "-rx <float> angular resolution in degrees (default "<<angular_resolution_x<<")\n"<< "-ry <float> angular resolution in degrees (default "<<angular_resolution_y<<")\n"<< "-c <int> coordinate frame (default "<< (int)coordinate_frame<<")\n"<< "-l live update - update the range image according to the selected view in the 3D viewer.\n"<< "-h this help\n"<< "\n\n";
}void
setViewerPose (pcl::visualization::PCLVisualizer& viewer, const Eigen::Affine3f& viewer_pose)
{Eigen::Vector3f pos_vector = viewer_pose * Eigen::Vector3f(0, 0, 0);Eigen::Vector3f look_at_vector = viewer_pose.rotation () * Eigen::Vector3f(0, 0, 1) + pos_vector;Eigen::Vector3f up_vector = viewer_pose.rotation () * Eigen::Vector3f(0, -1, 0);viewer.setCameraPosition (pos_vector[0], pos_vector[1], pos_vector[2],look_at_vector[0], look_at_vector[1], look_at_vector[2],up_vector[0], up_vector[1], up_vector[2]);
}// --------------
// -----Main-----
// --------------
int
main (int argc, char** argv)
{// --------------------------------------// -----Parse Command Line Arguments-----// --------------------------------------if (pcl::console::find_argument (argc, argv, "-h") >= 0){printUsage (argv[0]);return 0;}if (pcl::console::find_argument (argc, argv, "-l") >= 0){live_update = true;std::cout << "Live update is on.\n";}if (pcl::console::parse (argc, argv, "-rx", angular_resolution_x) >= 0)std::cout << "Setting angular resolution in x-direction to "<<angular_resolution_x<<"deg.\n";if (pcl::console::parse (argc, argv, "-ry", angular_resolution_y) >= 0)std::cout << "Setting angular resolution in y-direction to "<<angular_resolution_y<<"deg.\n";int tmp_coordinate_frame;if (pcl::console::parse (argc, argv, "-c", tmp_coordinate_frame) >= 0){coordinate_frame = pcl::RangeImage::CoordinateFrame (tmp_coordinate_frame);std::cout << "Using coordinate frame "<< (int)coordinate_frame<<".\n";}angular_resolution_x = pcl::deg2rad (angular_resolution_x);angular_resolution_y = pcl::deg2rad (angular_resolution_y);// ------------------------------------------------------------------// -----Read pcd file or create example point cloud if not given-----// ------------------------------------------------------------------// 读取给定的pcd点云文件或者自行创建随机点云pcl::PointCloud<PointType>::Ptr point_cloud_ptr (new pcl::PointCloud<PointType>);pcl::PointCloud<PointType>& point_cloud = *point_cloud_ptr;Eigen::Affine3f scene_sensor_pose (Eigen::Affine3f::Identity ());std::vector<int> pcd_filename_indices = pcl::console::parse_file_extension_argument (argc, argv, "pcd");if (!pcd_filename_indices.empty ()){std::string filename = argv[pcd_filename_indices[0]];if (pcl::io::loadPCDFile (filename, point_cloud) == -1){std::cout << "Was not able to open file \""<<filename<<"\".\n";printUsage (argv[0]);return 0;}scene_sensor_pose = Eigen::Affine3f (Eigen::Translation3f (point_cloud.sensor_origin_[0],point_cloud.sensor_origin_[1],point_cloud.sensor_origin_[2])) *Eigen::Affine3f (point_cloud.sensor_orientation_);}else{std::cout << "\nNo *.pcd file given => Generating example point cloud.\n\n";for (float x=-0.5f; x<=0.5f; x+=0.01f){for (float y=-0.5f; y<=0.5f; y+=0.01f){PointType point; point.x = x; point.y = y; point.z = 2.0f - y;point_cloud.points.push_back (point);}}point_cloud.width = point_cloud.size (); point_cloud.height = 1;}// -----------------------------------------------// -----Create RangeImage from the PointCloud-----// -----------------------------------------------//从点云创建深度图像对象 边界大小为1float noise_level = 0.0;float min_range = 0.0f;int border_size = 1;pcl::RangeImage::Ptr range_image_ptr(new pcl::RangeImage);pcl::RangeImage& range_image = *range_image_ptr; range_image.createFromPointCloud (point_cloud, angular_resolution_x, angular_resolution_y,pcl::deg2rad (360.0f), pcl::deg2rad (180.0f),scene_sensor_pose, coordinate_frame, noise_level, min_range, border_size);// --------------------------------------------// -----Open 3D viewer and add point cloud-----// --------------------------------------------//创建3D视图并且添加点云进行显示pcl::visualization::PCLVisualizer viewer ("3D Viewer");//定义初始化可视化对象viewer.setBackgroundColor (1, 1, 1); //设置背景为白色 [0, 1]pcl::visualization::PointCloudColorHandlerCustom<pcl::PointWithRange> range_image_color_handler (range_image_ptr, 0, 0, 0); //设置自定义颜色 黑色viewer.addPointCloud (range_image_ptr, range_image_color_handler, "range image");viewer.setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "range image");//注释部分用于添加坐标系//viewer.addCoordinateSystem (1.0f, "global");//PointCloudColorHandlerCustom<PointType> point_cloud_color_handler (point_cloud_ptr, 150, 150, 150);//viewer.addPointCloud (point_cloud_ptr, point_cloud_color_handler, "original point cloud");viewer.initCameraParameters ();setViewerPose(viewer, range_image.getTransformationToWorldSystem ()); //设置深度图像的视点参数// --------------------------// -----Show range image-----// --------------------------pcl::visualization::RangeImageVisualizer range_image_widget ("Range image");range_image_widget.showRangeImage (range_image);//--------------------// -----Main loop-----//--------------------while (!viewer.wasStopped ()){range_image_widget.spinOnce (); //处理深度图像可视化的当前事件viewer.spinOnce (); //处理3D窗口的当前事件 随时更新2D深度图像 响应可视化窗口的当前视角 -l命令激活pcl_sleep (0.01);if (live_update){scene_sensor_pose = viewer.getViewerPose(); //从视窗获得当前观察位置range_image.createFromPointCloud (point_cloud, angular_resolution_x, angular_resolution_y,pcl::deg2rad (360.0f), pcl::deg2rad (180.0f),scene_sensor_pose, pcl::RangeImage::LASER_FRAME, noise_level, min_range, border_size); //创建对应视角深度图像range_image_widget.showRangeImage (range_image); //在图像显示插件中进行显示}}
}
实验结果
1、可视化点云图像
3D视窗中以点云形式进行可视化。
2、可视化深度图像
将深度值映射为颜色,从而以颜色图像方式可视化深度图像。
3、PCL Visualizer 可视化类
PCL Visualizer类
:PCL库功能最全的可视化类,性能优于CloudViewer类
,如显示法线、绘制多种形状和多个视口。
代码
/* \author Geoffrey Biggs */#include <iostream>
#include <boost/thread/thread.hpp>
#include <pcl/common/common_headers.h>
#include <pcl/common/common_headers.h>
#include <pcl/features/normal_3d.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/console/parse.h>
// 帮助
void
printUsage (const char* progName)
{std::cout << "\n\nUsage: "<<progName<<" [options]\n\n"<< "Options:\n"<< "-------------------------------------------\n"<< "-h this help\n"<< "-s Simple visualisation example\n"<< "-r RGB colour visualisation example\n"<< "-c Custom colour visualisation example\n"<< "-n Normals visualisation example\n"<< "-a Shapes visualisation example\n"<< "-v Viewports example\n"<< "-i Interaction Customization example\n"<< "\n\n";
}/* 可视化单个点云 */
boost::shared_ptr<pcl::visualization::PCLVisualizer> simpleVis (pcl::PointCloud<pcl::PointXYZ>::ConstPtr cloud)
{//创建3D窗口并添加点云boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer (new pcl::visualization::PCLVisualizer ("3D Viewer")); //创建视窗对象 给标题栏名字“3D Viewer” 定义为boost::shared_ptr智能共享指针 保证该指针在整个程序中全局使用viewer->setBackgroundColor (0, 0, 0); //设置背景颜色为黑色viewer->addPointCloud<pcl::PointXYZ> (cloud, "sample cloud"); //将点云添加到视窗对象中 然后起个名 updataPointCloud()可实现点云的更新viewer->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "sample cloud"); //改变点云在视窗中的尺寸viewer->addCoordinateSystem (1.0); //显示坐标轴viewer->initCameraParameters (); //初始化相机参数 帮助用户从默认角度和方向观察点云return (viewer);
}/* 可视化点云颜色特征 显示点云自带的颜色*/
boost::shared_ptr<pcl::visualization::PCLVisualizer> rgbVis (pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr cloud)
{//创建3D窗口并添加点云 boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer (new pcl::visualization::PCLVisualizer ("3D Viewer")); //创建视窗对象 给标题栏名字“3D Viewer” 定义为boost::shared_ptr智能共享指针 保证该指针在整个程序中全局使用viewer->setBackgroundColor (0, 0, 0); //设置背景颜色为黑色pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGB> rgb(cloud); //创建颜色处理对象 获取点云的RGB数据viewer->addPointCloud<pcl::PointXYZRGB> (cloud, rgb, "sample cloud"); //将点云和rgb数据添加到视窗对象中 然后起个名viewer->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "sample cloud"); //改变点云在视窗中的尺寸viewer->addCoordinateSystem (1.0); //显示坐标轴viewer->initCameraParameters (); //初始化相机参数 帮助用户从默认角度和方向观察点云return (viewer);
}/* 可视化点云自定义颜色特征 用户可自己给点云上色*/
boost::shared_ptr<pcl::visualization::PCLVisualizer> customColourVis (pcl::PointCloud<pcl::PointXYZ>::ConstPtr cloud)
{//创建3D窗口并添加点云boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer (new pcl::visualization::PCLVisualizer ("3D Viewer")); //创建视窗对象 给标题栏名字“3D Viewer” 定义为boost::shared_ptr智能共享指针 保证该指针在整个程序中全局使用viewer->setBackgroundColor (0, 0, 0); //设置背景颜色为黑色pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> single_color(cloud, 0, 255, 0); //创建自定义颜色处理对象 根据点云数据 用户添加自定义的颜色为绿色viewer->addPointCloud<pcl::PointXYZ> (cloud, single_color, "sample cloud"); //将点云和rgb数据添加到视窗对象中 然后起个名viewer->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "sample cloud"); //改变点云在视窗中的尺寸viewer->addCoordinateSystem (1.0); //显示坐标轴viewer->initCameraParameters (); //初始化相机参数 帮助用户从默认角度和方向观察点云return (viewer);
}/* 可视化点云法线和其他特征 */
boost::shared_ptr<pcl::visualization::PCLVisualizer> normalsVis (pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr cloud, pcl::PointCloud<pcl::Normal>::ConstPtr normals)
{//创建3D窗口并添加点云其包括法线 boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer (new pcl::visualization::PCLVisualizer ("3D Viewer")); //同上viewer->setBackgroundColor (0, 0, 0); //同上pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGB> rgb(cloud); //同上viewer->addPointCloud<pcl::PointXYZRGB> (cloud, rgb, "sample cloud"); //同上viewer->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "sample cloud"); //同上viewer->addPointCloudNormals<pcl::PointXYZRGB, pcl::Normal> (cloud, normals, 10, 0.05, "normals"); //在可视化中给点云添加法线 每10个点显示一个 每个法线长度0.05viewer->addCoordinateSystem (1.0); //同上viewer->initCameraParameters (); //同上return (viewer);
}/* 绘制普通形状 */
boost::shared_ptr<pcl::visualization::PCLVisualizer> shapesVis (pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr cloud)
{//创建3D窗口并添加点云 之后在绘制图像 boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer (new pcl::visualization::PCLVisualizer ("3D Viewer")); //同上viewer->setBackgroundColor (0, 0, 0); //同上pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGB> rgb(cloud); //同上viewer->addPointCloud<pcl::PointXYZRGB> (cloud, rgb, "sample cloud"); //同上viewer->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "sample cloud"); //同上viewer->addCoordinateSystem (1.0); //同上viewer->initCameraParameters (); //同上//在点云上添加直线和球体模型viewer->addLine<pcl::PointXYZRGB> (cloud->points[0],cloud->points[cloud->size() - 1], "line"); //第一个点和最后一个点的连线viewer->addSphere (cloud->points[0], 0.2, 0.5, 0.5, 0.0, "sphere"); //圆心, 半径, r,g,b, 名字//在其他位置添加基于模型参数的平面及圆锥体pcl::ModelCoefficients coeffs; //定义ModelCoefficients对象coeffs.values.push_back (0.0);coeffs.values.push_back (0.0);coeffs.values.push_back (1.0);coeffs.values.push_back (0.0);viewer->addPlane (coeffs, "plane"); //模型系数标准平面方程:ax+by+cz+d=0 -->z=0coeffs.values.clear ();coeffs.values.push_back (0.3);coeffs.values.push_back (0.3);coeffs.values.push_back (0.0);coeffs.values.push_back (0.0);coeffs.values.push_back (1.0);coeffs.values.push_back (0.0);coeffs.values.push_back (5.0);viewer->addCone (coeffs, "cone"); //模型系数标准平面方程:未知return (viewer);
}/* 多视口显示 */
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewportsVis (pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr cloud, pcl::PointCloud<pcl::Normal>::ConstPtr normals1, pcl::PointCloud<pcl::Normal>::ConstPtr normals2)
{// 创建3D窗口并添加显示点云其包括法线boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer (new pcl::visualization::PCLVisualizer ("3D Viewer")); //同上viewer->initCameraParameters (); //同上int v1(0);viewer->createViewPort(0.0, 0.0, 0.5, 1.0, v1); //创建新的视口 确定视口1在窗口中的位置 范围[0, 1]viewer->setBackgroundColor (0, 0, 0, v1); //视口背景颜色viewer->addText("Radius: 0.01", 10, 10, "v1 text", v1); //添加标签 ,x,y,标签id,视口1pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGB> rgb(cloud); //同上viewer->addPointCloud<pcl::PointXYZRGB> (cloud, rgb, "sample cloud1", v1); //添加点云、颜色、名儿、视口1到PCL可视化对象中int v2(0); //同上viewer->createViewPort(0.5, 0.0, 1.0, 1.0, v2);viewer->setBackgroundColor (0.3, 0.3, 0.3, v2);viewer->addText("Radius: 0.1", 10, 10, "v2 text", v2);pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZRGB> single_color(cloud, 0, 255, 0);viewer->addPointCloud<pcl::PointXYZRGB> (cloud, single_color, "sample cloud2", v2);viewer->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "sample cloud1");viewer->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "sample cloud2");viewer->addCoordinateSystem (1.0);viewer->addPointCloudNormals<pcl::PointXYZRGB, pcl::Normal> (cloud, normals1, 10, 0.05, "normals1", v1); //为视口1的点云添加法线1viewer->addPointCloudNormals<pcl::PointXYZRGB, pcl::Normal> (cloud, normals2, 10, 0.05, "normals2", v2); //为视口2的点云添加法线2return (viewer);
}/* 自定义交互 */
unsigned int text_id = 0;
//键盘事件回调函数
void keyboardEventOccurred (const pcl::visualization::KeyboardEvent &event,void* viewer_void)
{boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer = *static_cast<boost::shared_ptr<pcl::visualization::PCLVisualizer> *> (viewer_void);//判断“R”键是否按下if (event.getKeySym () == "r" && event.keyDown ()){std::cout << "r was pressed => removing all text" << std::endl;char str[512];for (unsigned int i = 0; i < text_id; ++i){sprintf (str, "text#%03d", i);viewer->removeShape (str);}text_id = 0;}
}
//鼠标事件回调函数
void mouseEventOccurred (const pcl::visualization::MouseEvent &event,void* viewer_void)
{boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer = *static_cast<boost::shared_ptr<pcl::visualization::PCLVisualizer> *> (viewer_void);//判断鼠标左键是否按下if (event.getButton () == pcl::visualization::MouseEvent::LeftButton &&event.getType () == pcl::visualization::MouseEvent::MouseButtonRelease){std::cout << "Left mouse button released at position (" << event.getX () << ", " << event.getY () << ")" << std::endl;char str[512];sprintf (str, "text#%03d", text_id ++);viewer->addText ("clicked here", event.getX (), event.getY (), str);}
}
//交互
boost::shared_ptr<pcl::visualization::PCLVisualizer> interactionCustomizationVis ()
{boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer (new pcl::visualization::PCLVisualizer ("3D Viewer")); //同上viewer->setBackgroundColor (0, 0, 0);viewer->addCoordinateSystem (1.0);viewer->registerKeyboardCallback (keyboardEventOccurred, (void*)&viewer); //注册键盘事件回调函数、回调参数viewer->registerMouseCallback (mouseEventOccurred, (void*)&viewer); //注册鼠标事件回调函数、回调参数return (viewer);
}
// -----Main-----
int
main (int argc, char** argv)
{// 解析命令行参数if (pcl::console::find_argument (argc, argv, "-h") >= 0){printUsage (argv[0]);return 0;}bool simple(false), rgb(false), custom_c(false), normals(false),shapes(false), viewports(false), interaction_customization(false);if (pcl::console::find_argument (argc, argv, "-s") >= 0){simple = true;std::cout << "Simple visualisation example\n";}else if (pcl::console::find_argument (argc, argv, "-c") >= 0){custom_c = true;std::cout << "Custom colour visualisation example\n";}else if (pcl::console::find_argument (argc, argv, "-r") >= 0){rgb = true;std::cout << "RGB colour visualisation example\n";}else if (pcl::console::find_argument (argc, argv, "-n") >= 0){normals = true;std::cout << "Normals visualisation example\n";}else if (pcl::console::find_argument (argc, argv, "-a") >= 0){shapes = true;std::cout << "Shapes visualisation example\n";}else if (pcl::console::find_argument (argc, argv, "-v") >= 0){viewports = true;std::cout << "Viewports example\n";}else if (pcl::console::find_argument (argc, argv, "-i") >= 0){interaction_customization = true;std::cout << "Interaction Customization example\n";}else{printUsage (argv[0]);return 0;}// 自行创建一随机点云pcl::PointCloud<pcl::PointXYZ>::Ptr basic_cloud_ptr (new pcl::PointCloud<pcl::PointXYZ>);pcl::PointCloud<pcl::PointXYZRGB>::Ptr point_cloud_ptr (new pcl::PointCloud<pcl::PointXYZRGB>);std::cout << "Genarating example point clouds.\n\n";// 以椭圆为边线沿z轴拉伸获取其点云,并赋予红绿蓝渐变色。uint8_t r(255), g(15), b(15);for (float z(-1.0); z <= 1.0; z += 0.05){for (float angle(0.0); angle <= 360.0; angle += 5.0){pcl::PointXYZ basic_point;basic_point.x = 0.5 * cosf (pcl::deg2rad(angle));basic_point.y = sinf (pcl::deg2rad(angle));basic_point.z = z;basic_cloud_ptr->points.push_back(basic_point); //创建的xyz给basic_cloud_ptr点云pcl::PointXYZRGB point;point.x = basic_point.x;point.y = basic_point.y;point.z = basic_point.z;uint32_t rgb = (static_cast<uint32_t>(r) << 16 |static_cast<uint32_t>(g) << 8 | static_cast<uint32_t>(b));point.rgb = *reinterpret_cast<float*>(&rgb);point_cloud_ptr->points.push_back (point); //创建的xyzrgb给point_cloud_ptr点云}if (z < 0.0){r -= 12;g += 12;}else{g -= 12;b += 12;}}basic_cloud_ptr->width = (int) basic_cloud_ptr->points.size ();basic_cloud_ptr->height = 1;point_cloud_ptr->width = (int) point_cloud_ptr->points.size ();point_cloud_ptr->height = 1;// 0.05为搜索半径获取点云法线pcl::NormalEstimation<pcl::PointXYZRGB, pcl::Normal> ne;ne.setInputCloud (point_cloud_ptr); //输入点云数据pcl::search::KdTree<pcl::PointXYZRGB>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZRGB> ());ne.setSearchMethod (tree); //输入k-d tree结构pcl::PointCloud<pcl::Normal>::Ptr cloud_normals1 (new pcl::PointCloud<pcl::Normal>);ne.setRadiusSearch (0.05); //搜索半径0.05ne.compute (*cloud_normals1); //计算搜索半径内的法线 参数类型需要引用cloud_normals1指针那块儿地址// 0.1为搜索半径获取点云法线pcl::PointCloud<pcl::Normal>::Ptr cloud_normals2 (new pcl::PointCloud<pcl::Normal>);ne.setRadiusSearch (0.1); //重置搜索半径0.05ne.compute (*cloud_normals2); //计算搜索半径内的法线 参数类型需要引用cloud_normals2指针那块儿地址/* 根据输入参数判断怎么处理这块儿点云 */boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer;if (simple){viewer = simpleVis(basic_cloud_ptr);}else if (rgb){viewer = rgbVis(point_cloud_ptr);}else if (custom_c){viewer = customColourVis(basic_cloud_ptr);}else if (normals){viewer = normalsVis(point_cloud_ptr, cloud_normals2);}else if (shapes){viewer = shapesVis(point_cloud_ptr);}else if (viewports){viewer = viewportsVis(point_cloud_ptr, cloud_normals1, cloud_normals2);}else if (interaction_customization){viewer = interactionCustomizationVis();}// 主循环while (!viewer->wasStopped ()){viewer->spinOnce (100); //视窗处理事件时间boost::this_thread::sleep (boost::posix_time::microseconds (100000));}
}
实验结果
- 1、可视化单个点云
黑白相间,非常单调。
- 2、可视化点云颜色特征
显示点云自己的颜色 - 3、可视化自定义颜色特征
用户可以为非PointXYZRGB
点云添加自己喜欢的颜色。
- 4、可视化点云法线和其他特征
画个法线、主曲率、几何特征等。
- 5、绘制普通形状
线、面、球、锥形啥的。
- 6、多视口显示
一个窗口显示了两个视口。
对比发现,搜索半径0.05的点云计算出的法相不准确。
4、PCLPlotter可视化特征直方图
就是和Matlab一样,画图用的一个类。
代码
看看怎么用就行,有些特征提取、关键点啥的还没学到。
/* \author Kripasindhu Sarkar */
#include<pcl/visualization/pcl_plotter.h>
#include <pcl/io/pcd_io.h>
#include <pcl/filters/filter.h>
#include <pcl/filters/voxel_grid.h>
#include <pcl/console/parse.h>
#include <pcl/kdtree/kdtree_flann.h>
#include <pcl/filters/normal_space.h>
#include <pcl/common/eigen.h>
#include <pcl/features/normal_3d.h>
#include <pcl/features/fpfh.h>
#include <pcl/visualization/histogram_visualizer.h>
#include<iostream>
#include<vector>
#include<utility>
#include<math.h> //for abs()//提前说明命名空间 后期使用就不用加 :: 了
using namespace std;
using namespace pcl::visualization;
using namespace pcl::console;void
generateData (double *ax, double *acos, double *asin, int numPoints)
{double inc = 7.5 / (numPoints - 1);for (int i = 0; i < numPoints; ++i){ax[i] = i*inc;acos[i] = cos (i * inc);asin[i] = sin (i * inc);}
}//.....................回调函数....................
double
step (double val)
{if (val > 0)return (double) (int) val;elsereturn (double) ((int) val - 1);
}double
identity_i (double val)
{return val;
}int
main (int argc, char * argv [])
{if(argc<2){std::cout<<".exe source.pcd -r 0.005 -ds 5"<<endl;return 0;}float voxel_re=0.005,ds_N=5;parse_argument (argc, argv, "-r", voxel_re);// 设置点云分辨率parse_argument (argc, argv, "-ds", ds_N);// 设置半径//调节下采样的分辨率以保持数据处理的速度。// 下采样 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_src (new pcl::PointCloud<pcl::PointXYZ>); pcl::io::loadPCDFile (argv[1], *cloud_src); std::vector<int> indices1; pcl::removeNaNFromPointCloud (*cloud_src, *cloud_src, indices1); pcl::PointCloud<pcl::PointXYZ>::Ptr ds_src (new pcl::PointCloud<pcl::PointXYZ>); pcl::VoxelGrid<pcl::PointXYZ> grid; grid.setLeafSize (voxel_re, voxel_re, voxel_re); grid.setInputCloud (cloud_src); grid.filter (*ds_src); //计算法向量pcl::PointCloud<pcl::Normal>::Ptr norm_src (new pcl::PointCloud<pcl::Normal>); pcl::search::KdTree<pcl::PointXYZ>::Ptr tree_src(new pcl::search::KdTree<pcl::PointXYZ>()); pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> ne; PCL_INFO (" Normal Estimation - Source \n"); ne.setInputCloud (ds_src); ne.setSearchSurface (cloud_src); ne.setSearchMethod (tree_src); ne.setRadiusSearch (ds_N*2*voxel_re); ne.compute (*norm_src); // 提取关键点pcl::PointCloud<pcl::PointXYZ>::Ptr keypoints_src (new pcl::PointCloud<pcl::PointXYZ>); pcl::PointCloud<pcl::PointXYZ>::Ptr keypoints_tgt (new pcl::PointCloud<pcl::PointXYZ>); grid.setLeafSize (ds_N*voxel_re,ds_N*voxel_re,ds_N*voxel_re); grid.setInputCloud (ds_src); grid.filter (*keypoints_src); //Feature-Descriptor PCL_INFO ("FPFH - Feature Descriptor\n"); //FPFH //FPFH Source pcl::FPFHEstimation<pcl::PointXYZ, pcl::Normal, pcl::FPFHSignature33> fpfh_est_src; pcl::search::KdTree<pcl::PointXYZ>::Ptr tree_fpfh_src (new pcl::search::KdTree<pcl::PointXYZ>); fpfh_est_src.setSearchSurface (ds_src);//输入完整点云数据fpfh_est_src.setInputCloud (keypoints_src); // 输入关键点fpfh_est_src.setInputNormals (norm_src); fpfh_est_src.setRadiusSearch (2*ds_N*voxel_re);fpfh_est_src.setSearchMethod(tree_fpfh_src);pcl::PointCloud<pcl::FPFHSignature33>::Ptr fpfh_src (new pcl::PointCloud<pcl::FPFHSignature33>); fpfh_est_src.compute (*fpfh_src); /* 利用PCLPlotter绘制图像 *///1、定义绘图器PCLPlotter *plotter = new PCLPlotter ("My Plotter"); //2、设置特性plotter->setShowLegend (true);std::cout<<pcl::getFieldsList<pcl::FPFHSignature33>(*fpfh_src); //获取点云的field name参数plotter->addFeatureHistogram<pcl::FPFHSignature33>(*fpfh_src,"fpfh",5,"one_fpfh"); //添加直方图显示//显示两秒plotter->setWindowSize (800, 600);plotter->spinOnce (2000);plotter->clearPlots ();// 产生对应点对int numPoints = 69;double ax[100], acos[100], asin[100];generateData (ax, acos, asin, numPoints);//添加绘图数据plotter->addPlotData (ax, acos, numPoints, "cos");plotter->addPlotData (ax, asin, numPoints, "sin");//显示2splotter->spinOnce (2000);plotter->clearPlots ();//...................绘制隐式函数....................//设置y轴范围plotter->setYRange (-10, 10);//定义多项式vector<double> func1 (1, 0);func1[0] = 1; //y = 1vector<double> func2 (3, 0);func2[2] = 1; //y = x^2plotter->addPlotData (std::make_pair (func1, func2), -10, 10, "y = 1/x^2", 100, vtkChart::POINTS);plotter->spinOnce (2000); //貌似是延时plotter->addPlotData (func2, -10, 10, "y = x^2");plotter->spinOnce (2000);//回调函数plotter->addPlotData ( identity_i, -10, 10, "identity");plotter->spinOnce (2000);plotter->addPlotData (abs, -10, 10, "abs");plotter->spinOnce (2000);plotter->addPlotData (step, -10, 10, "step", 100, vtkChart::POINTS);plotter->spinOnce (2000);plotter->clearPlots ();//........................一个简单动画..............................vector<double> fsq (3, 0);fsq[2] = -100; //y = x^2while (plotter->wasStopped ()){if (fsq[2] == 100) fsq[2] = -100;fsq[2]++;char str[50];sprintf (str, "y = %dx^2", (int) fsq[2]);plotter->addPlotData (fsq, -10, 10, str);plotter->setYRange (-1, 1);plotter->spinOnce (100);plotter->clearPlots ();}return 1;
}
实验结果
1、
快速点特征直方图
(FPFH Fast Point Feature Histograms)具体概念在之后的章节学习。
2、正弦和余弦图
3、隐式函数组图
5、PCL结合Qt使用框架
GUI工程组成:Qt+PCL+CMake
PCL是支持Qt开发的,经过简答,基于VTK可视化模块可以快速开发属于自己的点云观察界面。
还有网页上的点云可视化。
这些等把后边儿的章节学的差不多了,对点云的观察有了更深的理解,再来学习开发Qt界面。
PCL_5---可视化相关推荐
- 【置顶】利用 NLP 技术做简单数据可视化分析教程(实战)
置顶 本人决定将过去一段时间在公司以及日常生活中关于自然语言处理的相关技术积累,将在gitbook做一个简单分享,内容应该会很丰富,希望对你有所帮助,欢迎大家支持. 内容介绍如下 你是否曾经在租房时因 ...
- windows安装MongoDB环境以及在pycharm中配置可视化插件
安装MongoDB数据库 参考这里 安装PyMongo python3 -m pip3 install pymongo指定版本 python3 -m pip3 install pymongo==3.5 ...
- 只要5分钟用数据可视化带你看遍11月份新闻热点事件
2017年11月份已经离我们而去,在过去的11月份我们也许经历了双十一的剁手,也可能亲眼看见了别人剁手.11月份的北京大兴区发生了"11·18"重大火灾,国内多家幼儿园也多次上了头 ...
- 模型可视化_20210208
20210204 https://ezyang.github.io/convolution-visualizer/index.html 卷积动态可视化 今天小编要给大家推荐的这个可视化工具Visual ...
- lightgbm 决策树 可视化 graphviz
决策树模型,XGBoost,LightGBM和CatBoost模型可视化 安装 graphviz 参考文档 http://graphviz.readthedocs.io/en/stable/manua ...
- 深度学习网络模型可视化netron
很多时候,复现人家工程的时候,需要了解人家的网络结构.但不同框架之间可视化网络层方法不一样,这样给研究人员造成了很大的困扰. 前段时间,发现了一个可视化模型结构的神奇:Netron 查看全文 http ...
- Pytorch使用tensorboardX可视化。超详细
tensorboard --logdir runs 改为 tensorboard --logdir=D:\model\tensorboard\runs 重点 在网上看了很多方法后发现将原本链接中的计算 ...
- Pytorch的网络结构可视化(tensorboardX)(详细)
20210610 if config.test is True:model = load_test_model(model, config)print(model) 打印网络结构 版权声明:本文为博主 ...
- BERT可视化工具bertviz体验
BERT可视化工具体验:bertviz是用于BERT模型注意力层的可视化页面. 1,bertviz的github地址:https://github.com/jessevig/bertviz 2,将be ...
- 机器学习PAL数据可视化
机器学习PAL数据可视化 本文以统计全表信息为例,介绍如何进行数据可视化. 前提条件 完成数据预处理,详情请参见数据预处理. 操作步骤 登录PAI控制台. 在左侧导航栏,选择模型开发和训练 > ...
最新文章
- Oracle 导出表结构
- js中iframe访问父页的方法
- 佳铁怎样传输程序_阿里资深开发工程师合著《Java开发手册》,影响250万程序员附pdf...
- 三次握手和四次挥手图解_图解TCP三次握手和四次挥手
- 【Android开发】线程与消息处理-Handler消息传递机制之Looper
- 【iOS-Cocos2d游戏开发之二十】精灵的基础知识点总汇(位图操作/贴图更换/重排z轴等)以及利用CCSprite与CCLayerColor制作简单遮盖层!...
- [转]wchar_t char std::string std::wstring CString 转换
- Tiny4412 小试牛刀
- 利用FbinstTool+大白菜u盘工具,制作多系统启动U盘【转】
- Cesium 多边形(polygon)extrudedHeight 和 height 的区别
- 算法导论课后题和思考题 第3章
- 什么是SWFObject,如何使用!
- 如何利用CRM软件建立有利可图的客户关系?
- 计算机中复制和移动的操作系统,如何将旧电脑中的全部文件复制到新电脑中,包括操作系统?...
- html 自动填表,Delphi WEB网页自动填表
- Jmeter使用BeanShell取样器调用Python脚本
- web scraper 爬取微博粉丝性别以及微博内容
- 简易入手《SOM神经网络》的本质与原理
- 给GitLab项目添加成员用户
- 微信消息管理之被动回复用户消息