当前位置: 首页 > ops >正文

VTK—三维图像重建和剖切

一、获取三维图像数据

1.vtkMetaImageReader 可以读取*.mhd、*.mha格式的图像文件

#include <vtkMetaImageReader.h>int main()
{vtkNew<vtkMetaImageReader>reader;reader->SetFileName("head.mhd");reader->Update();
}

2.vtkJPEGReader、vtkPNGReader可以读取一系列普通2d图像文件,然后使用沿着Z轴方向堆叠起来,从而获取3D图像数据

#include <vtkJPEGReader.h>
#include <vtkImageAppend.h>int main()
{//读取普通JPEG图像vtkNew<vtkJPEGReader>reader;//准备把多个普通2D图像沿着Z轴堆叠成3D图像vtkNew<vtkImageAppend>image;image->SetAppendAxis(2);//临时文件名字char name[64] = {};//读取100张普通2D图像,文件名字head001.jpg,head002.jpg...for (int i = 0; i < 100; i++){sprintf_s(name, 64, "head%03d.jpg", i + 1);reader->SetFileName(name);image->AddInputConnection(reader->GetOutputPort());}}

3.vtkImageData可以允许自己定义一个3d图像

//简化一下构造对象的写法
#define CREATE(type,name) vtkNew<type> name//自定义一个三维图像,维度128*128*128,像素值自己生成const int dim[3] = { 128,128,128 };//使用一个数据组存储每个点的像素值CREATE(vtkUnsignedCharArray,scalar);scalar->SetName("Scalar");for (int i = 0; i < dim[2]; i++)for (int j = 0; j < dim[1]; j++)for (int k = 0; k < dim[0]; k++){unsigned char value = 1.0 * (k+j+i)/dim[0]/3 * 255;scalar->InsertNextTuple1(value);}//定义图像维度等基本参数CREATE(vtkImageData,data);data->SetDimensions(dim[0],dim[1],dim[2]);data->SetOrigin(0, 0, 0);data->SetSpacing(1, 1, 1);
//上面生成的像素值作为点数据的标量data->GetPointData()->SetScalars(scalar);

二、体素绘制的常规步骤

1.获取图像数据(vtkImageData)

2.选择合适的映射器(vtkVolumeMapper) 

3.定义属性数据(vtkVolumeProperty)

        3.1设置颜色传递函数(vtkColorTransferFunction)—— 定义像素值和渲染颜色的对应关系

        3.2设置不透明度传递函数(vtkPiecewiseFunction)—— 定义像素值和不透明度的对应关系

        3.3设置环境亮度(SetAmbient(double))

        3.4设置漫反射亮度(SetDiffuse(double))

        3.5设置镜反射亮度(SetSpecular(double))

4.创建渲染对象(vtkVolume)

        4.1设置映射器(SetMapper)

        4.2设置属性(SetProperty)

5.常规的渲染管线

        5.1 vtkRenderer

        5.2 vtkRenderWindow

        5.3 vtkRenderWindowInteractor

//选则常用的映射器CREATE(vtkFixedPointVolumeRayCastMapper,mapper);mapper->SetInputData(data);	//颜色传递函数,像素值与颜色的对应关系CREATE(vtkColorTransferFunction,color);color->AddRGBPoint(0,10,10,0 );color->AddRGBPoint(127,255,255,0);color->AddRGBPoint(255,10,10,0);//不透明度传递函数,像素值与不透明度的对应关系CREATE(vtkPiecewiseFunction,opacity);opacity->AddPoint(10, 0.05);opacity->AddPoint(127, 0.9);opacity->AddPoint(250, 0.051);//体属性CREATE(vtkVolumeProperty,property);property->SetColor(color);                      //颜色传递函数property->SetScalarOpacity(opacity);	        //不透明度传递函数property->SetAmbient(0.3);						//环境亮度       property->SetDiffuse(0.5);						//漫反射亮度property->SetSpecular(0.2);						//镜面反射亮度//可显示的体素CREATE(vtkVolume,volume);volume->SetMapper(mapper);volume->SetProperty(property);//下面是常规的可视化管线CREATE(vtkRenderer, render);CREATE(vtkRenderWindow, window);window->SetSize(800, 600);CREATE(vtkRenderWindowInteractor, inter);CREATE(vtkInteractorStyleSwitch, style);style->SetCurrentStyleToTrackballCamera();render->AddVolume(volume);	window->AddRenderer(render);inter->SetRenderWindow(window);inter->SetInteractorStyle(style);

三、交互剖切3D图像

1.在窗口中添加一个vtkPlaneWidget交互对象

2.给vtkPlaneWidget添加一个回调对象

3.交互拖动vtkPlaneWidget过程中不断获取当前平面,使用该平面剖切图像

//实例化一个回调对象,实现3D图像剖切CREATE(myCallback,callback);callback->m_mapper = mapper;//添加一个平面小部件,改变剖切面CREATE(vtkPlaneWidget,planeWidget);planeWidget->SetInteractor(inter);planeWidget->SetCurrentRenderer(render);planeWidget->SetOrigin(0, 0, -100);planeWidget->SetPoint1(200, 0, -100);planeWidget->SetPoint2(0, 200, -100);planeWidget->SetRepresentationToWireframe();planeWidget->AddObserver(vtkCommand::InteractionEvent, callback);planeWidget->On();

四、完整的代码


#include <cassert>//一些初始化工作,否则会报错
#include <vtkAutoInit.h>VTK_MODULE_INIT(vtkRenderingOpenGL2)
VTK_MODULE_INIT(vtkInteractionStyle)
VTK_MODULE_INIT(vtkRenderingFreeType)
VTK_MODULE_INIT(vtkRenderingVolumeOpenGL2)
VTK_MODULE_INIT(vtkRenderingContextOpenGL2)//常用和可视化管线头文件
#include <vtkNew.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkPolyDataMapper.h>
#include <vtkInteractorStyleSwitch.h>
#include <vtkRenderWindowInteractor.h>#include <vtkPlane.h>
#include <vtkPlanes.h>
#include <vtkVolume.h>
#include <vtkPoints.h>
#include <vtkCommand.h>
#include <vtkPointData.h>
#include <vtkImageData.h>
#include <vtkAxesActor.h>
#include <vtkPlaneWidget.h>
#include <vtkDoubleArray.h>
#include <vtkVolumeProperty.h>
#include <vtkPiecewiseFunction.h>
#include <vtkUnsignedCharArray.h>
#include <vtkColorTransferFunction.h>
#include <vtkFixedPointVolumeRayCastMapper.h>//简化一下构造对象的写法
#define CREATE(type,name) vtkNew<type> name//回调对象的写法
class myCallback :public vtkCommand
{
public://不实现这个函数,无法使用vtkNewstatic myCallback* New(){return new myCallback;}//真正执行工作的函数,必须要实现void Execute(vtkObject* caller, unsigned long eventId, void* callData)override{assert(m_mapper);vtkPlaneWidget* widget = vtkPlaneWidget::SafeDownCast(caller);assert(widget);//获取交互小部件平面CREATE(vtkPlane,plane);widget->GetPlane(plane);//获取交互小部件的平面原点CREATE(vtkPoints,points);points->InsertNextPoint(plane->GetOrigin());//获取交互小部件的平面法向量CREATE(vtkDoubleArray, normals);;normals->SetNumberOfComponents(3);normals->InsertNextTuple3(plane->GetNormal()[0], plane->GetNormal()[1], plane->GetNormal()[2]);//使用一组平面剖切,组内可以只有一个平面CREATE(vtkPlanes,planes);planes->SetPoints(points);planes->SetNormals(normals);//使用平面剖切三维对象,支持平面组m_mapper->SetClippingPlanes(planes);}//三维重建的映射器vtkFixedPointVolumeRayCastMapper* m_mapper = nullptr;
};int main()
{//自定义一个三维图像,维度128*128*128,像素值自己生成const int dim[3] = { 128,128,128 };CREATE(vtkUnsignedCharArray,scalar);scalar->SetName("Scalar");for (int i = 0; i < dim[2]; i++)for (int j = 0; j < dim[1]; j++)for (int k = 0; k < dim[0]; k++){unsigned char value = 1.0 * (k+j+i)/dim[0]/3 * 255;scalar->InsertNextTuple1(value);}CREATE(vtkImageData,data);data->SetDimensions(dim[0],dim[1],dim[2]);data->SetOrigin(0, 0, 0);data->SetSpacing(1, 1, 1);data->GetPointData()->SetScalars(scalar);//选则常用的映射器CREATE(vtkFixedPointVolumeRayCastMapper,mapper);mapper->SetInputData(data);	//颜色传递函数,像素值与颜色的对应关系CREATE(vtkColorTransferFunction,color);color->AddRGBPoint(0,10,10,0 );color->AddRGBPoint(127,255,255,0);color->AddRGBPoint(255,10,10,0);//不透明度传递函数,像素值与不透明度的对应关系CREATE(vtkPiecewiseFunction,opacity);opacity->AddPoint(10, 0.05);opacity->AddPoint(127, 0.9);opacity->AddPoint(250, 0.051);//体属性CREATE(vtkVolumeProperty,property);property->SetColor(color);                      //颜色传递函数property->SetScalarOpacity(opacity);	        //不透明度传递函数property->SetAmbient(0.3);						//环境亮度       property->SetDiffuse(0.5);						//漫反射亮度property->SetSpecular(0.2);						//镜面反射亮度//可显示的体素CREATE(vtkVolume,volume);volume->SetMapper(mapper);volume->SetProperty(property);//下面是常规的可视化管线CREATE(vtkRenderer, render);CREATE(vtkRenderWindow, window);window->SetSize(800, 600);CREATE(vtkRenderWindowInteractor, inter);CREATE(vtkInteractorStyleSwitch, style);style->SetCurrentStyleToTrackballCamera();render->AddVolume(volume);	window->AddRenderer(render);inter->SetRenderWindow(window);inter->SetInteractorStyle(style);//添加一个坐标轴,指示方向CREATE(vtkAxesActor,axes);axes->SetTotalLength(50, 50, 50);render->AddActor(axes);//实例化一个回调对象,实现3D图像剖切CREATE(myCallback,callback);callback->m_mapper = mapper;//添加一个平面小部件,改变剖切面CREATE(vtkPlaneWidget,planeWidget);planeWidget->SetInteractor(inter);planeWidget->SetCurrentRenderer(render);planeWidget->SetOrigin(0, 0, -100);planeWidget->SetPoint1(200, 0, -100);planeWidget->SetPoint2(0, 200, -100);planeWidget->SetRepresentationToWireframe();planeWidget->AddObserver(vtkCommand::InteractionEvent, callback);planeWidget->On();//开始交互inter->Start();return 0;
}

http://www.xdnf.cn/news/8190.html

相关文章:

  • 【博通芯片方案】调试指令详解版二(无线)
  • 高等数学-连续
  • 【RocketMQ 生产者和消费者】- 生产者启动源码-创建 MQClientInstance(2)
  • yarn 命令运行问题 bug
  • 催化燃烧型氢气传感器的响应速度和恢复速度如何?
  • os:进程与线程上
  • OS虚拟内存管理
  • 武汉火影数字|数字企业馆制作 多媒体数字化展厅
  • 4 SLAM(同步定位与建图)学习指南
  • 【北邮通信系统建模与仿真simulink笔记】(2)2.3搭建仿真模型模块操作运行仿真
  • F5《2025年应用战略现状》报告:AI 落地加速,企业战略从讨论迈向行动
  • 从原理到实践:一文详解残差网络
  • 【Bluedroid】蓝牙 HID Host connect全流程源码解析
  • 简说Qt信号和槽
  • 雅思英语考试基本介绍
  • 案例分享——福建洋柄水库大桥智慧桥梁安全监测
  • 一文讲透:如何用AI生成时序图
  • 六:操作系统虚拟内存之帧分配
  • 鸿蒙Flutter实战:23-混合开发详解-3-源码模式引入
  • MaskGIT:掩码图像生成经典方法
  • Github超19k+ strar的实时协同编辑的开源框架yjs
  • 楼宇智能照明控制系统设计与实现(基于组态软件)
  • Ubuntu更新源服务器时出现:pk-client-error-quark
  • 抖音IP属地跟无线网有关吗?如何更改
  • 从LCD1602显示实验看嵌入式仿真教学平台如何革新高校实践教育
  • “人工智能+多学科”选题思路,2025热点AI+(180个)
  • Linux进程信号(五)之捕捉信号
  • 已将析构函数隐式定义为“已删除”错误
  • 场景化应用实战系列六:检索问答系统
  • VisionPro_几何学工具