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区域,可看到是跟随目标变化的。
#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