シリーズ記事の目次
第 1 章: PCL による線分点群の生成
第 2 章: PCL による円筒点群の作成
序文
点群ライブラリ (PCL) は、独立した大規模なオープン 2D/3D 画像および点群処理プロジェクトです。PCL は強力ですが、点群、特に線分、球、立方体、円柱などの一般的な点群を作成する機能は含まれていません。代わりに、視覚化クラスにいくつかの一般的な幾何学的形状のみが含まれています。 as : 線分、球、立方体などは点群データとして転送できないので、自分で書くつもりです 今回は三角面点群の作成についての記事です。
1. 三角面とは何ですか?
これは主に三角点群と区別するために私が勝手につけた名前で、簡単に言うと、与えられた空間内にある同一線上にないランダムな 3 次元の 3 点と、それら 3 点によって形成されるランダムに生成された多数の三角形のことです。 、点群に塗りつぶされます。
2. 三角形面点群の作成手順
1. ライブラリをインポートする
PCL 環境の構成については、「Windows システムで 5 分で PCL (デバッグとリリース) を構成する」を参照してください。
コードは以下のように表示されます:
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/visualization/pcl_visualizer.h>
2. 三角形表面点群の作成
- 3 つの入力点が同一線上にあるかどうかを確認します
- 三角形の面点群を生成する
- 目視による検証
キーファンクションコードは次のとおりです
//判断三个空间点是否共线
//param[in] p1, p2, p3: 输入的三个空间点
//param[out] bool:是否共线
bool arePointsCollinear(const pcl::PointXYZ& p1, const pcl::PointXYZ& p2, const pcl::PointXYZ& p3) {
// 计算两个向量
pcl::PointXYZ v1(p2.x - p1.x, p2.y - p1.y, p2.z - p1.z);
pcl::PointXYZ v2(p3.x - p1.x, p3.y - p1.y, p3.z - p1.z);
// 计算两个向量的叉乘
pcl::PointXYZ cross_product;
cross_product.x = v1.y * v2.z - v1.z * v2.y;
cross_product.y = v1.z * v2.x - v1.x * v2.z;
cross_product.z = v1.x * v2.y - v1.y * v2.x;
// 如果叉乘结果为零向量,则说明三个点共线
return cross_product.x == 0 && cross_product.y == 0 && cross_product.z == 0;
}
//根据圆柱面参数创建空间任意圆柱面点云
//param[in] p1, p2, p3: 输入的三个空间点
//param[in] num_points:随机点的数量
//param[out] cloud:PCD格式的点云文件
pcl::PointCloud<pcl::PointXYZ>::Ptr generateTrianglePointCloud(const pcl::PointXYZ& p1, const pcl::PointXYZ& p2, const pcl::PointXYZ& p3, int num_points)
{
// 创建一个点云对象
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
// 填充三角形内的点
for (int i = 0; i < num_points; i++)
{
float u = static_cast<float>(rand()) / RAND_MAX; // 在[0, 1]范围内生成随机数
float v = static_cast<float>(rand()) / RAND_MAX; // 在[0, 1]范围内生成随机数
if (u + v > 1.0)
{
u = 1.0 - u;
v = 1.0 - v;
}
float w = 1.0 - u - v;
pcl::PointXYZ point;
point.x = u * p1.x + v * p2.x + w * p3.x;
point.y = u * p1.y + v * p2.y + w * p3.y;
point.z = u * p1.z + v * p2.z + w * p3.z;
cloud->push_back(point);
}
return cloud;
}
主な関数コードは次のとおりです
int main()
{
// 随机定义四个三维点
pcl::PointXYZ p1(1,4,7);
pcl::PointXYZ p2(3,3,3);
pcl::PointXYZ p3(8,3.2,0);
// 检查是否共线
if (arePointsCollinear(p1, p2, p3)) {
std::cout << "警告:三个点共线!" << std::endl;
return 0;
}
// 生成三角形面点云
pcl::PointCloud<pcl::PointXYZ>::Ptr triangle1_cloud = generateTrianglePointCloud(p1, p2, p3, 10000);
// 创建可视化对象并添加点云
pcl::visualization::PCLVisualizer viewer("Point Cloud Viewer");
viewer.setBackgroundColor(0, 0, 0);
viewer.addPointCloud<pcl::PointXYZ>(triangle1_cloud, "cloud");
// 保存点云数据
pcl::io::savePCDFileASCII("triangle1_cloud.pcd", *triangle1_cloud);
// 设置点云颜色为红色
viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 1.0, 0.0, 0.0, "cloud");
// 设置点云大小
viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "cloud");
// 等待可视化窗口关闭
while (!viewer.wasStopped())
{
viewer.spinOnce();
}
return 0;
}
可視化結果は図の通りです。
効果は悪くありません。ポイントが多すぎる、または少なすぎると感じる場合は、自分でポイント数を設定できます~
要約する
3 つの点が同一線上にない限り、対応する三角形表面点群を作成できます。役に立った場合は、必ず 3 回接続してください。転載する場合は出典を明記してください。