ui添加
添加connect连接槽函数
connect(m_UI->actionLinePathFit, &QAction::triggered, this, &MainWindow::doActionLinePathFit);
添加函数声明
void doActionLinePathFit(); //直线轨迹
添加PCL头文件
#include <pcl/keypoints/uniform_sampling.h> // 均匀采样
#include <pcl/sample_consensus/ransac.h> //随机采样一致性算法实现
#include <pcl/sample_consensus/sac_model_line.h> //直线采样
添加函数实现
void MainWindow::doActionLinePathFit()
{
if (getSelectedEntities().size() != 1)
{
ccLog::Print(QStringLiteral("只能选择一个点云实体"));
return;
}
ccHObject* entity = getSelectedEntities()[0];
ccPointCloud* ccCloud = ccHObjectCaster::ToPointCloud(entity);
// ---------------------------读取数据到PCL----------------------------------
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
cloud->resize(ccCloud->size());
for (int i = 0; i < cloud->size(); ++i)
{
const CCVector3* point = ccCloud->getPoint(i);
cloud->points[i].x = point->x;
cloud->points[i].y = point->y;
cloud->points[i].z = point->z;
}
//----------------------------- 空间直线拟合 -----------------------------
pcl::SampleConsensusModelLine<pcl::PointXYZ>::Ptr model_line(new pcl::SampleConsensusModelLine<pcl::PointXYZ>(cloud)); //指定拟合点云与几何模型
pcl::RandomSampleConsensus<pcl::PointXYZ> ransac(model_line); //创建随机采样一致性对象
ransac.setDistanceThreshold(1); //设置容忍范围,也就是阈值
ransac.setMaxIterations(10000); //最大迭代次数
ransac.computeModel(); //执行RANSAC空间直线拟合
vector<int> inliers; //存储内点索引的向量
ransac.getInliers(inliers); //提取内点对应的索引
/// 根据索引提取内点
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_line(new pcl::PointCloud<pcl::PointXYZ>);
pcl::copyPointCloud<pcl::PointXYZ>(*cloud, inliers, *cloud_line);
/// 模型参数
Eigen::VectorXf coefficient;
ransac.getModelCoefficients(coefficient);
ccLog::Print(QStringLiteral("直线点向式方程为\n(x -%1) / %2 = (y - %3) / %4 = (z - %5) / %6").arg(coefficient[0]).arg(coefficient[1]).arg(coefficient[2]).arg(coefficient[3]).arg(coefficient[4]).arg(coefficient[5]));
// ------------------------PCL->CloudCompare--------------------------------
if (!cloud_line->empty())
{
ccPointCloud* Path = new ccPointCloud(QString("Path"));
for (int i = 0; i < cloud_line->size(); ++i)
{
double x = cloud_line->points[i].x;
double y = cloud_line->points[i].y;
double z = cloud_line->points[i].z;
Path->addPoint(CCVector3(x, y, z));
}
Path->setColor(ccColor::Rgba(rand() % 255, rand() % 255, 0, 255));
Path->showColors(true);
if (ccCloud->getParent())
{
ccCloud->getParent()->addChild(Path);
}
ccCloud->setEnabled(false);
addToDB(Path);
ccPointCloud* PointCloudafterPCL = new ccPointCloud(QString("PCL计算后的点云"));
for (int i = 0; i < cloud->size(); ++i)
{
double x = cloud->points[i].x;
double y = cloud->points[i].y;
double z = cloud->points[i].z;
PointCloudafterPCL->addPoint(CCVector3(x, y, z));
}
PointCloudafterPCL->setColor(ccColor::Rgba(rand() % 255, rand() % 255, 0, 255));
PointCloudafterPCL->showColors(true);
if (ccCloud->getParent())
{
ccCloud->getParent()->addChild(PointCloudafterPCL);
}
ccCloud->setEnabled(false);
addToDB(PointCloudafterPCL);
refreshAll();
updateUI();
}
else
{
ccCloud->setEnabled(true);
// Display a warning message in the console
dispToConsole("Warning: example shouldn't be used as is", ccMainAppInterface::WRN_CONSOLE_MESSAGE);
}
}
结果显示1
主视图
左视图
显示结果2
主视图
左视图