該可視化模塊提供了座標系變化,3D動畫等功能ios
最簡單的顯示座標系函數
viz::Viz3d window("window"); window.showWidget("Coordinate", viz::WCoordinateSystem()); window.spin();
其中spin()函數開啓一個event loop永遠循環,spinOnce(int time = 1, bool redraw = true)表示event loop循環time時間。一般將與視圖的交互放在一個循環中:oop
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軸旋轉的動畫ui
Viz模塊中主要使用Affine3f仿射變換來處理空間轉換的過程,下面實例實現3D點雲在世界座標系下,繞相機座標系z軸旋轉:spa
#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; }