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;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM