之前學習點雲庫做一些簡單的應用都是直接複製demo的代碼,然後把導入文件改一下,今天嘗試自己寫一些程序,結果錯漏百出,難受的早上,不過堅持了下來,求誇~~~

這個主要是一個簡單的繪製軌跡的教程,繪製軌跡只需要兩個東西,旋轉R和平移T,只要我們能夠得到這兩個東西,再結合初始坐標點,利用點雲庫裡面的Visualization模塊中的addLine函數就可以實現軌跡的繪製了。

這裡為了簡單,我們直接採用模擬的數據以及模擬的旋轉矩陣。先一步一步講解流程,最後再附上源碼~~

1.生成點雲數據

```c++  //為了方便,我們在這裡只生成一個點

pcl::PointCloud::Ptr cloud1(new pcl::PointCloud);
cloud1->width = 1;
cloud1->height = 1;
cloud1->points.resize(cloud1->width * cloud1->height);
cloud1->points[0].x = 1;
cloud1->points[0].y = 1;
cloud1->points[0].z = 1;

cout << "cloud1 size " << cloud1->points.size()<<endl;

2.模擬生成旋轉矩陣

2.模擬生成旋轉矩陣

```c++
//模擬一個旋轉矩陣,為了簡單,這裡只是用一個,每次迭代都使用這個矩陣,效果是x方向一次增加1個單位長度
//我們知道旋轉矩陣形式如下[ R t
0 1] 下一篇文章會講解一下這些的由來
Eigen::Matrix4f transform_1 ;
transform_1 << 1 , 0 , 0 , 1 ,
0 , 1 , 0 , 0 ,
0 , 0 , 1 , 0 ,
0 , 0 , 0 , 1 ;
cout << transform_1 <<endl;

3.接下來會用來 Register模塊中的transforms函數來實現點的轉變

```c++ //將矩陣進行變化
pcl::PointCloud::Ptr cloud2(new pcl::PointCloud);
pcl::transformPointCloud (cloud1, cloud2, transform_1);
cout << "original cloud1 points "<< cloud1->points[0].x<<" "<points[0].y <<"    "<points[0].z<points[0].x<<" "<points[0].y <<"    "<points[0].z<<endl;
cout<<"----------------------------------------"<<endl;

吐槽:不知道為啥B乎每次都把我們格式弄壞了。。。

4.最後會用到Visualization模塊中的PCLVisualizer類顯示窗口

pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer ("3D Viewer"));
viewer->setBackgroundColor (0, 0, 0);
viewer->addText("Trajector", 10, 10, "v1 text");
viewer->addCoordinateSystem (1.0);
viewer->initCameraParameters ();
int line_numeber = 0;
char str[25];//這一個的作用是為了下面給每條線段 1 個唯一的id符,不然的畫只能畫出一條線

while(!viewer->wasStopped()){

viewer->spinOnce (1000);//這一句很重要,一開始沒有寫這一句,導致窗口一直沒有顯示,用於更新屏幕
line_numeber++;//依次增加,從而實現id號的不同
sprintf(str, "%d", line_numeber);//將數字轉化為字元串,addLine需要,addLine函數定義在下面
viewer->addLine<pcl::PointXYZ> (cloud1->points[0], cloud2->points[0], str);
*cloud1 = *cloud2;//將上一步的點雲給另外一個
pcl::transformPointCloud (*cloud1, *cloud2, transform_1);
//cout語句用於測試
cout << "cloud1 points "<< cloud1->points[0].x<<" "<<cloud1->points[0].y <<" "<<cloud1->points[0].z<<endl;
cout << "cloud1 points "<< cloud2->points[0].x<<" "<<cloud2->points[0].y <<" "<<cloud2->points[0].z<<endl;
cout<<"----------------------------------------"<<endl;
}

5.最後把頭文件給你就組成完整的程序了

#include <iostream>
#include<pcl/visualization/pcl_visualizer.h>
#include<pcl/registration/transforms.h> #include<stdio.h> //這兩個std文件沒有作用,因為一開始想用到itoa(),將整形轉化為字元的函數,後來發現這
#include <stdlib.h>//這個函數只有在window下面才存在
using namespace std;

注意點:

1.

void pcl::visualization::PCLVisualizer::spinOnce(int time =1 ; bool force_redraw = false )

Spin once method. Calls the interactor and updates the screen once.

  • Parameters

[in] time- How long (in ms) should the visualization loop be allowed to run.

[in] force_redraw- if false it might return without doing anything if the interactors framerate does not require a redraw yet.

while(!viewer->wasStopped()){
// viewer->spinOnce (100);
}

viewer->spinOnce (100);一定要加這一句,否則什麼現象也沒有

2.

bool pcl::visualization::PCLVisualizer::addLine(const P1 & pt1, const P2 & ptr2,const std::string& id ="line",int viewpoint = 0 )

Add a line segment from two points.
  • Parameters

[in]pt1the first (start) point on the line

[in]pt2the second (end) point on the line [in]idthe line id/name (default: "line") [in]viewport(optional) the id of the new viewport (default: 0) Note:每一條線都需要有自己的id號

總結:還是要多多自己敲代碼,複製粘貼一時爽,真定編碼火葬場~~~B乎的格式和Typora很不一樣....,還是CSDN好。


推薦閱讀:
相關文章