【PCL自学:PCLPlotter】PCLPlotter绘制数据分析图

一、什么是PCLPlotter

   PCLPoltter类似于Matlab的plot函数,用来对点云数据绘制分析图,例如某一行或列点云Z值的变化图。PCLPlotter提供了一个非常直接和简单的绘图界面。我们可以在库中可视化所有类型的重要绘图比如从多项式函数或直方图。在本章节中介绍一些特定概念时,请仔细阅读文档,以了解确切的方法名。
   我们直接从程序片段中学习如何使用PCLPlotter吧。

二、示例程序

2.1 基本绘图流程

   从最简单的绘制X,Y相关二次曲线( y = x 2 y=x^2 y=x2)开始。

#include<vector>
#include<iostream>
#include<utility>

#include<pcl/visualization/pcl_plotter.h>
//...

int
main ()
{
  //首先定义一个绘图器 PCLPlotter
  pcl::visualization::PCLPlotter * plotter = new PCLPlotter ();

  //然后定义绘图函数的多项式系数, 例如y = x^2.其多项式系数有3个,分别是1,0,0,在定义的容器里,第0个是常数,第1个是x的系数,第2个是x^2的系数。除了x^2系数是1,其余是0。
  std::vector<double> func1 (3,0);
  func1[2] = 1;

  //以[- 10,10]为X轴范围,以“y = X ^2”为标题,向绘图器中添加多项式func1
  plotter->addPlotData (func1, -10, 10, "y = x^2");

  //显示多项式图像
  plotter->plot ();

  return 0;
}

   以上代码运行结束后如下:
在这里插入图片描述
   由以上代码我们可以总结出PCLPlotter的基本代码结构,其使用方法非常简单,类似于Matlab

...
//1. 定义1个 plotter. 
pcl::visualization::PCLPlotter *plotter = new PCLPlotter ("My Plotter");

...
//2. 使用addPlotData* ()函数 添加多项式系数数据
plotter->addPlotData* ();

...
//3. 设置Plotter界面属性
plotter->setWindowSize (900, 600);
plotter->setYTitle ("this is my own function");

...
//4. 显示界面
plotter->plot ()

  基本使用框架介绍完毕,下面我们将分别介绍更加细节的内容。

2.2 绘图细节处理

2.2.1 为图像选择颜色方案

  在addPlotData*()函数中,可以选择将想要的颜色添加到绘图中。但如果不主动设置,Plotter将根据配色方案自动上色。
  默认的颜色方案是vtkColorSeries::SPECTRUM,它在整个光谱中包含7种不同的色调。
  除了默认,也可以选择vtkColorSeries::WARM, vtkColorSeries::COOL, vtkColorSeries::BLUES, vtkColorSeries::WILD_FLOWER, vtkColorSeries::CITRUS.
  你可以通过setColorScheme()函数来改变颜色方案。要将颜色方案的效果反映到所有绘图中,在调用任何addPlotData*()函数之前调用此函数才能生效。

2.2.2 选择不同类型的数据输入到图表

  在文档中可以查看addPlotData()函数的详细签名。这些原型基本上说明了它们的功能。

① Point-Correspondences(特征点匹配)
  这是提供输入数据的最基本方式。使用std::vectorstd::pair;提供点对应,即(x,y)坐标。如下

...
std::vector<std::pair<double, double> > data;
populateData (data);
plotter->addPlotData (data,"cos");
...

② Table (表格)
  用户以空格分隔的表的形式将通信存储在文本文件中。这就形成了使用MS Excel绘图的替代。下面是一个非常简单的可执行文件,它执行了MS Excel Plotter的功能。

#include<pcl/visualization/pcl_plotter.h>

int
main (int argc, char ** argv)
{
  pcl::visualization::PCLPlotter * plotter = new PCLPlotter ();
  plotter->addPlotData (argv[1]);
  plotter->plot ();

  return 0;
}

③ Polynomial and Rational Functions(多项式和有理函数)
  多项式用系数向量来定义,有理函数用多项式对(分子和分母对)来定义。下面的代码片段绘制了函数y = 1/x的图形.

...
std::vector<double> func1 (1,0);
func1[0] = 1; // 1
std::vector<double> func2 (2,0);
func1[1] = 1; // x

plotter->addPlotData (std::make_pair (func1, func2),-10, 10, "y = 1/x");
...

④ A custom explicit function(自定义显式函数)
  用户可以指定一个自定义函数,f以回调的形式描述关系:Y = f(X)

...
double
identity (double val)
{
  return val;
}
...

...
plotter->addPlotData (identity,-10, 10,"identity");
...

2.2.3 添加其他属性和装饰

  用户可以添加其他属性的情节,如标题,象限标题,图例,背景颜色等。需要在plotter->plot ();函数调用之前的任何时间调用这些函数。

...
plotter->setTitle ("My plot"); //global title
plotter->setXTitle ("degrees");
plotter->setYTitle ("cos");
plotter->setShowLegend (true); //show legends
...
plotter->plot ();
...

2.2.4 直方图和折线图

  PCLPlotter提供了一个非常方便的MATLAB类直方图绘图函数(MATLAB中的hist())。它将原始数据根据频率进行分类并绘制成条形图。

...

std::vector<double> freqdata = generateNomalDistData ();

plotter->addHistogramData (freqdata,10); //number of bins are 10

plotter->plot ();
...

2.2.5 随着数据添加动态显示图形

...

//data and callback defined here
...

plotter->addPlotData (func1, -10, 10, "y = x^2");
plotter->spinOnce (2000);    //动态显示频率 2s刷新一次

plotter->clearPlots ();
plotter->addPlotData (identity,-10, 10,"identity");
plotter->spinOnce (2000);

plotter->clearPlots ();
plotter->addPlotData (abs,-5, 5,"abs");
plotter->spinOnce (2000);
...

2.3 Demo

  /* \author Kripasindhu Sarkar */
  
  #include<pcl/visualization/pcl_plotter.h>
  
  #include<iostream>
  #include<vector>
  #include<utility>
  #include<cmath>  //for std::abs()
  
 using namespace pcl::visualization;
 
 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] = std::cos (i * inc);
     asin[i] = sin (i * inc);
   }
 }
 
 //.....................callback functions defining Y= f(X)....................
 double
 step (double val)
 {
   if (val > 0)
     return (double) (int) val;
   else
     return (double) ((int) val - 1);
}
 
 double
 identity (double val)
{
   return val;
}
//............................................................................
 
 int
 main ()
 {
   //defining a plotter
   PCLPlotter *plotter = new PCLPlotter ("My Plotter");
 
   //setting some properties
   plotter->setShowLegend (true);
 
   //generating point correspondances
   int numPoints = 69;
   double ax[100], acos[100], asin[100];
   generateData (ax, acos, asin, numPoints);
 
   //adding plot data
   plotter->addPlotData (ax, acos, numPoints, "cos");
   plotter->addPlotData (ax, asin, numPoints, "sin");
 
   //display for 2 seconds
   plotter->spinOnce (3000);
   plotter->clearPlots ();
   
   
   //...................plotting implicit functions and custom callbacks....................
 
   //make a fixed axis
   plotter->setYRange (-10, 10);
 
   //defining polynomials
   std::vector<double> func1 (1, 0);
   func1[0] = 1; //y = 1
   std::vector<double> func2 (3, 0);
   func2[2] = 1; //y = x^2
 
   plotter->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);
 
   //callbacks
   plotter->addPlotData (identity, -10, 10, "identity");
   plotter->spinOnce (2000);
 
   plotter->addPlotData (std::abs, -10, 10, "abs");
   plotter->spinOnce (2000);
 
   plotter->addPlotData (step, -10, 10, "step", 100, vtkChart::POINTS);
   plotter->spinOnce (2000);
 
   plotter->clearPlots ();
 
   //........................A simple animation..............................
   std::vector<double> fsq (3, 0);
   fsq[2] = -100; //y = x^2
   while (!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->spinOnce (100);
    plotter->clearPlots ();
  }

  return 1;
}

【博主简介】
  斯坦福的兔子,男,天津大学工学硕士。毕业至今从事光学三维成像及点云处理相关工作。因工作中使用的三维处理库为公司内部库,不具有普遍适用性,遂自学开源PCL库及其相关数学知识以备使用。谨此将自学过程与君共享。
博主才疏学浅,尚不具有指导能力,如有问题还请各位在评论处留言供大家共同讨论。

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值