1. 程式人生 > >《PCL點雲庫學習&VS2010(X64)》Part 8 PCL1.72(VTK6.2.0)視覺化例程

《PCL點雲庫學習&VS2010(X64)》Part 8 PCL1.72(VTK6.2.0)視覺化例程

Part 8 PCL1.72(VTK6.2.0)視覺化例程                                                                                               

PCL1.72

VTK6.20

控制檯程式

加入.props屬性表文件

1、Cloud_Viewer

Cloud_Viewer.cpp程式碼:

#include <vtkAutoInit.h>       
VTK_MODULE_INIT(vtkRenderingOpenGL);
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingFreeType); 

#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.0f, 0.5f, 1.0f);
	pcl::PointXYZ o;
	o.x = 1.0;
	o.y = 0;
	o.z = 0;
	viewer.addSphere(o, 0.25, "Sphere", 0);
	std::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);//this is to set the coordination of text "Once per viewer loop:"
	//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);
	pcl::visualization::CloudViewer viewer("Cloud Viewer");
	//showCloud 函式是同步的,在此處等待直到渲染顯示為止
	viewer.showCloud(cloud);
	//該註冊函式在視覺化時只調用一次
	viewer.runOnVisualizationThreadOnce(viewerOneOff);
	//該註冊函式在渲染輸出是每次都呼叫
	viewer.runOnVisualizationThread(viewerPsycho);
	while (!viewer.wasStopped())
	{
		//在此處可以新增其他處理
		user_data++;
	}
	return 0;
}
編譯,執行:

2、控制檯程式:pcl_visualizer_demo

注意:

1)報錯 Error C4996"fopen" 在屬性——前處理器——前處理器定義中,新增_CRT_SECURE_NO_WARNINGS命令,重新編譯即可通過。

2)標頭檔案前面加入

#include <vtkAutoInit.h>       
VTK_MODULE_INIT(vtkRenderingOpenGL);
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingFreeType);

3)viewer->addPointCloud<pcl::PointXYZ> (cloud, "sample cloud");

這句是產生點雲資料的程式碼,註釋掉後,介面中就沒有點雲可顯示。

4)viewer->addPointCloudNormals<pcl::PointXYZRGB, pcl::Normal> (cloud, normals, 10, 0.05, "normals");

這句是為點雲新增法線,這行程式碼放在繪製點雲的程式碼後面,即可實現對點雲法線的顯示。
一旦使用者計算得到法線,只需要一行程式在視窗中就可以顯示這些法線,該顯示法線成員方法的引數有法線顯示的個數(
這裡,每 10 個點顯示一個)及每個法線的長度 (這個例子中是 0.05,當然使用者可以自行調整為這些引數)。

5)//在其他位置新增基於模型引數的平面及圓錐體
pcl::ModelCoefficients coeffs;
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 方向,許多繪製形狀的函式都採用這種定義係數的方法來定義形狀。

6)coeffs.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");

利用模型係數指定錐形的引數。

7)int v1(0);
viewer->createViewPort(0.0, 0.0, 0.5, 1.0, v1);
viewer->setBackgroundColor (0, 0, 0, v1);
viewer->addText("Radius: 0.01", 10, 10, "v1 text", v1);

第一句是Vieweport的預設位置,第二句是設定視口的程式碼,第三句設定背景色,第四句新增文字。

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

pcl_visualizer_demo.cpp程式碼:

#include <vtkAutoInit.h>       
VTK_MODULE_INIT(vtkRenderingOpenGL);
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingFreeType);

/* \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";
}

//Simple visualisation example
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"));
  viewer->setBackgroundColor (0, 0, 0);
  viewer->addPointCloud<pcl::PointXYZ> (cloud, "sample cloud");
  viewer->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "sample cloud");
  viewer->addCoordinateSystem (1.0);
  viewer->initCameraParameters ();
  return (viewer);
}

//RGB colour visualisation example
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"));
  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 ();
  return (viewer);
}

//Custom colour visualisation example
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"));
  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");
  viewer->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "sample cloud");
  viewer->addCoordinateSystem (1.0);
  viewer->initCameraParameters ();
  return (viewer);
}

//Normals visualisation example
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");
  viewer->addCoordinateSystem (1.0);
  viewer->initCameraParameters ();
  return (viewer);
}

//Shapes visualisation example
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");
   //在其他位置新增基於模型引數的平面及圓錐體
   pcl::ModelCoefficients coeffs;
  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");
  coeffs.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);
}

//Viewports example
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);
  viewer->setBackgroundColor (0, 0, 0, v1);
  viewer->addText("Radius: 0.01", 10, 10, "v1 text", v1);
  pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGB> rgb(cloud);
  viewer->addPointCloud<pcl::PointXYZRGB> (cloud, rgb, "sample cloud1", v1);
  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);
  viewer->addPointCloudNormals<pcl::PointXYZRGB, pcl::Normal> (cloud, normals2, 10, 0.05, "normals2", v2);

  return (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);
  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);
  }
}

//Interaction Customization example
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);

      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);
    }
    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);
  pcl::PointCloud<pcl::Normal>::Ptr cloud_normals1 (new pcl::PointCloud<pcl::Normal>);
  ne.setRadiusSearch (0.05);
  ne.compute (*cloud_normals1);
  //  0.1為搜尋半徑獲取點雲法線
  pcl::PointCloud<pcl::Normal>::Ptr cloud_normals2 (new pcl::PointCloud<pcl::Normal>);
  ne.setRadiusSearch (0.1);
  ne.compute (*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));
  }
}

除錯執行:

F5或者Ctrl+F5是沒有作用的,需要在控制檯中執行

1)Win+r,確定,進入控制檯

2)輸入:cd /d D:\PCLWorkspace\7\pcl_visualizer_demo\Debug

3)輸入:pcl_visualizer_demo.exe -s

可以觀察第一個例程,其他的例子操作類似。

執行結果:

simple:


RGB:

Custom:

Normals:

Shape:

Viewerports:

Interaction:


3、PCL視覺化視窗的一些常用快捷鍵操作,有的在VTK介面中也是可以的:

r鍵: 重現視角。如果讀入檔案沒有在主視窗顯示,不妨按下鍵盤的r鍵一試。
j鍵:截圖功能。
g鍵:顯示/隱藏 座標軸。
滑鼠:左鍵,使影象繞自身旋轉; 滾輪, 按住滾輪不鬆,可移動影象,滾動滾輪,可放大/縮小 影象; 右鍵,“原地” 放大/縮小。
-/+:-(減號)可縮小點; +(加號),可放大點。


4、兩點間劃線例程,其實就是顯示兩點直線:

       在pcl中, 有一類可以畫兩點之間線段的函式,繪製點之間連線的方法十分有用,例如,顯示兩組點雲之間的對應點關係時,可方便使用者直觀的觀看點雲之間的對應關係。它是視覺化函式pcl::visualizeton的一員:

#include <iostream>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/point_types.h>
#include <boost/thread/thread.hpp>
using namespace std;    
typedef pcl::PointCloud<pcl::PointXYZ>  pointcloud;
int main(int argc, char *argv[])
{
    pointcloud::Ptr  cloud (new pointcloud);
    pcl::PointXYZ a, b, z;
    a.x = 0;
    a.y = 0;
    a.z = 0;
    b.x  = 5;
    b.y  = 8;
    b.z = 10;
    z.x = 4;
    z.y = 3;
    z.z = 20;

      boost::shared_ptr<pcl::visualization::PCLVisualizer> view (new pcl::visualization::PCLVisualizer ("line Viewer"));
      view->setBackgroundColor(r,g,b); //背景色
      view->addLine<pcl::PointXYZ>(a,b,"line");
    view->addLine<pcl::PointXYZ>  (a,z,255,0,0,"line1"); //紅色線段,線的名字叫做"line1"
    view->addArrow<pcl::PointXYZ> (b,z,255,0,0,"arrow");  //帶箭頭
       while (!view->wasStopped ())
       {
           view->spinOnce(100);
           boost::this_thread::sleep (boost::posix_time::microseconds (100000));

       }

    return 0;
}

      上面程式主要是畫了兩條線段,a-b,名字叫做“line”; a-z. 名字叫做"line1"其中a-z為紅色,在addLine<PointT>函式中,其原型為

addLine(p1,p2,r,g,b, "viewport");

addArrow(b,z,r,g,b,"id name"), 

       主要是畫出從b指向z的帶箭頭的線段,其顏色由使用者指定,也可預設。

5、PCL視覺化類顯示直方圖,

1)以FPFH為例,可以這樣做,注意這邊的用histogram_visualizer.h裡的函式:

#include <pcl/visualization/histogram_visualizer.h> //直方圖的視覺化
#include <boost/thread/thread.hpp>
#include <pcl/visualization/pcl_plotter.h>
int main (int argc, char **argv)
{
    ....
     直方圖計算
    ....
    
      pcl::visualization::PCLHistogramVisualizer view;
      view.setBackgroundColor(255,0,0);
      view.addFeatureHistogram<pcl::FPFHSignature33> (*fpfhs,"fpfh",1000);//對下標為1000的元素視覺化
      //view.spinOnce(10000);  //迴圈的次數
      view.spin();  //無限迴圈
    return 0;
}
2)也可以用pcl_plotter.h中的plotter函式來畫直方圖,需要在新增標頭檔案#include <pcl/visualization/pcl_plotter.h>:
#include <pcl/visualization/pcl_plotter.h>

……

 pcl::visualization::PCLPlotter plotter;
// We need to set the size of the descriptor beforehand.
plotter.addFeatureHistogram(*fpfhs, 300); //設定的很座標長度,該值越大,則顯示的直方圖越細緻
plotter.plot();