[VTK]基于VTK的三维重建
https://www.cnblogs.com/dawnWind/archive/2013/02/17/3D_06.html
0. Background
很久很久以前记录了一下使用WPF进行三维重建的一些探索,后来了解到了VTK这个开发包,
觉得功能很强大,因此后续都在基于VTK进行三维重建,在前文中对于VTK的一些相关网站进行了介绍
http://www.cnblogs.com/dawnWind/archive/2013/01/14/3D_04.html
这里就不再累赘了,感兴趣的Google一下即可。
对于VTK感兴趣的还可能会认识到与之相关的几个开发包。
其一是ITK:http://www.itk.org/
ITK始于著名的(VHP)Visible Human Project
http://www.nlm.nih.gov/research/visible/visible_gallery.html
简要地说VHP就是使用现代技术使用医学扫描等方式(如X光、CT、CMR等)获得人体二维图片,并根据这些图片构建出三维模型,
当然这里说要求的精度以及细度都非常高。人体的三维模型在我们头脑中可能立马会闪现很多电影里面有的场景,
一个组织脉络都清晰可见的人体呈现在我们面前。可以说在那个时代美国提出的这一科技项目不仅是高屋建瓴实际上
也给后续相关技术的发展带来了巨大的推动。
不过ITK说关注的更多是三维数据的测量、切割等,如果要进行三维呈现通常可以和VTK进行协作,这两者之间的数据
互通也很方便。不过对于ITK的了解我也就到此为止,并没有安装并使用过。
国内对于ITK、VTK开发包类似的研究主要由田捷带领开发的MITK,它整合ITK、VTK,为了达到一致简洁的开发,主要针对的领域是医学处理。
背景知识就这么多,接下来说一下使用VTK进行三维重建的基本步骤。
1. 3D Reconstruction with VTK
先上码。

// 读取文件夹下图片,将图像进行轮廓提取后再进行三维重建
int build3DViewFull()
{
vtkSmartPointer<vtkRenderer> aRenderer = vtkSmartPointer<vtkRenderer>::New();
vtkSmartPointer<vtkRenderWindow> renWin = vtkSmartPointer<vtkRenderWindow>::New();
renWin->AddRenderer(aRenderer); vtkSmartPointer<vtkRenderWindowInteractor> iren =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
iren->SetRenderWindow(renWin); // 新建文件读取对象,常见的有vtkBMPReader、vtkDICOMImageReader、vtkJPEGReader等
vtkSmartPointer<vtkJPEGReader> jpegReader =
vtkSmartPointer<vtkJPEGReader>::New();
// 不同的reader需要设置的参数是不同的 因此本例仅适合jpegreader
jpegReader->SetFilePrefix("C:/Users/DawnWind/Desktop/000/"); // 要打开的路径
jpegReader->SetFilePattern("%s%d.jpg"); // 图片文件名格式,此处为 0.jpg 1.jpg ...
jpegReader->SetDataByteOrderToLittleEndian();
jpegReader->SetDataSpacing(1, 1, 1.4); // 设置图片中像素比,我理解得不清楚,具体请百度之
jpegReader->SetFileNameSliceSpacing(1); jpegReader->SetDataExtent(0, 209, 0, 209, 0, 29);
// 这里因为在000文件夹里面有0.jpg ~ 29.jpg,所以设置为 0,29
// 每张图片的长宽为210 * 210 因此设置为0,209 jpegReader->Update();
// update这里要注意一下,对于VTK在默认情况下是在最后操作时候才一次性刷新
// 也就是说如果没有自动刷新的话,在一些中间过程中是无法获得到数据的,因为没update进去 vtkSmartPointer<vtkContourFilter> skinExtractor =
vtkSmartPointer<vtkContourFilter>::New();
skinExtractor->SetInputConnection(jpegReader->GetOutputPort());
skinExtractor->SetValue(200, 100); //值越大,保留的部分越少。 //重新计算法向量
vtkSmartPointer<vtkPolyDataNormals> skinNormals =
vtkSmartPointer<vtkPolyDataNormals>::New();
skinNormals->SetInputConnection(skinExtractor->GetOutputPort());
skinNormals->SetFeatureAngle(60.0);
//Specify the angle that defines a sharp edge.
//If the difference in angle across neighboring polygons is greater than this value,
//the shared edge is considered "sharp". //create triangle strips and/or poly-lines 为了更快的显示速度
vtkSmartPointer<vtkStripper> skinStripper =
vtkSmartPointer<vtkStripper>::New();
skinStripper->SetInputConnection(skinNormals->GetOutputPort()); vtkSmartPointer<vtkPolyDataMapper> skinMapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
skinMapper->SetInputConnection(skinStripper->GetOutputPort());
skinMapper->ScalarVisibilityOff(); //这样不会带颜色 vtkSmartPointer<vtkActor> skin =
vtkSmartPointer<vtkActor>::New();
skin->SetMapper(skinMapper); // An outline provides context around the data.
// 一个围绕在物体的立体框,可以先忽略
/*
vtkSmartPointer<vtkOutlineFilter> outlineData =
vtkSmartPointer<vtkOutlineFilter>::New();
outlineData->SetInputConnection(dicomReader->GetOutputPort()); vtkSmartPointer<vtkPolyDataMapper> mapOutline =
vtkSmartPointer<vtkPolyDataMapper>::New();
mapOutline->SetInputConnection(outlineData->GetOutputPort()); vtkSmartPointer<vtkActor> outline =
vtkSmartPointer<vtkActor>::New();
outline->SetMapper(mapOutline);
outline->GetProperty()->SetColor(0,0,0); aRenderer->AddActor(outline);
*/
// It is convenient to create an initial view of the data. The FocalPoint
// and Position form a vector direction. Later on (ResetCamera() method)
// this vector is used to position the camera to look at the data in
// this direction.
vtkSmartPointer<vtkCamera> aCamera =
vtkSmartPointer<vtkCamera>::New();
aCamera->SetViewUp (0, 0, -1);
aCamera->SetPosition (0, 1, 0);
aCamera->SetFocalPoint (0, 0, 0);
aCamera->ComputeViewPlaneNormal();
aCamera->Azimuth(30.0);
aCamera->Elevation(30.0); // Actors are added to the renderer. An initial camera view is created.
// The Dolly() method moves the camera towards the FocalPoint,
// thereby enlarging the image.
aRenderer->AddActor(skin);
aRenderer->SetActiveCamera(aCamera);
aRenderer->ResetCamera ();
aCamera->Dolly(1.5); // Set a background color for the renderer and set the size of the
// render window (expressed in pixels).
aRenderer->SetBackground(.2, .3, .4);
renWin->SetSize(640, 480); // Note that when camera movement occurs (as it does in the Dolly()
// method), the clipping planes often need adjusting. Clipping planes
// consist of two planes: near and far along the view direction. The
// near plane clips out objects in front of the plane; the far plane
// clips out objects behind the plane. This way only what is drawn
// between the planes is actually rendered.
aRenderer->ResetCameraClippingRange (); // Initialize the event loop and then start it.
iren->Initialize();
iren->Start();
return 0;
}

通过上面代码的可以看出,对于一个三维重建是有一些必须步骤要走的。
一是要有输入源(上文中是reader读入的数据)通过处理构成的模型actor、二是要有相机(camera)、三要有用于展示的窗口(window)
其他的就是将其中的脉络理清了,可以仿照上面代码所述进行理解,具体理论可以去查找一下OpenGL的三维模型结构,其实与我前面说的
WPF三维模型相关理论是相通的。
可以获得类似下图结果:
号外:关于VTK的设置之类就没有多说了,假设大家已经可以运行VTK的示例

[VTK]基于VTK的三维重建的更多相关文章
- 【VTK】VTK 之一 环境准备
VTK总结 http://blog.sina.com.cn/s/articlelist_2216172153_3_1.html VTK教程http://blog.csdn.net/www_doling ...
- 基于OpenCV做“三维重建”(1)--找到并绘制棋盘
<OpenCV计算机视觉编程攻略(第3版)>这套书已经出到第3版了,如果你非要我说这本书有多好,我说不出来:只是很多我第一手的例子都是来源于这本书的-相比较OpenCV官方提供的代码,这本 ...
- VTK基于MFC单文档的开发
目录 项目的搭建 相关头文件的引用 添加成员变量vtkRenderer, vtkMFCWindow CXxxView()中实例化变量vtkRenderer CXxxView::OnInitialUpd ...
- VTK显示.vtk格式文件
void ReadandShowVTKFile () { vtkSmartPointer<vtkRenderer > aRenderer = vtkSmartPointer<vtkR ...
- 基于OpenCV做“三维重建”(0)-- OpenCV3.2+VIZ6.3.0在vs2012下的编译和使用
一.问题提出 ViZ对于显示3维的效果图来说,非常有帮助:我在使用OpenCV进行双目测距的过程中,有一些参数希望能够通过可视化的方法显示出来,所以参考了这方面相关的资料.做了一些实验 ...
- VTK:VTK嵌入MFC成功
VTK作为医学显示库,得到较多使用.作为较为上层的设计,对OpenGL进行了封装,并且有Windows.Linux.安卓等开发版本,可移植性较强. 不过VES暂时没有编译成功. 以下是嵌入MFC-ID ...
- 基于OpenCV做“三维重建”(4)--相机姿态还原和实现三维重建
v当我们构建成功了viz,就可以使用3维效果给我们提供的便利,进一步进行一些3维的操作. 在这个动画中,注意图片后面的那个黑线,对应的是相机的位置. /*----------------------- ...
- 基于OpenCV做“三维重建”(3)--相机参数矩阵
通过前面的相机标定,我们能够获得一些参数模型.但是这些相机的参数矩阵到底是什么意思?怎样才能够判断是否正确?误差都会来自哪里?这里就必须要通过具体实验来加深认识.采集带相机参数的图片具有一定难度,幸好 ...
- 基于OpenCV做“三维重建”(2)--封装标定过程
既然已经能够找到了标定点,那么下边的工作就是使用标定结果了.[这本书在这里的内容组织让人莫名其妙]但是通过阅读代码能够很方便地串起来. /*------------------------------ ...
随机推荐
- resize 按钮不会被伪元素遮盖
textarea默认有个resize样式,效果就是下面这样 读 <css 揭秘>时发现两个亮点: 其实这个属性不仅适用于 textarea 元素,适用于下面所有元素: elements w ...
- git 提示:fatal: remote origin already exists. 错误解决
今天git连接远程库的时候出现fatal: remote origin already exists. 这个错误 大概是之前连接过别的库吧 然后我们的解决办法就是删除之前的连接 1.删除git远程仓库 ...
- Scikit-learn技巧(拓展)总结
Scikit-learn技巧(拓展)总结 本文转载自:http://www.jianshu.com/p/516f009c0875 最近看了<Python数据挖掘入门与实战>,网上有说翻译地 ...
- SQL语句中的正则表达式
正则表达式 REGEXP_LIKE执行正则表达式匹配 SELECT FIRST_NAME FROM EMPLOYEES WHERE REGEXP_LIKE(FIRST_NAME,'^al(an|yss ...
- CF576C Points on Plane 构造
正解:构造 解题报告: 先放下传送门趴QAQ 话说我jio得这题好玄学啊,,,就是,我实在觉得我这题做得完美无缺了?可就是过不去,,,而且它告诉我的奇异错误是"wrong output fo ...
- mysql 数据操作 多表查询 多表连接查询 外链接之左连接 右连接
1.外链接之左连接:优先显示左表全部记录 left join 在内连接的基础上保留左表的记录 即便左表有一条记录和右表没有关系,也把他留下 mysql> select * from empl ...
- 修改lastpass主密码后需重启firefox才能加载已保存的站点密码或用导入工具
最近索尼事件闹得沸沸扬扬,预防黑客先从升级密码开始.由于开发的需要一般是用firefox作为默认的浏览器,很早以前就装了lastpass密码管理器作为必备附加组件,在注册时按一下Alt+G就会帮你生成 ...
- CMSPRESS-PHP无限级分类
原博文地址:http://blog.sina.com.cn/s/blog_75ad10100101mrv0.html 当你学习php无限极分类的时候,大家都觉得一个字“难”我也觉得很难,所以,现在都还 ...
- vue学习之二ECMAScript6标准
一.ECMAScript6标准简述 ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准,已经在 2015 年 6 月正式发布了.它的目标,是使得 JavaScr ...
- Py-lamda表达式学习【转载】
转自:https://blog.csdn.net/zjuxsl/article/details/79437563 1.语法定义 在Python中,lambda的语法是唯一的.其形式如下: lambda ...