PCL交互选择ROI区域
创始人
2024-02-02 00:05:10
0

PCL的配置和如何配准点云可见博主之前的博客

win10环境下PCL安装和配置回顾(一)_竹叶青lvye的博客-CSDN博客_pcl win10

win10环境下PCL安装和配置回顾(二)_竹叶青lvye的博客-CSDN博客_win10 安装pcl

PCL - 3D点云配准(registration)介绍_竹叶青lvye的博客-CSDN博客

其它的PCL方面常用的一些点云算法,可自己花时间去研读,这边想去简单实现下ROI区域交互式的选择,接下还是延续前面几篇博客所用的PCL的配置。

一. 生成测试点云

这边点云选择

mirrors / pointcloudlibrary / data · GitCode

里面的learn5.pcd点云

 这里自定义了一个旋转平移矩阵(将点云通过这个变换为另外一个点云),详细见如下代码:

#include   // for pcl::make_shared
#include 
#include 
#include 
#include #include 
#include #include #include 
#include 
#include #include #include using pcl::visualization::PointCloudColorHandlerGenericField;
using pcl::visualization::PointCloudColorHandlerCustom;//convenient typedefs
typedef pcl::PointXYZ PointT;
typedef pcl::PointCloud PointCloud;
typedef pcl::PointNormal PointNormalT;
typedef pcl::PointCloud PointCloudWithNormals;int main()
{PointCloud::Ptr cloud_src(new PointCloud);PointCloud::Ptr cloud_tgt(new PointCloud);pcl::io::loadPCDFile("D:\\PCL\\data-master\\segmentation\\mOSD\\learn\\learn5.pcd", *cloud_src);Eigen::Matrix4f transform_1 = Eigen::Matrix4f::Identity();//定义绕X轴的旋转矩阵,并初始化为单位阵float theta = M_PI / 4; // The angle of rotation in radianstransform_1(0, 0) = std::cos(theta);transform_1(0, 1) = -sin(theta);transform_1(1, 0) = sin(theta);transform_1(1, 1) = std::cos(theta);transform_1(0, 3) = 0.7f;transform_1(1, 3) = 0.6f;transform_1(2, 3) = 1.2f;pcl::transformPointCloud(*cloud_src, *cloud_tgt, transform_1);std::cout << "cloud_src size: " << cloud_src->size() << std::endl;std::cout << "cloud_target size: " << cloud_tgt->size() << std::endl;pcl::visualization::PCLVisualizer* p;int vp_1, vp_2;p = new pcl::visualization::PCLVisualizer("view");PointCloudColorHandlerCustom src_h(cloud_src, 255, 0, 0);PointCloudColorHandlerCustom tgt_h(cloud_tgt, 0, 255, 0);p->addPointCloud(cloud_src, src_h, "vp1_src");p->addPointCloud(cloud_tgt, tgt_h, "vp1_target");p->spin();return (0);
}

 运行结果如下:

二. 交互点选

接下来在变换前的点云数据上点选一个ROI区域,代码如下:

#include   // for pcl::make_shared
#include 
#include 
#include 
#include #include 
#include #include #include 
#include 
#include #include #include 
#include 
#include 
#include #include using pcl::visualization::PointCloudColorHandlerGenericField;
using pcl::visualization::PointCloudColorHandlerCustom;//convenient typedefs
typedef pcl::PointXYZ PointT;
typedef pcl::PointCloud PointCloud;
typedef pcl::PointNormal PointNormalT;
typedef pcl::PointCloud PointCloudWithNormals;//Mutex 
boost::mutex cloud_mutex;struct callback_args
{PointCloud::Ptr clicked_points_3d;pcl::visualization::PCLVisualizer::Ptr viewerPtr;
};//点选函数
void pointPick_callback(const pcl::visualization::PointPickingEvent& event, void* args)
{struct callback_args* data = (struct callback_args*)args;if (event.getPointIndex() == -1){return;}//提取当前点PointT current_point;event.getPoint(current_point.x, current_point.y, current_point.z);data->clicked_points_3d->points.push_back(current_point);//显示当前点pcl::visualization::PointCloudColorHandlerCustom 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");cout << current_point << endl;
}int main()
{PointCloud::Ptr cloud_src(new PointCloud);PointCloud::Ptr cloud_tgt(new PointCloud);pcl::io::loadPCDFile("D:\\PCL\\data-master\\segmentation\\mOSD\\learn\\learn5.pcd", *cloud_src);Eigen::Matrix4f transform_1 = Eigen::Matrix4f::Identity();//定义绕X轴的旋转矩阵,并初始化为单位阵float theta = M_PI / 4; // The angle of rotation in radianstransform_1(0, 0) = std::cos(theta);transform_1(0, 1) = -sin(theta);transform_1(1, 0) = sin(theta);transform_1(1, 1) = std::cos(theta);transform_1(0, 3) = 0.7f;transform_1(1, 3) = 0.6f;transform_1(2, 3) = 1.2f;pcl::transformPointCloud(*cloud_src, *cloud_tgt, transform_1);std::cout << "cloud_src size: " << cloud_src->size() << std::endl;std::cout << "cloud_target size: " << cloud_tgt->size() << std::endl;pcl::visualization::PCLVisualizer* p;p = new pcl::visualization::PCLVisualizer("view");cloud_mutex.lock();    // for not overwriting the point cloudPointCloudColorHandlerCustom src_h(cloud_src, 0, 0, 255);PointCloudColorHandlerCustom tgt_h(cloud_tgt, 0, 255, 0);p->setBackgroundColor(0.5, 0.5, 0.1, 0); // 设置背景为深灰p->addPointCloud(cloud_src, src_h, "vp1_src");p->addPointCloud(cloud_tgt, tgt_h, "vp1_target");struct callback_args cb_args;PointCloud::Ptr clicked_points_3d(new PointCloud);cb_args.clicked_points_3d = clicked_points_3d;cb_args.viewerPtr = pcl::visualization::PCLVisualizer::Ptr(p);p->registerPointPickingCallback(pointPick_callback, (void*)&cb_args);cout << "->Shift + 鼠标左键选点,按 ‘Q’结束选点" << endl;p->spin();cout << "->选点结束" << endl;Eigen::Affine3f affine(transform_1);PointT conver_point = pcl::transformPoint(cb_args.clicked_points_3d->points[0], affine);std::cout << "use the affine to covert the point: " << std::endl;std::cout << conver_point << std::endl;cloud_mutex.unlock();while (!p->wasStopped()){p->spinOnce(100);boost::this_thread::sleep(boost::posix_time::microseconds(100000));}return (0);
}

运行程序,可看到如下先点选了蓝色点云上的一个角点,又鼠标点选了绿色点云上对应位置处的一角点。这个两个点云的点同时也在点云上show出来了。

 按了Q退出点选模式后,程序会将点云的绿色处的点去由变换矩阵变化下,算出来的值,可看到和上面鼠标点选的绿色点云的角点坐标是近似的。

 

三. 将点云上的ROI区域跟随目标的变换而变化,并在其变换后的点云数据上画出立体框

代码如下,在第一个点云上可以通过鼠标点选ROI区域,完毕后会在第二个点云上会产生一个ROI区域,可看到是跟随目标变化的。

#include   // for pcl::make_shared
#include 
#include 
#include 
#include #include 
#include #include #include 
#include 
#include #include #include 
#include 
#include 
#include #include #include using pcl::visualization::PointCloudColorHandlerGenericField;
using pcl::visualization::PointCloudColorHandlerCustom;//convenient typedefs
typedef pcl::PointXYZ PointT;
typedef pcl::PointCloud PointCloud;
typedef pcl::PointNormal PointNormalT;
typedef pcl::PointCloud PointCloudWithNormals;pcl::PointCloud::Ptr points;//Mutex 
boost::mutex cloud_mutex;
int count = 0;struct callback_args
{PointCloud::Ptr clicked_points_3d;PointCloud::Ptr clicked_points_3d_convert;pcl::visualization::PCLVisualizer::Ptr viewerPtr;Eigen::Affine3f affine;
};//点选函数
void pointPick_callback(const pcl::visualization::PointPickingEvent& event, void* args)
{count++;struct callback_args* data = (struct callback_args*)args;if (event.getPointIndex() == -1){return;}//提取当前点PointT current_point;event.getPoint(current_point.x, current_point.y, current_point.z);data->clicked_points_3d->points.push_back(current_point);//显示当前点pcl::visualization::PointCloudColorHandlerCustom 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");//添加点索引号PointT position(current_point.x, current_point.y + 0.01, current_point.z);data->viewerPtr->addText3D(std::to_string(count), position, 0.1, 1,0,0);data->viewerPtr->resetCameraViewpoint();cout << current_point << endl;PointT convert_point = pcl::transformPoint(current_point, data->affine);data->clicked_points_3d_convert->points.push_back(convert_point);if (count == 6){//方向包围盒OBBpcl::MomentOfInertiaEstimation  feature_extractor;feature_extractor.setInputCloud(data->clicked_points_3d);feature_extractor.compute();pcl::PointXYZ min_point_OBB;pcl::PointXYZ max_point_OBB;pcl::PointXYZ position_OBB;Eigen::Matrix3f rotational_matrix_OBB;feature_extractor.getOBB(min_point_OBB, max_point_OBB, position_OBB, rotational_matrix_OBB);Eigen::Vector3f position(position_OBB.x, position_OBB.y, position_OBB.z);Eigen::Quaternionf quat(rotational_matrix_OBB);data->viewerPtr->addCube(position, quat, max_point_OBB.x - min_point_OBB.x, max_point_OBB.y - min_point_OBB.y, max_point_OBB.z - min_point_OBB.z, "OBB");data->viewerPtr->setShapeRenderingProperties(pcl::visualization::PCL_VISUALIZER_REPRESENTATION, pcl::visualization::PCL_VISUALIZER_REPRESENTATION_WIREFRAME, "OBB");feature_extractor.setInputCloud(data->clicked_points_3d_convert);feature_extractor.compute();feature_extractor.getOBB(min_point_OBB, max_point_OBB, position_OBB, rotational_matrix_OBB);Eigen::Vector3f positionConvert(position_OBB.x, position_OBB.y, position_OBB.z);Eigen::Quaternionf quatConvert(rotational_matrix_OBB);data->viewerPtr->addCube(positionConvert, quatConvert, max_point_OBB.x - min_point_OBB.x, max_point_OBB.y - min_point_OBB.y, max_point_OBB.z - min_point_OBB.z, "OBBConvert");data->viewerPtr->setShapeRenderingProperties(pcl::visualization::PCL_VISUALIZER_REPRESENTATION, pcl::visualization::PCL_VISUALIZER_REPRESENTATION_WIREFRAME, "OBBConvert");}
}int main()
{PointCloud::Ptr cloud_src(new PointCloud);PointCloud::Ptr cloud_tgt(new PointCloud);pcl::io::loadPCDFile("D:\\PCL\\data-master\\segmentation\\mOSD\\learn\\learn5.pcd", *cloud_src);Eigen::Matrix4f transform_1 = Eigen::Matrix4f::Identity();//定义绕X轴的旋转矩阵,并初始化为单位阵float theta = M_PI / 4; // The angle of rotation in radianstransform_1(0, 0) = std::cos(theta);transform_1(0, 1) = -sin(theta);transform_1(1, 0) = sin(theta);transform_1(1, 1) = std::cos(theta);transform_1(0, 3) = 0.7f;transform_1(1, 3) = 0.6f;transform_1(2, 3) = 1.2f;pcl::transformPointCloud(*cloud_src, *cloud_tgt, transform_1);std::cout << "cloud_src size: " << cloud_src->size() << std::endl;std::cout << "cloud_target size: " << cloud_tgt->size() << std::endl;pcl::visualization::PCLVisualizer* p;p = new pcl::visualization::PCLVisualizer("view");cloud_mutex.lock();    // for not overwriting the point cloudPointCloudColorHandlerCustom src_h(cloud_src, 0, 0, 255);PointCloudColorHandlerCustom tgt_h(cloud_tgt, 0, 255, 0);p->setBackgroundColor(0.5, 0.5, 0.1, 0); // 设置背景为深灰p->addPointCloud(cloud_src, src_h, "vp1_src");p->addPointCloud(cloud_tgt, tgt_h, "vp1_target");struct callback_args cb_args;PointCloud::Ptr clicked_points_3d(new PointCloud);PointCloud::Ptr clicked_points_3d_convert(new PointCloud);cb_args.clicked_points_3d = clicked_points_3d;cb_args.clicked_points_3d_convert = clicked_points_3d_convert;cb_args.viewerPtr = pcl::visualization::PCLVisualizer::Ptr(p);//cb_args.viewerPtr->addCoordinateSystem(0.5);PointT position(0, 0, 0);PointT positionx(1, 0, 0);PointT positiony(0, 1, 0);PointT positionz(0, 0, 1);cb_args.viewerPtr->addArrow(positionx, position,0,0,1,false, "x");cb_args.viewerPtr->addArrow(positiony, position, 0,1, 0,false, "y");cb_args.viewerPtr->addArrow(positionz, position, 1, 0, 0,false, "z");cb_args.viewerPtr->addText3D("x", positionx, 0.2, 0, 0, 1,"x1");cb_args.viewerPtr->addText3D("y", positiony, 0.2, 0, 1, 0,"y1");Eigen::Affine3f affine(transform_1);cb_args.affine = affine;p->registerPointPickingCallback(pointPick_callback, (void*)&cb_args);cout << "->Shift + 鼠标左键选点,按 ‘Q’结束选点" << endl;p->spin();cout << "->选点结束" << endl;PointT conver_point = pcl::transformPoint(cb_args.clicked_points_3d->points[0], affine);std::cout << "use the affine to covert the point: " << std::endl;std::cout << conver_point << std::endl;cloud_mutex.unlock();while (!p->wasStopped()){p->spinOnce(100);boost::this_thread::sleep(boost::posix_time::microseconds(100000));}return (0);
}

执行效果如下:

 可看到,此段代码实现了ROI区域跟随点云变化的功能。

上一篇:Nginx入门笔记

下一篇:BI-SQL丨SNAPSHOT

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
一帆风顺二龙腾飞三阳开泰祝福语... 本篇文章极速百科给大家谈谈一帆风顺二龙腾飞三阳开泰祝福语,以及一帆风顺二龙腾飞三阳开泰祝福语结婚对应...
美团联名卡审核成功待激活(美团... 今天百科达人给各位分享美团联名卡审核成功待激活的知识,其中也会对美团联名卡审核未通过进行解释,如果能...