pclポイントクラウドの視覚化
視覚化は、コンピュータグラフィックスと画像処理技術を使用してデータをグラフィックスまたは画像に変換し、画面に表示してインタラクティブに処理する理論、方法、および技術です。
PCLのpcl_visualizationライブラリは、視覚化関連のデータ構造とコンポーネントを提供します。これらは主に、他のモジュールアルゴリズムによって処理された結果を視覚化するために使用され、ユーザーに直感的にフィードバックできます。これは、pcl_common、pcl_range_image、pcl_kdtree、pcl_IOモジュール、およびVTK外部オープンソース視覚化ライブラリに依存しています。一般的に使用される2つの視覚化クラスを以下に示します。
分類一:pcl :: visualization :: PCLVisualizer
PCLVisualizerは、3D点群を視覚化するためのPCLのメインクラスです。さまざまな3Dオブジェクトの追加やインタラクションの実現などの内部実現は、他のクラスよりも完全です。
基本的な表示機能:点群の表示、グリッド、色の設定、線の接続
#include <pcl/io/pcd_io.h>
#include <pcl/io/ply_io.h>
#include <pcl/point_types.h>
// 包含相关头文件
#include <pcl/visualization/pcl_visualizer.h>
typedef pcl::PointXYZ PointT;
int main()
{
// 读取点云
pcl::PointCloud<PointT>::Ptr cloud1(new pcl::PointCloud<PointT>);
pcl::io::loadPCDFile("0010.pcd", *cloud1);
pcl::PointCloud<PointT>::Ptr cloud2(new pcl::PointCloud<PointT>);
pcl::io::loadPCDFile("0020.pcd", *cloud2);
// 定义对象
pcl::visualization::PCLVisualizer viewer;
//设置背景颜色,默认黑色
//viewer.setBackgroundColor(100, 100, 100); // rgb
// --- 显示点云数据 ----
// "cloud1" 为显示id,默认cloud,显示多个点云时用默认会报警告。
pcl::visualization::PointCloudColorHandlerCustom<PointT> green(cloud2, 0, 255, 0); // rgb
viewer.addPointCloud(cloud1, green, "cloud1");
pcl::visualization::PointCloudColorHandlerCustom<PointT> red(cloud2, 255, 0, 0); // rgb
// 将点云设置颜色,默认白色
viewer.addPointCloud(cloud2, red, "cloud2");
// 将两个点连线
PointT temp1 = cloud1->points[0];
PointT temp2 = cloud1->points[1000];
//viewer.addLine(temp1, temp2, "line0");
// 同样可以设置线的颜色,蓝色
viewer.addLine(temp1, temp2, 0, 0, 255, "line0");
// --- 显示网格数据 ---
pcl::PolygonMesh mesh;
pcl::io::loadPLYFile("read.ply", mesh);
viewer.addPolygonMesh(mesh);
// 开始显示2种方法,任选其一
// 1. 阻塞式
viewer.spin();
// 2. 非阻塞式
while (!viewer.wasStopped())
{
viewer.spinOnce(100);
boost::this_thread::sleep(boost::posix_time::microseconds(100000));
// 可添加其他操作
}
system("pause");
return 0;
}
レンダリング
高度な機能:インタラクション、表示領域のセグメンテーションのためのコールバック関数を設定します
キーイベント
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/pcl_visualizer.h>
// 回掉函数所用数据结构
struct callback_args {
bool *isShow;
pcl::PointCloud<pcl::PointXYZ>::Ptr orgin_points;
pcl::visualization::PCLVisualizer::Ptr viewerPtr;
};
// 按键事件回掉函数
void kb_callback(const pcl::visualization::KeyboardEvent& event, void* args)
{
if (event.keyDown() && event.getKeyCode() == 'a')
{
std::cout << "a has pressed" << std::endl;
struct callback_args* data = (struct callback_args *)args;
if (*(data->isShow))
{
data->viewerPtr->removePointCloud("cloud");
*(data->isShow) = false;
std::cout << "remove" << std::endl;
}
else {
data->viewerPtr->addPointCloud(data->orgin_points, "cloud");
*(data->isShow) = true;
std::cout << "add" << std::endl;
}
}
}
int main(int argc, char** argv)
{
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::io::loadPCDFile("bunny.pcd", *cloud);
pcl::console::print_highlight("load cloud !\n");
// 定义对象
pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer);
viewer->addPointCloud(cloud, "cloud");
// 初始化参数
bool isShow = true;
struct callback_args kb_args;
kb_args.isShow = &isShow;
kb_args.orgin_points = cloud;
kb_args.viewerPtr = viewer;
// 设置回掉函数
viewer->registerKeyboardCallback(kb_callback, (void*)&kb_args);
viewer->spin();
return 0;
}
このコードは、aを押して表示をクリアし、次にそれを押して再表示することを実装します。
主にコールバック関数の実装を設定します
viewer->registerKeyboardCallback(kb_callback, (void*)&kb_args);
kb_callbackは特定の機能を実装します。
クリックイベント
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/visualization/pcl_visualizer.h>
struct callback_args {
// structure used to pass arguments to the callback function
pcl::PointCloud<pcl::PointXYZ>::Ptr clicked_points_3d;
pcl::visualization::PCLVisualizer::Ptr viewerPtr;
};
void pp_callback(const pcl::visualization::PointPickingEvent& event, void* args)
{
struct callback_args* data = (struct callback_args *)args;
if (event.getPointIndex() == -1)
return;
int index = event.getPointIndex();
std::cout << "index: " << index << std::endl;
pcl::PointXYZ current_point;
event.getPoint(current_point.x, current_point.y, current_point.z);
data->clicked_points_3d->points.push_back(current_point);
// Draw clicked points in red:
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> red(data->clicked_points_3d, 255, 0, 0);
data->viewerPtr->removePointCloud("clicked_points");
data->viewerPtr->addPointCloud(data->clicked_points_3d, red, "clicked_points");
data->viewerPtr->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 10, "clicked_points");
std::cout << current_point.x << " " << current_point.y << " " << current_point.z << std::endl;
}
int main(int argc, char** argv)
{
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::io::loadPCDFile("bunny.pcd", *cloud);
pcl::console::print_highlight("load cloud !\n");
pcl::visualization::PCLVisualizer viewer;
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> green(cloud, 0, 255, 0);
viewer.addPointCloud(cloud, green, "cloud");
// Add point picking callback to viewer:
struct callback_args cb_args;
pcl::PointCloud<pcl::PointXYZ>::Ptr clicked_points_3d(new pcl::PointCloud<pcl::PointXYZ>);
cb_args.clicked_points_3d = clicked_points_3d;
cb_args.viewerPtr = pcl::visualization::PCLVisualizer::Ptr(&viewer);
viewer.registerPointPickingCallback(pp_callback, (void*)&cb_args);
pcl::console::print_highlight("Shift+click on three floor points, then press 'Q'...\n");
// Spin until 'Q' is pressed:
viewer.spin();
system("pause");
return 0;
}
レンダリング
shfitを押してポイントをクリックすると、座標が印刷されます。
地域選択イベント
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/visualization/pcl_visualizer.h>
struct callback_args{
// structure used to pass arguments to the callback function
pcl::PointCloud<pcl::PointXYZ>::Ptr orgin_points;
pcl::PointCloud<pcl::PointXYZ>::Ptr chosed_points_3d;
pcl::visualization::PCLVisualizer::Ptr viewerPtr;
};
void ap_callback(const pcl::visualization::AreaPickingEvent& event, void* args)
{
struct callback_args* data = (struct callback_args *)args;
std::vector<int> indiecs;
if (!event.getPointsIndices(indiecs))
return;
for (int i = 0; i < indiecs.size(); ++i)
{
data->chosed_points_3d->push_back(data->orgin_points->points[indiecs[i]]);
}
// Draw clicked points in red:
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> red(data->chosed_points_3d, 255, 0, 0);
data->viewerPtr->removePointCloud("chosed_points");
data->viewerPtr->addPointCloud(data->chosed_points_3d, red, "chosed_points");
data->viewerPtr->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 5, "chosed_points");
std::cout << "selected " << indiecs.size() << " points , now sum is " << data->chosed_points_3d->size() << std::endl;
}
int main(int argc, char** argv)
{
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::io::loadPCDFile("rabbit.pcd", *cloud);
pcl::console::print_highlight("load cloud !\n");
pcl::visualization::PCLVisualizer viewer;
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> green(cloud, 0, 255, 0);
viewer.addPointCloud(cloud, green, "cloud");
// Add point picking callback to viewer:
struct callback_args cb_args;
cb_args.orgin_points = cloud;
pcl::PointCloud<pcl::PointXYZ>::Ptr chosed_points_3d(new pcl::PointCloud<pcl::PointXYZ>);
cb_args.chosed_points_3d = chosed_points_3d;
cb_args.viewerPtr = pcl::visualization::PCLVisualizer::Ptr(&viewer);
viewer.registerAreaPickingCallback(ap_callback, (void*)&cb_args);
pcl::console::print_highlight("press x enter slected model, then press 'qQ'...\n");
// Spin until 'Q' is pressed:
viewer.spin();
system("pause");
return 0;
}
表示領域のセグメンテーション
pclは、表示領域を(xmin、ymin)から(xmax、ymax)の長方形の領域に分割でき、範囲は(0、1)です。左下(0,0)、右上(1,1)。以前のすべての機能は、エリア表示をサポートしています。
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
// 包含相关头文件
#include <pcl/visualization/pcl_visualizer.h>
typedef pcl::PointXYZ PointT;
int main()
{
// 读取点云
pcl::PointCloud<PointT>::Ptr cloud(new pcl::PointCloud<PointT>);
pcl::io::loadPCDFile("read.pcd", *cloud);
// 定义对象
pcl::visualization::PCLVisualizer viewer;
int v1(1); // viewport
viewer.createViewPort(0.0, 0.0, 0.5, 1.0, v1);
viewer.setBackgroundColor(255, 0, 0, v1);
viewer.addPointCloud(cloud, "cloud1", v1);;
int v2(2);// viewport
viewer.createViewPort(0.5, 0.0, 1.0, 1.0, v1);
viewer.setBackgroundColor(0, 255, 0, v2);
viewer.addPointCloud(cloud, "cloud2", v2);;
viewer.spin();
system("pause");
return 0;
}
クラス2:pcl :: visualization :: CloudViewer
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
// 包含相关头文件
#include <pcl/visualization/cloud_viewer.h>
typedef pcl::PointXYZ PointT;
int main()
{
// 读取点云
pcl::PointCloud<PointT>::Ptr cloud(new pcl::PointCloud<PointT>);
pcl::io::loadPCDFile("read.pcd", *cloud);
pcl::visualization::CloudViewer viewer("simple cloud viewer");
viewer.showCloud(cloud);
while (!viewer.wasStopped())
{
// todo::
}
system("pause");
return 0;
}