viz::WGrid类有两种构造形式
1、
1 @param cells Number of cell columns and rows, respectively.网格的行、列数量 2 @param cells_spacing Size of each cell, respectively.每个格子大小 3 @param color Color of the grid. 5 WGrid(const Vec2i &cells = Vec2i::all(10), const Vec2d &cells_spacing = Vec2d::all(1.0), const Color &color = Color::white());
2、
1 WGrid(const Point3d& center, const Vec3d& normal, const Vec3d& new_yaxis, 2 const Vec2i &cells = Vec2i::all(10), const Vec2d &cells_spacing = Vec2d::all(1.0), const Color &color = Color::white());
第二种前面三个参数作用一直没看明白,直到翻出底层源代码看到其构造函数的实现,即:
1 cv::viz::WGrid::WGrid(const Point3d& center, const Vec3d& normal, const Vec3d& new_yaxis, const Vec2i &cells, const Vec2d &cells_spacing, const Color &color) 2 { 3 Vec3d zvec = normalize(normal); 4 Vec3d xvec = normalize(new_yaxis.cross(zvec)); 5 Vec3d yvec = zvec.cross(xvec); 6 7 WGrid grid(cells, cells_spacing, color); 8 grid.applyTransform(makeTransformToGlobal(xvec, yvec, zvec, center)); 9 *this = grid; 10 }
上面 zvec xvec yvec分别代表网格惯性坐标系 z 轴方向向量、x 轴方向向量、y 轴方向向量,这些向量是由构造函数的输入形参计算得来,
Vec3d zvec = normalize(normal);// <1> 表示z轴方向向量就是网格的法向量
Vec3d xvec = normalize(new_yaxis.cross(zvec)); // <2> 人为指定 new_yaxis 与 zvec作叉积得到x轴方向
Vec3d yvec = zvec.cross(xvec); // <3> 由于y轴必须同时与x、z轴垂直,所以这里直接叉积
eg:
1 viz::WGrid wgrid(Point3d(0, 7, 0), Vec3d(0, 1, 0), Vec3d(1, 0, 0), 2 Vec2i::all(20), Vec2d::all(1.0), viz::Color::white());
我这里的得出的平面就与XOY平面平行。
最新效果,好了以后3D可视化再也不用PCL了。
1 #include<opencv2/opencv.hpp> 2 using namespace cv; 3 #include <iostream> 4 #include<vector> 5 6 7 int main() 8 { 9 // myWindow 10 viz::Viz3d myWindow("myWindow"); 11 myWindow.showWidget("Coordinate", viz::WCoordinateSystem(8.0)); 12 myWindow.setBackgroundColor(viz::Color::gray()/*(186, 36, 1)*/); 13 14 15 // WCube 16 viz::WCube wcube(Vec3d::all(-1), Vec3d::all(1), true, viz::Color::orange()); 17 wcube.setRenderingProperty(viz::LINE_WIDTH, 3); 18 myWindow.showWidget("wcube", wcube); 19 20 // reference: https://www.cnblogs.com/winslam/p/13895474.html 21 viz::WGrid wgrid(Point3d(0, 7, 0), Vec3d(0, 1, 0), Vec3d(1, 0, 0), 22 Vec2i::all(80), Vec2d::all(4.0), viz::Color::white()); 23 myWindow.showWidget("wgrid", wgrid); 24 25 // WText3D 26 viz::WText3D wtext3d("OpenCV", Point3d(6, 5, 5), 0.8, true, viz::Color::white()); 27 myWindow.showWidget("wtext3d", wtext3d); 28 29 // WPolyLine (将点集自动转为一根线显示,适合SLAM显示轨迹) 30 std::vector<Point3d> points3d; 31 int i = 0; 32 int id = 0; 33 Mat rvec = Mat::zeros(1, 3, CV_32F); 34 while (!myWindow.wasStopped()) 35 { 36 if (points3d.size() > 5) 37 { 38 points3d.resize(0); 39 i = 0; 40 } 41 std::cout << "i = " << i << std::endl; 42 std::cout << "points3d.size() = " << points3d.size() << std::endl; 43 points3d.push_back(Point3d(i, -3 * i, i * i)); 44 45 viz::WPolyLine wpolyLine = viz::WPolyLine(points3d, viz::Color::green()); 46 wpolyLine.setRenderingProperty(viz::LINE_WIDTH, 2); 47 myWindow.showWidget("12345", wpolyLine); // id 不能重复 48 // 49 ////myWindow.resetCameraViewpoint 50 ////myWindow.setViewerPose 51 52 // 网格 53 myWindow.showWidget("wgrid", wgrid); 54 myWindow.spinOnce(300, true); 55 56 i = i + 1; 57 //myWindow.removeWidget("12345"); 58 59 } 60 myWindow.removeAllWidgets(); 61 return 1; 62 }