• 在Qt的点云显示窗口中添加坐标轴C++


    通过摸索整理了三个方法:

    一、方法1://不推荐,但可以参考

    1、通过pcl的compute3DCentroid()方法计算点云的中心点坐标;

    函数原型如下:

    compute3DCentroid (const pcl::PointCloud<PointT> &cloud, Eigen::Vector4f &centroid);

    2、通过vtk的addCoordinareSystem()在指定位置放一个坐标系;

    函数原型如下:

    addCoordinareSystem(double scale, float x, float y, float z,const std::string &id = "reference",int viewport = 0);

     这里的scale可以指定坐标轴的尺寸,但是点云有时候比较大,坐标轴也很大的时候会看起来很奇怪,甚至遮挡住部分点云,,所以我想把这个坐标轴放在右下角,就像cloudcompare软件中效果一样,于是此处增加:

    3、通过vtk的createViewPort()新建一个窗口在右下角,然后把点云放在这个小窗口里

    函数原型如下:

    createViewPort (double xmin, double ymin, double xmax, double ymax, int &viewport);
    

    此处前四个参数都表示viewer窗口中的所在位置在全图的比例,最大值为1.0;

    4、完整代码如下:

    1. #include <pcl/common/centroid.h> //计算点云中心的头文件
    2. //其它相关环境的头文件自行补充
    3. //初始化一个viewer
    4. pcl::visualization::PCLVisualizer::Ptr viewer;
    5. //初始化一个点云
    6. pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
    7. //加载点云文件
    8. if(pcl::io::loadPCDFile("cloud.pcd",*cloud)==-1)
    9. {
    10. //此处cloud.pcd是你的点云文件
    11. }
    12. Eigen::Vector4f center;
    13. pcl::compute3DCentroid(*cloud,center); //计算中心点坐标,保存到center
    14. int v1 = 0;
    15. viewer->createViewPort(0.8,0.0,1.0,0.2,v1); //在viewer中新建一个窗口
    16. viewer->addCoordinateSystem(1.0,center[0],center[1],center[2],"v1",v1); //在小窗中显示坐标轴

    想法很丰满,显示很骨感,这个方法的效果并不是很好,首先一点是通过createViewPort创造的小窗背景是黑色的,不是透明的,拖动旋转大窗口的点云时可以发现小窗部分会遮住它,就像是ps里图层的概念...

    二、方法2://不推荐,但可以参考

    在Qt中使用vtkRenderer的窗口显示点云时,vtk有一个专用的函数添加坐标系:

    1. #include <vtkOrientationMarkerWidget.h>
    2. viewer->addOrientationMarkerWidgetAxes(ui->widget_opengl->GetInteractor());
    3. //这里的widget_opengl是我显示点云的窗口名称

    此处窗口的创建与使用可参考另一篇博客:

    http://t.csdn.cn/SpwoF

    通过此方法可以最快速得到一个坐标系,背景透明的,在显示窗口的角落,但是这个坐标系是可以被鼠标拖动的,很容易误触!有兴趣的朋友可以试一下效果

    不多时便找到了更好的解决办法:

    三、方法3:推荐

    通过自定义坐标系再加入到显示点云的窗口中,并且禁止鼠标改变坐标系窗口的位置,就可以实现和cloudcompare几乎一致的效果了

    将如下代码加入到点云显示的部分即可:

    (QT中通过widget组件显示点云窗口的方法参考http://t.csdn.cn/SpwoF

    1. #include <vtkOrientationMarkerWidget.h>
    2. #include <vtkAxesActor.h>
    3. vtkAxesActor* axes = vtkAxesActor::New();
    4. axes->SetPosition(0,0,0); //坐标系的原点
    5. axes->SetTotalLength(1,1,1); //轴长
    6. axes->SetShaftType(1); //旋转轴的类型:圆柱体、线、或者自定义
    7. axes->SetCylinderRadius(0.02);
    8. vtkOrientationMarkerWidget* widget = vtkOrientationMarkerWidget::New();
    9. widget->SetOutlineColor(1,1,1);
    10. widget->SetOrientationMarker(axes);
    11. widget->SetInteractor(ui->widget_opengl->GetInteractor());//加入交互
    12. widget->SetViewport(0.0,0.0,0.3,0.3); //设置显示位置
    13. widget->SetEnabled(true);
    14. widget->SetInteractive(false); //禁止拖动坐标系位置

  • 相关阅读:
    阿里云武林头条活动分享
    C语言中,字节对齐是一种重要的内存管理概念
    【Javascript】DOM文档
    单元测试啊
    【Vue3从零开始-实战】S14:详情页回退事件及路由参数的传递获取数据
    webpack 高级
    3.4JavaScript网页编程——JS高级(可以不看)
    [附源码]计算机毕业设计贵港高铁站志愿者服务平台
    在EXCEL中快速浏览GIS文件的属性和图形信息,独家发布
    阿里云短信服务设置操作项目
  • 原文地址:https://blog.csdn.net/qq_19319481/article/details/132697091