1.前言

VTK应用程序所需的数据可以通过两种途径获取: 第一种是生成模型 ;第二种是从外部存储介质里导入相关的数据文件,(如vtkBMPReader读取 BMP图像) 。VTK 也可以将程序中处理完成的数据写入单个文件中, 或者将所渲染的场景导出。从可视化管线的角度来看,一般以数据的读取 (或由模型创建数据)开始,而以数据的写盘操作(或 Mapper)结束

前面我们已经接触到了 VTK的 Reader类,将数据导入可视化管道的流程:

  • 实例化 Reader对象;
  • 指定所要读取的文件名;
  • 调用 Update()方法促使管线执行。当管线后续的 Fiter有 Update0请求时,如调用Render()方法管线就会读取相应的图像文件, 所以这一步可省略 。

类似地, 使用 Writer类的主要步骤如下:

  • 实例化 Writer对象;
  • 输入要写盘的数据以及指定待写盘的文件名;
  • 调用 Write()方法促使 Writer类开始写盘操作。

2.vtkImageData类

图像数据在 VTK 中是用vtkImageData类表示的,对于不同的图像文件类型, VTK提供相对应的类对图像文件进行读写操作。比如,前面章节中所提的vtkBMPReader是用于读取 BMP图像, vtkJPEGReader用于读取 JPG图像。 VTK除了支持 BMP、 JPG图像格式之外,还支持其他多种图像格式的读写。例如:
注意:
1.值得注意的是vtkImageReader/vtkImageWriter用于读写RAW格式的数据(即俗称的“裸数据”) ,该类型的图像没有文件信息,因此在读取此类图像时,需要指定图像各个维度的大小、字节顺序(是大端字节序还是小端字节序)、存储像素値的类型等信息,只有指定这些信息、,类vtkImageReader才能正确读取图像
2.类vtkDicomImageReader可用于读取DICOM图像,但该类的功能很不完善,虽然VTK 最初是因医学图像可视化而诞生。但VTK对DICOM图像的读写操作却很不支持,比如该类不支持多帧DICOM图像的读取,而且VTK 也没有实现对 DICOM图像的写操作, 即没有提供类vlkDlCOMlmageWriter。
对 DICOM图像支持较好的函数库主要有 GDCM和 DCMTK。著名的医学图像分割与配准工具包 ITK 就是封装了 GDCM函数库进行 DICOM图像的读写。

3.单幅图像的读写

#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL);  #include <vtkSmartPointer.h>
#include <vtkPNGReader.h>
#include <vtkImageViewer2.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkJPEGWriter.h>
#include <vtkRenderer.h> //定义了Cameraint main()
{//读取PNG图像vtkSmartPointer<vtkPNGReader> pngread = vtkSmartPointer<vtkPNGReader>::New();pngread->SetFileName("logo.png");//显示该幅图像vtkSmartPointer<vtkImageViewer2> ImageViewer =vtkSmartPointer<vtkImageViewer2>::New();ImageViewer->SetInputConnection(pngread->GetOutputPort());vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInter = vtkSmartPointer<vtkRenderWindowInteractor>::New();ImageViewer->SetupInteractor(renderWindowInter);ImageViewer->Render();ImageViewer->GetRenderer()->ResetCamera();ImageViewer->Render();//写图像vtkSmartPointer<vtkJPEGWriter> writer = vtkSmartPointer<vtkJPEGWriter>::New();writer->SetFileName("VTK-logo.jpg");writer->SetInputConnection(pngread->GetOutputPort());writer->Write();renderWindowInter->Start();
}

      
该段代码先使用vtkPNGReader读入 PNG图像,然后用VTK 窗口显示读取的 PNG图像,最后使用类vtkJPEGWriter将读入的文件写成JPG图像。程序中使用 SetFileName方法设置要读写的图像名, 在写文件操作时要调用方法 Write方法才会将内存中的数据写入到存储介质中。

可能我们会感觉到很奇怪,数据管线已经铺设好了,可是我们是怎么样实现引擎渲染的呢?已到最后完成了与Windows操作系统完成了交互?在显示图像时并没有用到,vtkRenderWindow、 vtkRenderer、 vtkActor等类,而只是使用了vtkImageViewer2以及设置了交互样式。其实, VTK 可视化管线相关的几个类都已经封装在vtkImageViewer2 里。vtkImageViewer2主要是针对二维图像(特别是医学图像)显示设计的,实现了图像缩放、转、平移、窗宽窗位调节等功能: 除了可以用于单幅二维图像的显示之外, 也可以显示三维图像的某个切片, 还可以设置不同的显示方向。

4.读取序列图像文件

医学图像应用程序中常常会处理序列的图像文件,比如计算机断层成像或者磁共振成像所成图像一般都是由多个有顺序的二维图像组成, 应用程序需要一次性导入一个序列的二维图像。VTK没有提供专门的类读取序列图像文件,但是VTK的图像Reader类都有提供方法SetFileNames()来设置多个图像文件名,利用该方法可以实现序列图像的读取。

#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL);  #include <stdio.h>
#include <vtkSmartPointer.h>
#include <vtkStringArray.h>
#include <vtkJPEGReader.h>
#include <vtkImageViewer2.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>int main()
{//生成文件序列组名vtkSmartPointer <vtkStringArray> fileArray =vtkSmartPointer <vtkStringArray>::New();char fileName[128];for(int i=1; i<100; i++){sprintf(fileName,"Head/head%03d.jpg",i);vtkstd::string fileStr(fileName);fileArray->InsertNextValue(fileStr);}//读取JPG序列图像vtkSmartPointer <vtkJPEGReader> reader = vtkSmartPointer <vtkJPEGReader>::New();reader->SetFileNames(fileArray);//显示vtkSmartPointer<vtkImageViewer2> viewer = vtkSmartPointer<vtkImageViewer2>::New();viewer->SetInputConnection(reader->GetOutputPort());vtkSmartPointer<vtkRenderWindowInteractor> interact =vtkSmartPointer<vtkRenderWindowInteractor>::New();//默认选择第50张切片viewer->SetSlice(50);//viewer->SetSliceOrientationToXY();viewer->SetSliceOrientationToXZ();//viewer->SetSliceOrientationToYZ();viewer->SetupInteractor(interact);viewer->Render();interact->Start();return 0;
}

程序中使用 vtkStringArray生成文件名列表, 然后调用 vtkJPEGReader的方法。SetFileNames()设置符读取的序列图像的文件名 。初始显示该序列图像的第50个切片,显示的方向为 SetSliceOrientationToXY()。
还可以使用 Reader类里的 SetFilePrefix()和 SetFilePattem()等方法读取序列图像。

5.参考资料

1.《C++ primer》
2.《The VTK User’s Guide – 11thEdition》
3.《The Visualization Toolkit – AnObject-Oriented Approach To 3D Graphics (4th Edition)》
4.  张晓东, 罗火灵. VTK图形图像开发进阶[M]. 机械工业出版社, 2015.

VTK修炼之道13:数据读写_图像数据的读写相关推荐

  1. VTK修炼之道14:图像处理_创建

    1.引言:图像数据结构 数字图像文件内容由两个部分组成:图像头信息和数据.图像头信息定义了图像的基本信息,主要包括起点位置(Origin),像素间隔(space)和维数(dimension).通过这三 ...

  2. VTK修炼之道61:体绘制_光线投影+最大密度投影+等值面法

    1.vtkVolumeMapper vtkVolumeMapper是所有体绘制Mapper类的虚基类,提供接口函数,并由其子类实现具体功能.该类的继承关系如下图所示: 应该掌握一些常用的体绘制类. 2 ...

  3. VTK修炼之道60:体绘制_体绘制管线图形渲染管线

    1.几何渲染与体绘制 1.1 几何渲染 前面练习的渲染技术都是几何渲染技术.所谓的几何渲染技术,就是通过绘制几何图元(顶点.线段.面片等)来渲染数据,例如:绘制图像需要在空间中建立一个四边形图元,然后 ...

  4. VTK修炼之道36:图像平滑_均值滤波器

    1.图像平滑 图像平滑常用于图像的预处理中,如计算梯度时先对图像进行平滑处理,可以减少噪声对梯度的影响.图像平滑一般是通过模板卷积运算实现.模板可以看做是一个大小为nxn的小图像,例如3x3,5x5等 ...

  5. VTK修炼之道62:体绘制_固定点光线投影体绘制与GPU加速光线投影体绘制

    1.固定点光线投影算法 vtkFixedPointVolumeRayCastMapper是一个较好的vtkVolumeRayCastMapper的替代者.该类能够实现基于Alpha合成的体绘制方法和最 ...

  6. VTK修炼之道16:图像处理_窗口分割和图像融合(ViewportvtkImageBlend)

    1.前言 前面演示的例子都是在一个窗口中显示一个图像.但是在常见的图像处理软件中,经常会遇到在一个窗口中显示多个图像,这就会用到图像融合技术.图像融合利用图像的alpha通道和不透明度来实现.VTK中 ...

  7. VTK修炼之道32:边缘检测_梯度算子

    1.梯度算子提取图像边缘 图像中不连续的灰度值会产生边缘,图像的边缘检测是基于边界的图像分割方法,如分水岭算法,通常是分割原图的梯度图像,梯度实际上也是反应的图像边缘信息.图像边缘一般常用图像一阶导数 ...

  8. VTK修炼之道39:图像平滑_各向异性滤波

    1.各向异性扩散滤波 高斯平滑方法在平滑噪声的同时,模糊了图像的重要边缘图像. 各向异性滤波是一种基于偏微分方程的滤波技术,建立于热量的各向异性扩散理论. 各向异性滤波在图像的平坦区域选择大尺度平滑, ...

  9. VTK修炼之道38:图像平滑_中值滤波器

    1.中值滤波 vtkImageHybridMedian2D实现了对二维图像的中值滤波.其实现原理是,采用一个5x5的模板,逐次将模板中心对应于图像的每个像素上,将模板图像覆盖的像素的中值作为当前像素的 ...

最新文章

  1. 手写js的insertAfter
  2. windows phone 快捷键
  3. ubus c语言例子,openwrt之ubus例子
  4. OJ1029: 三角形判定
  5. Thrift框架使用C++的一个demo
  6. 跟工作选择障碍同学聊一聊现实的问题……
  7. 通达oa SQL注入day
  8. 电脑围棋领域的研究概述
  9. SLAM 之四元数转欧拉角再理解
  10. 马来西亚计算机科学与工程大学,一分钟了解世界名校马来西亚电脑科学与工程大学...
  11. 校园招聘的简历写作与面试技巧
  12. 抖音短视频内容该如何创作
  13. Swift学习笔记 ——(一)
  14. 淘宝API接入说明(商品详情数据示例)
  15. 简单实现自定义Android TextView字体
  16. 计算机存储器件中运行速度最快,选择题:下列存储器中,存取速度最快的是()...
  17. 人脸、商品、车辆识别一网打尽!
  18. Kali社会工程学套件上的二维码攻击工具
  19. ET5.0 UGUI替换为FairyGUI
  20. 5G专网技术在智能电网中的应用

热门文章

  1. ASP.NET浏览器跨域
  2. MySQL 修复root权限
  3. [导入]ASP.NET AJAX 说明文档-客户端引用-全局命名空间-JavaScript 基础类型扩展-Array 类型扩展-contains 函数...
  4. HD 1159 Common Subsequence (最长公共子序列)
  5. hdu 1255(线段树+离散化)
  6. JSP简单练习-上传文件
  7. NYOJ 123 士兵杀敌(四)
  8. hdu 1106 排序
  9. MySQL的常见存储引擎介绍与参数设置调优
  10. JS中的this的应用总结