zoukankan      html  css  js  c++  java
  • OpenCV 3.2 Viz 3D可视化

    该可视化模块提供了坐标系变化,3D动画等功能

    最简单的显示坐标系

      viz::Viz3d window("window");
      window.showWidget("Coordinate", viz::WCoordinateSystem());
      window.spin();

    其中spin()函数开启一个event loop永远循环,spinOnce(int time = 1, bool redraw = true)表示event loop循环time时间。通常将与视图的交互放在一个循环中:

      while(!window.wasStopped())
      {
        // interact with window
        window.spinOnce(1, true);
      }

    3D姿态通常通过仿射变换Affine3f来指定, 可以利用罗德里格斯公式将较为直观的旋转向量转换为旋转矩阵,带入放射变化中:

    #include <iostream>
    #include <opencv2/viz.hpp>
    #include <opencv2/highgui.hpp>
    #include <opencv2/calib3d.hpp>
    
    using namespace std;
    using namespace cv;
    
    int main()
    {
      viz::Viz3d window("window");
      window.showWidget("Coordinate", viz::WCoordinateSystem());
      
      viz::WPlane plane(Size2d(2,2), viz::Color::white());
      plane.setRenderingProperty(viz::LINE_WIDTH, 5);
      plane.setPose(Affine3f());
      window.showWidget("plane", plane);
      
      Mat rvec = Mat::zeros(1, 3, CV_32F);
      while(!window.wasStopped())
      {
        rvec.at<float>(0,0) = 0.f;
        rvec.at<float>(0,1) += CV_PI*0.01f;
        rvec.at<float>(0,2) = 0.f;
        Mat rmat;
        Rodrigues(rvec, rmat);
        Affine3f pose(rmat, Vec3f(0,0,0));
        window.setWidgetPose("plane", pose);
        window.spinOnce(1, true);
      }
    }

    实现了一个xy平面上,白色的2*2大小平面绕y轴旋转的动画

    Viz模块中主要使用Affine3f仿射变换来处理空间转换的过程,下面实例实现3D点云在世界坐标系下,绕相机坐标系z轴旋转:

    #include <iostream>
    #include <fstream>
    #include <opencv2/viz.hpp>
    #include <opencv2/highgui.hpp>
    #include <opencv2/calib3d.hpp>
    
    using namespace std;
    using namespace cv;
    
    
    // load a ply file
    // http://graphics.stanford.edu/data/3Dscanrep/
    Mat cvcloud_load()
    {
        Mat cloud(1, 1889, CV_32FC3);
        ifstream ifs("/home/shang/Desktop/bunny.ply");
    
        string str;
        for(size_t i = 0; i < 12; ++i)
            getline(ifs, str);
    
        Point3f* data = cloud.ptr<cv::Point3f>();
        float dummy1, dummy2;
        for(size_t i = 0; i < 1889; ++i)
            ifs >> data[i].x >> data[i].y >> data[i].z >> dummy1 >> dummy2;
    
        cloud *= 5.0f;
        return cloud;
    }
    
    int main()
    {
      // step 1. construct window
      viz::Viz3d window("mywindow");
      window.showWidget("Coordinate Widget", viz::WCoordinateSystem());
      
      
      // step 2. set the camera pose
      Vec3f cam_position(3.0f, 3.0f, -3.0f), cam_focal_point(3.f, 3.f, -4.0f), cam_y_direc(-1.0f,0.0f,0.0f);
      Affine3f cam_pose = viz::makeCameraPose(cam_position, cam_focal_point, cam_y_direc);
      Affine3f transform = viz::makeTransformToGlobal(Vec3f(0.0f,-1.0f, 0.0f), Vec3f(-1.0f, 0.0f, 0.0f), Vec3f(0.0f, 0.0f, -1.0f), cam_position);
      
      
      Mat bunny = cvcloud_load();
      viz::WCloud bunny_cloud(bunny,viz::Color::green());
      
      double z = 0.0f;
      Affine3f cloud_pose_global;
      while(!window.wasStopped())
      {
        z += CV_PI*0.01f;
        cloud_pose_global = transform.inv()*Affine3f(Vec3f(0.0, 0.0, z), Vec3f(0.0, 0.0, 2.0))*Affine3f::Identity();
        window.showWidget("bunny_cloud", bunny_cloud, cloud_pose_global);
        
        // step 3. To show camera and frustum by pose
        // scale is 0.5
        viz::WCameraPosition camera(0.5);
        // show the frustum by intrinsic matrix
        viz::WCameraPosition camera_frustum(Matx33f(3.1,0,0.1,0,3.2,0.2,0,0,1));
        window.showWidget("Camera", camera, cam_pose);
        window.showWidget("Camera_frustum", camera_frustum, cam_pose);
        window.spinOnce(1, true);
      }
      return 0;
    }
  • 相关阅读:
    行测(爆发篇)之图形推理
    行测(爆发篇)之资料分析
    申论(准备篇)之申论思维
    行测(基础篇)之基础常识复习建议
    行测(基础篇)之汉语语法与阅读习惯梳理
    行测笔记整理
    申论之日积月累
    申论(准备篇)之大纲的五个隐藏秘密
    行测(基础篇)之中学知识回顾
    申论(准备篇)之找好方向
  • 原文地址:https://www.cnblogs.com/shang-slam/p/6545578.html
Copyright © 2011-2022 走看看