费了半天劲,终于把这个WMesh类搞懂了,可惜效果不佳,比Matlab中的mesh差多了。

使用WMesh前,需要有一个Mesh对象,Mesh是三维数据点的基本几何信息、颜色信息、索引信息等集成的对象。Mesh对象无法直接在Viz3d中显示,需要转换为WMesh对象,然后才可以显示。

首先了解Mesh类:

我们先看看Mesh的定义,在Mesh中有四个Mat型的成员变量,分别是cloud、colors和normals。

望名知意,cloud表示点云,它实际上是点云中每个点的坐标组成的二维矩阵,它的通道数为3,所以cloud的数据类型为:CV_32FC3,cloud的三个通道[0]、[1]、[2]分别对应坐标的x、y、z。对cloud还有一个特殊要求,那就是一行、N列,也就是一个一位矢量。需要预先把每个点坐标依次赋值给cloud的一些列元素,比如点P(x,y,z),赋值给cloud的第0行、j列元素:cloud.ptr<Vec3f>(0)[j][0]=x; cloud.ptr<Vec3f>(0)[j][1]=y; cloud.ptr<Vec3f>(0)[j][2]=z。

在Mesh中的第二个成员colors也是一个一维矩阵,1行、N列,与cloud的尺度一致。colors通常是3通道或四通道,但绝不以是2通道。三通道时,分别对应红、绿、蓝三原色。colors的每个元素与cloud中的元素一一对应,分别给cloud中对应元素赋予颜色。还有一点需要注意,colors的每个通道上的数据类型必须是CV_8U,因此colors的数据类型通常为CV_8UC3。

第三个公有成员是normals,它与colors类似,具体内容还没有研究。

第四个共有成员是polygons,它也是一个一维行矢量,但是列数要比cloud多一列,在polygons的第一个

还有一个公有静态成员函数load,大家自己研究吧!

class CV_EXPORTS Mesh
{
public:
Mat cloud, colors, normals;
//! Raw integer list of the form: (n,id1,id2,...,idn, n,id1,id2,...,idn, ...)
//! where n is the number of points in the poligon, and id is a zero-offset index into an associated cloud.
Mat polygons;
//! Loads mesh from a given ply file
static Mesh load(const String& file);
};

接下来,我们以一个实例来说明Mesh的用法。在本示例中,我读取了一幅图像,将图像的灰度值作为z值,这样就可以以三维的形式观察二维图像数据:

#include <opencv2/viz/vizcore.hpp>
#include <opencv2/opencv.hpp> #include <iostream>
using namespace cv;
using namespace std;
//#include "myfunction.h" int main()
{
Mat img=imread("D:/CodeWork/MyImage/opencv_logo.png"); Mat gray;
img.convertTo(gray,CV_32FC1); int rows=img.rows,cols=img.cols;
//为了赋值方便,这里我用了与img同行、同列的矩阵
Mat cloud(rows,cols,CV_32FC3);
int cx=cols/,cy=rows/; //为cloud矩阵赋值
for(int i=;i<rows;i++)
{
float y=i-cy;
for(int j=;j<cols;j++)
{
float x=j-cx;
cloud.ptr<Vec3f>(i)[j][]=x;
cloud.ptr<Vec3f>(i)[j][]=-y;
cloud.ptr<Vec3f>(i)[j][]=(img.ptr<Vec3b>(i)[j][]
+img.ptr<Vec3b>(i)[j][]
+img.ptr<Vec3b>(i)[j][])/;
}
}
///创建polygons矩阵,并为其赋值,它的第0个元素是三维点的个数
/// 剩下的元素值分别为1、2、3......、N。此次的N表示总的三维点数
Mat polygon(,cols*rows+,CV_32SC1,Scalar::all());
polygon.ptr<int>()[]=rows*cols;
for(int i=;i<=polygon.cols;i++)
polygon.ptr<int>()[i]=i;
///下面是把二维的cloud转化为一维的cloud
Mat cloud1d=cloud.reshape(,cloud.rows*cloud.cols);
cloud1d=cloud1d.t();
///创建并赋值Mesh对象
viz::Mesh mesh;
mesh.cloud=cloud1d;
mesh.polygons=polygon;
///创建颜色矩阵
Mat color;
color=img.reshape(,rows*cols);
color=color.t();
mesh.colors=color;
///mesh本身无法在三维窗口中显示,需要经过WMesh处理,得到WMesh对象wmesh
viz::WMesh wmesh(mesh); ///显示wmesh
imshow("original image",img);
viz::Viz3d my3DWin("My 3D Window");
my3DWin.setBackgroundColor(viz::Color::cyan());
my3DWin.showWidget("wmesh",wmesh); my3DWin.spin(); return ;
}

最新文章

  1. Net作业调度(三) — Quartz.Net进阶
  2. WinForm 代码实现以管理员身份运行
  3. flot - jQuery 图表插件(jquery.flot)使用
  4. 内核input子系统分析
  5. Best Practices for Background Jobs_3 Managing Device Awake State之电源锁、Alarm、WakefulBroadcastReceiver
  6. Jquery获取checkbox属性checked为undefined
  7. Oracle 的表备份的方法
  8. php函数mt_rand和rand 速度测试
  9. vector 之删除元素
  10. ASP.NET Web Service如何工作(3)
  11. ID卡常见型号
  12. 内存分析工具 MAT 的使用
  13. python基本面试题
  14. OGG初始化之使用Oracle Data Pump加载数据
  15. 聊天机器人(chatbot)终极指南:自然语言处理(NLP)和深度机器学习(Deep Machine Learning)
  16. MT【178】平移不变性
  17. Linux Delay Accounting
  18. 前端动画小记---bilibili ( ゜-゜)つロ客户下载小动画
  19. Rabbitmq消息服务器通讯异常: name must not be blank
  20. 用树莓派做电视盒子,安装Android TV系统

热门文章

  1. c# 获取api 数据
  2. Java一致性Hash算法的实现
  3. python中open与with open的区别
  4. cnblogs设置各级标题样式和目录
  5. Acwing-204-表达整数的奇怪方式(扩展中国剩余定理)
  6. 快速傅立叶变换FFT模板
  7. sqoop数据导出
  8. 初学 Nginx (一) SSI 的作用
  9. Keras学习笔记三:一个图像去噪训练并离线测试的例子,基于mnist
  10. LeetCode 106. 从中序与后序遍历序列构造二叉树(Construct Binary Tree from Inorder and Postorder Traversal)