VTK中vtkImageData类和vtkPolyData类使用频率极高,vtkImageData类和vtkPolyData类派生自vtkDataSet类,是数据集的一种。
  vtkPolyData数据由几何结构数据、拓扑结构数据和属性数据组成。几何结构数据主要是组成模型的点集,拓扑结构数据是点按一定关系组成的单元数据,属性数据与几何结构数据和拓扑结构数据想关联,可以标量、向量、张量,可以用来间接表示图像的颜色。vtkPolyData可以表示多种几何数据,用来表示顶点、线、多边形、三角形带在内的几何结构,即三维实体。通常使用者在界面或者交互器上拾取的坐标点积、勾勒的多边形以及闭合三角带形成的多面体都可以使用vtkPolyData来表示和渲染,vtkPolyData占据了VTK的数据集中很大一部分。
  VTK库是图形图像可视化库,那么除了多边形的图形vtkPolyData数据,还有常用到的图像数据,图像数据主要是使用了vtkImageData类。vtkImageData类表示的是一种在拓扑上和几何上都是规则的几何结构,包括了体素数据和像素数据,所以vtkImageData类可以表示二维和三维的图像。使用vtkImageData作为输入和输出的类大多都以vtkImage作为前缀,主要是用来处理图像。

  在项目实践中,经常会碰到几何多边形vtkPolyData数据转换为图像vtkImageData数据。比如导入几何多边形格式的文件然后需要按照图像体渲染方式输出MIP图像或者DDR图像;有比如在图像数据上圈选病灶进行分割图像,其中圈选可以生成多边形数据,然后就需要转换为图像数据的掩膜对图像数据剪裁;以上这些场景都是用到了几何多边形转换图像数据,如何转换是个问题,下面记录下我搜集到的资料;

vtkPolyDataToImageStencil

  vtkPolyDataToImageStencil类可以将vtkPolyData数据转换为图像模具(Stencil)。vtkPolyData数据可以是闭合曲面网格或一系列多段线等高线(每个切片一个等高线)。需要注意的是:如果提供了等高线,则等高线必须与Z平面对齐。不支持其他轮廓方向。

接口

  使用SetInputData设定要转换为模具的多边形数据。

virtual void SetInputData(vtkPolyData*);
vtkPolyData *GetInput();

  使用vtkImageStencilSource类提供的三个函数设置输出图像的三维尺寸、像素间距和起点坐标;
这三个参数分别是SetOutputWholeExtent,SetOutputSpacing和SetOutputOrigin;如果没有指定起始坐标,则起始坐标默认值为(0,0,0);如果没有设置像素间距,则像素间距默认为(1,1,1)

vtkSetVector3Macro(OutputOrigin, double);
vtkGetVector3Macro(OutputOrigin, double);
vtkSetVector3Macro(OutputSpacing, double);
vtkGetVector3Macro(OutputSpacing, double);
vtkSetVector6Macro(OutputWholeExtent, int);
vtkGetVector6Macro(OutputWholeExtent, int);

vtkImageStencil

  vtkImageStencil类通过cookie cuter操作合并图像。
  vtkImageStencil将使用一个模具将两个图像组合在一起。模具应以vtkImageStencilData的形式提供
  cookie cuter是英语俚语“千篇一律”的意思。从字面上讲,cookie-cutter 就是一个金属形状的圈圈,把曲奇饼切成想要的形状,由于曲奇饼很软、金属模具很硬,所以 cookie-cutter 切出来的东西都是一模一样的形状,这也就是为什么它用来形容“千篇一律”的原因。这里的“cookie cuter操作”是指使用模具在原有的图像数据上获取重叠的图像数据,变相是一种图像的融合操作;

接口

使用SetInputData设置输入的vtkImageData,模具数据是vtkImageStencilData指针类型;
使用SetStencilConnection设置模具数据;

virtual void SetStencilData(vtkImageStencilData *stencil);
vtkImageStencilData *GetStencil();
void SetStencilConnection(vtkAlgorithmOutput* outputPort)
{this->SetInputConnection(2, outputPort);
}

设置翻转类型ReverseStencil。可以根据ReverseStencil结合BackgroundValue来决定生成模具图像内的体素数值;

vtkTypeBool ReverseStencil;
vtkSetMacro(ReverseStencil, vtkTypeBool);
vtkBooleanMacro(ReverseStencil, vtkTypeBool);
vtkGetMacro(ReverseStencil, vtkTypeBool);

使用SetBackgroundInputData设置第二个输入。此图像将用于设置图像模具外的数据值。如果未设置,输出体素将被填充BackgroundValue值;BackgroundValue值由SetBackgroundValue方法设置;

virtual void SetBackgroundInputData(vtkImageData *input);
vtkImageData *GetBackgroundInput();
void SetBackgroundValue(double val) { this->SetBackgroundColor(val,val,val,val); };
double GetBackgroundValue() { return this->BackgroundColor[0]; };

vtkImageStencilToImage

  vtkImageStencilToImage类将图像模板转换为二进制图像。默认输出为8位图像,模具内的值为1,模具外的值为0。当与  vtkPolyDataToImageStencil类或vtkImplicitFunctionToImageStencil类结合使用时,可用于从网格或函数创建二进制图像。

接口

使用SetOutsideValue和SetInsideValue设置模具内外的值,分别对应了OutsideValue和InsideValue;InsideValue是模具内的值;OutsideValue是模具外的值;
使用SetOutputScalarType设置对外输出数据的类型;

double OutsideValue;
double InsideValue;
int OutputScalarType;
vtkSetMacro(OutsideValue, double);
vtkGetMacro(OutsideValue, double);
vtkSetMacro(InsideValue, double);
vtkGetMacro(InsideValue, double);
vtkSetMacro(OutputScalarType, int);
vtkGetMacro(OutputScalarType, int);
void SetOutputScalarTypeToFloat() { this->SetOutputScalarType(VTK_FLOAT); }
void SetOutputScalarTypeToDouble() { this->SetOutputScalarType(VTK_DOUBLE); }
void SetOutputScalarTypeToInt() { this->SetOutputScalarType(VTK_INT); }
void SetOutputScalarTypeToUnsignedInt() { this->SetOutputScalarType(VTK_UNSIGNED_INT); }
void SetOutputScalarTypeToLong() { this->SetOutputScalarType(VTK_LONG); }
void SetOutputScalarTypeToUnsignedLong() { this->SetOutputScalarType(VTK_UNSIGNED_LONG); }
void SetOutputScalarTypeToShort() { this->SetOutputScalarType(VTK_SHORT); }
void SetOutputScalarTypeToUnsignedShort() { this->SetOutputScalarType(VTK_UNSIGNED_SHORT); }
void SetOutputScalarTypeToUnsignedChar() { this->SetOutputScalarType(VTK_UNSIGNED_CHAR); }
void SetOutputScalarTypeToChar() { this->SetOutputScalarType(VTK_CHAR); }
vtkNew<vtkPolyDataToImageStencil> pol2stenc;
pol2stenc->SetInputData(geometry);
pol2stenc->SetOutputOrigin(origin);
pol2stenc->SetOutputSpacing(spacing);
pol2stenc->SetOutputWholeExtent(whiteImage->GetExtent());
pol2stenc->Update();

示例

下面使用一个例子说明vtkPolyData转换为vtkImageData;
1.实例化一个圆球对象sphereSource;
2.根据sphereSource的三维尺度,实例化一个图像数据vtkImageData对象whiteImage,whiteImage内的体素值为从各自体素的id值;
3.实例化vtkPolyDataToImageStencil类对象pol2stenc,输入模具来源数据sphereSource,使用whiteImage对象的三维尺寸值;
4.实例化vtkImageStencil对象imgstenc,输入图像数据whiteImage,模具数据pol2stenc,关闭翻转标识,设置模具外体素值为0;
5.渲染出结果;

#pragma once
#include <vtkImageData.h>
#include <vtkImageStencil.h>
#include <vtkMetaImageWriter.h>
#include <vtkNew.h>
#include <vtkPointData.h>
#include <vtkPolyData.h>
#include <vtkPolyDataToImageStencil.h>
#include <vtkSphereSource.h>
#include <vtkNamedColors.h>
#include <vtkInteractorStyleSwitch.h>
#include <vtkDataSetMapper.h>
#include <vtkCamera.h>class Test_vtkPolyDataToImageStencil {public:static void Test() {vtkNew<vtkSphereSource> sphereSource;sphereSource->SetRadius(250);sphereSource->SetPhiResolution(30);sphereSource->SetThetaResolution(30);sphereSource->SetCenter(250, 250, 250);auto pd = sphereSource->GetOutput();sphereSource->Update();vtkNew<vtkImageData> whiteImage;double bounds[6];pd->GetBounds(bounds);double spacing[3]; // desired volume spacingspacing[0] = 1;spacing[1] = 1;spacing[2] = 1;whiteImage->SetSpacing(spacing);// compute dimensionsint dim[3];for (int i = 0; i < 3; i++){dim[i] = static_cast<int>(ceil((bounds[i * 2 + 1] - bounds[i * 2]) / spacing[i]));}whiteImage->SetDimensions(dim);whiteImage->SetExtent(0, dim[0] - 1, 0, dim[1] - 1, 0, dim[2] - 1);double origin[3];origin[0] = bounds[0] + spacing[0] / 2;origin[1] = bounds[2] + spacing[1] / 2;origin[2] = bounds[4] + spacing[2] / 2;whiteImage->SetOrigin(origin);whiteImage->AllocateScalars(VTK_UNSIGNED_CHAR, 1);// fill the image with foreground voxels:unsigned char inval = 255;unsigned char outval = 0;vtkIdType count = whiteImage->GetNumberOfPoints();for (vtkIdType i = 0; i < count; ++i){whiteImage->GetPointData()->GetScalars()->SetTuple1(i, 255);}// polygonal data --> image stencil:vtkNew<vtkPolyDataToImageStencil> pol2stenc;pol2stenc->SetInputData(pd);pol2stenc->SetOutputOrigin(origin);pol2stenc->SetOutputSpacing(spacing);pol2stenc->SetOutputWholeExtent(whiteImage->GetExtent());pol2stenc->Update();// cut the corresponding white image and set the background:vtkNew<vtkImageStencil> imgstenc;imgstenc->SetInputData(whiteImage);imgstenc->SetStencilConnection(pol2stenc->GetOutputPort());imgstenc->ReverseStencilOff();imgstenc->SetBackgroundValue(outval);imgstenc->Update();              vtkNew<vtkNamedColors> colors;vtkColor3d backgroundColor = colors->GetColor3d("Wheat");vtkColor3d checkerColor = colors->GetColor3d("Tomato");vtkColor3d fillColor = colors->GetColor3d("Banana");vtkNew<vtkRenderer> renderer;renderer->SetBackground(backgroundColor.GetData());vtkNew<vtkRenderWindow> renderWindow;renderWindow->AddRenderer(renderer);renderWindow->SetSize(640, 480);vtkNew<vtkRenderWindowInteractor> interactor;vtkNew<vtkInteractorStyleSwitch> style;interactor->SetInteractorStyle(style);interactor->SetRenderWindow(renderWindow);vtkNew<vtkDataSetMapper> imageMapper;vtkNew<vtkActor> imageActor;imageActor->SetMapper(imageMapper);renderer->AddViewProp(imageActor);imageMapper->SetInputConnection(imgstenc->GetOutputPort());renderer->ResetCamera();renderer->GetActiveCamera()->Azimuth(120);renderer->GetActiveCamera()->Elevation(30);renderer->ResetCameraClippingRange();renderWindow->SetWindowName("ClipVolume");renderWindow->Render();interactor->Start();}
};


设置开启翻转像素,则模具外的数据就会填充为1,模具内的数据填充为0;

imgstenc->ReverseStencilOn();

增加高斯模糊,做体渲染;

#pragma once
#include "vtk_include.h"
#include <vtkImageData.h>
#include <vtkImageStencil.h>
#include <vtkMetaImageWriter.h>
#include <vtkNew.h>
#include <vtkPointData.h>
#include <vtkPolyData.h>
#include <vtkPolyDataToImageStencil.h>
#include <vtkSphereSource.h>
#include <vtkImageGaussianSmooth.h>
class Test_vtkPolyDataToImageStencil {public:static void Test() {vtkNew<vtkSphereSource> sphereSource;sphereSource->SetRadius(20);sphereSource->SetPhiResolution(30);sphereSource->SetThetaResolution(30);sphereSource->SetCenter(250, 250, 250);auto pd = sphereSource->GetOutput();sphereSource->Update();vtkNew<vtkImageData> whiteImage;double bounds[6];pd->GetBounds(bounds);double spacing[3]; // desired volume spacingspacing[0] = 0.5;spacing[1] = 0.5;spacing[2] = 0.5;whiteImage->SetSpacing(spacing);// compute dimensionsint dim[3];for (int i = 0; i < 3; i++){dim[i] = static_cast<int>(ceil((bounds[i * 2 + 1] - bounds[i * 2]) / spacing[i]));}whiteImage->SetDimensions(dim);whiteImage->SetExtent(0, dim[0] - 1, 0, dim[1] - 1, 0, dim[2] - 1);double origin[3];origin[0] = bounds[0] + spacing[0] / 2;origin[1] = bounds[2] + spacing[1] / 2;origin[2] = bounds[4] + spacing[2] / 2;whiteImage->SetOrigin(origin);whiteImage->AllocateScalars(VTK_UNSIGNED_CHAR, 1);// fill the image with foreground voxels:unsigned char inval = 255;unsigned char outval = 0;vtkIdType count = whiteImage->GetNumberOfPoints();for (vtkIdType i = 0; i < count; ++i){whiteImage->GetPointData()->GetScalars()->SetTuple1(i, i);}// polygonal data --> image stencil:vtkNew<vtkPolyDataToImageStencil> pol2stenc;pol2stenc->SetInputData(pd);pol2stenc->SetOutputOrigin(origin);pol2stenc->SetOutputSpacing(spacing);pol2stenc->SetOutputWholeExtent(whiteImage->GetExtent());pol2stenc->Update();// cut the corresponding white image and set the background:vtkNew<vtkImageStencil> imgstenc;imgstenc->SetInputData(whiteImage);imgstenc->SetStencilConnection(pol2stenc->GetOutputPort());imgstenc->ReverseStencilOff();imgstenc->SetBackgroundValue(outval);imgstenc->Update();               vtkImageGaussianSmooth *gaosi = vtkImageGaussianSmooth::New();//高斯平滑处理gaosi->SetInputData(imgstenc->GetOutput());gaosi->SetDimensionality(3);gaosi->SetRadiusFactors(2, 2, 1);gaosi->Update();vtkNew<vtkGPUVolumeRayCastMapper> gpuMapper;gpuMapper->SetInputData(gaosi->GetOutput());gpuMapper->SetMaskTypeToBinary();gpuMapper->SetMaskInput(NULL);vtkPiecewiseFunction * psfunction = vtkPiecewiseFunction::New();//透明度传递函数psfunction->AddPoint(0.0, 0.0);psfunction->AddPoint(40.0, 0.0);psfunction->AddPoint(50.0, 0.3);psfunction->AddPoint(110.0, 0.4);psfunction->AddPoint(120, 0.5);psfunction->AddPoint(130, 0.6);psfunction->AddPoint(190, 0.8);psfunction->AddPoint(255, 1.0);vtkColorTransferFunction * colfunction = vtkColorTransferFunction::New();//颜色传递函数colfunction->AddRGBPoint(0.0, 0.5, 0.3, 0.2);colfunction->AddRGBPoint(50.0, 0.8, 0.5, 0.5);colfunction->AddRGBPoint(110.0, 0.6, 0.2, 0.3);colfunction->AddRGBPoint(190.0, 0.81, 0.27, 0.1);colfunction->AddRGBPoint(255.0, 0.5, 0.9, 0.9);vtkVolumeProperty * volpro = vtkVolumeProperty::New();//体数据属性volpro->SetColor(colfunction);volpro->SetScalarOpacity(psfunction);volpro->ShadeOn();volpro->SetInterpolationTypeToLinear();volpro->SetAmbient(0.2);volpro->SetDiffuse(0.9);volpro->SetSpecular(0.2);volpro->SetSpecularPower(10);vtkVolume * data = vtkVolume::New();//体数据映射器和属性data->SetMapper(gpuMapper);data->SetProperty(volpro);vtkRenderer *render = vtkRenderer::New();vtkRenderWindow *renwin = vtkRenderWindow::New();vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();renwin->AddRenderer(render);renwin->SetInteractor(iren);//绘制器render->AddVolume(data);render->SetBackground(0, 0, 0);render->ResetCameraClippingRange();//绘制窗口renwin->AddRenderer(render);renwin->Render();iren->Initialize();iren->Start();}
};

VTK笔记-图形相关-多边形数据转换图像数据-vtkPolyData转换为vtkImageData相关推荐

  1. VTK笔记-图形相关-圆锥体-vtkConeSoure类

    圆锥体 文章目录 圆锥体 前言 一.代码 1.1流程 二.遇到的问题 1.运行时异常 2.在ThinkPad E530C笔记本上出现的异常 3.运行结果 三.相机旋转 四.vtkConeSource ...

  2. VTK笔记-图形相关-线段平滑-vtkSplineFilter类

      在实际的开发中,提供有限的连续线段组成一条曲线,需要将该条曲线进行插值处理,生成更高采样率的曲线:这种情况下就需要进行插值:VTK中的线段插值是通过B样条插值实现,使用vtkSplineFilte ...

  3. python中.mat的图像数据怎么转换为.npy的数据

    .mat是MATLAB的二进制数据文件格式,而.npy是NumPy的二进制数据文件格式.要将.mat文件中的图像数据转换为.npy格式,你需要使用NumPy库和SciPy库. 首先,你需要安装这两个库 ...

  4. python读取图像数据流_浅谈TensorFlow中读取图像数据的三种方式

    本文面对三种常常遇到的情况,总结三种读取数据的方式,分别用于处理单张图片.大量图片,和TFRecorder读取方式.并且还补充了功能相近的tf函数. 1.处理单张图片 我们训练完模型之后,常常要用图片 ...

  5. VTK修炼之道13:数据读写_图像数据的读写

    1.前言 VTK应用程序所需的数据可以通过两种途径获取: 第一种是生成模型 ;第二种是从外部存储介质里导入相关的数据文件,(如vtkBMPReader读取 BMP图像) .VTK 也可以将程序中处理完 ...

  6. Hi3516开发笔记(十):Qt从VPSS中获取通道图像数据存储为jpg文件

    若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/123536470 红胖子(红模仿)的博文大全:开发技术集 ...

  7. VTK:演示在多边形数据上使用裁剪用法实战

    VTK:演示在多边形数据上使用裁剪用法实战 程序输出 程序完整源代码 程序输出 程序完整源代码 #include <vtkActor.h> #include <vtkCamera.h ...

  8. scipy笔记—scipy.misc.imresize用法(方便训练图像数据)

    scipy.misc.imresize 不同于普通的reshape, imresize不是单纯的改变图像矩阵的维度,而是能将图片重采样为指定像素,这样给深度学习中训练图像数据带来方便. import ...

  9. 基于C++的ITK图像分割与配准学习笔记1(图像数据表达-图像)

    ITK学习参考资料整理汇总(包含 ItkSoftwareGuide.PDF英文版.ItkSoftwareGuide-2.4.0-中文版.医学图像分割与配准(1ITK初步分册) (1)PDF. 医学图像 ...

最新文章

  1. java 线程---成员变量与局部变量
  2. 分离解析DNS服务器
  3. css 浮动问题 display显示 和 光标设置cursor
  4. 纪中A组模拟赛总结(2021.7.17)
  5. boa服务器实现温湿度显示,SMT车间温湿度分布式远程监控系统的设计
  6. [scikit-learn 机器学习] 2. 简单线性回归
  7. 拥抱创新,持续探索——对话阿里云MVP胡逢法
  8. Numpy高级操作大全!!!
  9. 计算机软件技术职业工作规划,软件技术职业规划书.docx
  10. B/S---控件属性
  11. 【老生谈算法】matlab实现图像复原算法源码——图像复原
  12. 计算机鼠标知识,计算机基础知识:鼠标的使用
  13. flex弹性布局教程-02-容器display设置为flex
  14. 在linux运行php文件
  15. Android ANR 触发原理
  16. 魔兽linux版本,linux下玩warcraft III(魔兽)
  17. 分享一款统计手机使用时间的APP,帮助集中注意力,拒绝手机上瘾,支持双端
  18. python处理Excel实现自动化办公教学(数据筛选、公式操作、单元格拆分合并、冻结窗口、图表绘制等)【三】
  19. 叠片式过滤器原理概述
  20. mysql查询distinct_mysql中select distinct的用法

热门文章

  1. 芯片附近为什么都放 0.1uF 电容 ?
  2. 天嵌科技恭祝大家元宵节快乐
  3. PayPal 注册和使用详解
  4. 自动化软件测试工程师(初面)面试题解析(含答案)
  5. Qt: multiple definition of XXX
  6. 梦茹 java_有关表彰2015-2016学年本科生先进集体、先进个人决定.PDF
  7. 编写程序实现通过有道或百度翻译url对用户输入数据进行翻译_8亿用户AI有道,超强神经网络翻译技术大解密...
  8. 美元人民币汇率API
  9. 关于打印机打印网页出现字迹显示不全的问题心得
  10. Mysql索引类型 normal, unique, full text的区别