QVTKWidget+itk+vtk 交互问题

现在做到单张dicom图片读取头信息已经显示的部分,按照东灵工作室写的教程例子先写了一下,他们使用ImageToVTKImageFilter类来对itk和vtk进行数据连接,在用vtk的vtkImageViewer2类连接qt的qvtkwidget进行显示。原理是(来源 http://codeplanet.sinaapp.com/?p=361):

ITK的数据流采用如图1所示流水线(pipeline)作业方式。遵循此方式,所处理的数据来龙去脉清晰明了。在图1中,数据流左边的ImageFile代表待处理的图像文件,而右边ImageFile则代表处理后的图像文件。ImageFileReade:将存贮图像文件读人到内存,形成Image,再调用所希望处理的Fileter算法(比如滤波、分割、配准等具体算法),将对读人的图像数据进行处理。最后,ImageFileWriter将处理的图像数据结果保存,或输人给图形显示系统(如VTK),进行数据可视化。


VTK是C++语言开发的、公开源码的、面向对象的数据可视化软件开发包,并不单纯用于医学图像数据的可视化。VTK支持跨平台的编译,可以应用于Windows,Linux等系统。VTK支持包括数量、向量、张量、结构和测定体积等方法一系列可视化算法,VTK还支持包括建模。VTK的数据流同样采用流水线作业方式,如图2所示。


vtkSource为整个可视化流的开始,比如读取、生成数据等。vtkFilte对输入源数据进行各种处理,与ITK的Fileter类似。原始数据经过各种Filte:的处理后,再由vtkMappe:转换(或映射)成可供其它算法模块直接使用的数据形式,比如为几何数据。vtkActor类用来描述绘制场景中一个实体,即绘制场景的某个角色(Actor)。通过SetMapper()方法,可以将几何数据的属性传递给Actor,再由vtkRenderer类将处理后的数据结果显示出来。
由于ITK和VTK的数据流都是采用流水线作业形式,比较方便地利用类库本身提供的类型转换类来实现,如图3所示。通过ITKtoVTKImageFilter类操作将ITK和VTK的图像数据连接了起来,VTK负责图像数据的显示,而ITK负责图像的处理,其中VTK的Image Viewe:是一个很方便实现的图像显示类,它在内部管理着vtkImageWindow, vtkRenderer, vtkActor2D和vtkImageMapper等图象类,实现图像查看、显示和可视化功能。


因此,东灵他们例子的代码是这么写的:

 // 将reader的输出作为m_pImageViewer的输入,并设置m_pImageViewer与渲染器m_pRenderer的关联  
       m_pImageViewer->SetInput(reader->GetOutput());  
       m_pImageViewer->UpdateDisplayExtent();  
       m_pImageViewer->SetRenderWindow(m_QVTKWidget->GetRenderWindow());  
       m_pImageViewer->SetRenderer(m_pRenderder);  
       m_pImageViewer->SetupInteractor(m_QVTKWidget->GetRenderWindow()->GetInteractor());  
       m_pImageViewer->SetSliceOrientationToXY(); //默认就是这个方向的  
       m_pImageViewer->GetImageActor()->InterpolateOff();  
       m_pRenderder->ResetCamera();  
       m_pRenderder->DrawOn();  
       m_QVTKWidget->GetRenderWindow()->Render();  

我用来实现dicom图像显示及交互,然后发现了只要一点击图片,程序就发生崩溃的错误。网上找了好多原因也没检查出来,后来选择不用vtkimageview2这个类而改用传统的写法,实例化vtk的render、actor、renderwindow,renderwindowinteractor后进行,成功实现。

之后再传到qvtkwidget,也成功了。

后来才发现东灵他们的代码没有new一个vtkRenderWindowInteractor,我在程序初始化的时候增加一个

vtkSmartPointer< vtkRenderWindowInteractor >  m_pInteractor = vtkSmartPointer< vtkRenderWindowInteractor >::New();
然后设置

qvtkWidget->GetRenderWindow()->SetInteractor(m_pInteractor);
测试发现可以成功实现。


ps:在网上搜索解决问题的时候也看到了一个重点就是

重载的vtkInteractorStyleTrackballCamera 也可以是子类 vtkInteractorImage. 同时要注意qvtk 与vtkImageViewer的 RenderWindow与Interactor的共享, 多以qvtk为准. SetInteractor 一定要在 SetRenderWindow之前, 以避免error出现.

-----------------------------------------------------------------------------------------------------

参考博客:

http://blog.csdn.net/www_doling_net/article/details/8668870

http://codeplanet.sinaapp.com/?p=361

http://blog.csdn.net/colddie/article/details/8966521

感谢作者提供的经验。

————————————————

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我会尽力回答你的问题。首先,你需要安装vite和vue3,可以在命令行中使用以下命令进行安装: ``` npm install -g vite npm install vue@next ``` 然后,你需要安装Vtk.js28版本和Itk.js14版本。你可以在以下链接中找到安装指南: - https://kitware.github.io/vtk-js/docs/installation.html - https://insightsoftwareconsortium.github.io/itk-js/docs/installation.html 接下来,你可以创建一个Vue3项目,并将Vtk.js和Itk.js添加到项目中。在`main.js`文件中,你可以添加以下代码: ```javascript import vtkFullScreenRenderWindow from 'vtk.js/Sources/Rendering/Misc/FullScreenRenderWindow'; import vtkSTLReader from 'vtk.js/Sources/IO/Geometry/STLReader'; import vtkActor from 'vtk.js/Sources/Rendering/Core/Actor'; import vtkMapper from 'vtk.js/Sources/Rendering/Core/Mapper'; import vtkRenderer from 'vtk.js/Sources/Rendering/Core/Renderer'; import vtkInteractorStyleTrackballCamera from 'vtk.js/Sources/Interaction/Style/InteractorStyleTrackballCamera'; import { readImageArrayBuffer } from 'itk'; // 加载STL模型 function loadSTLModel(renderer, filePath) { const reader = vtkSTLReader.newInstance(); reader.setUrl(filePath).then(() => { const mapper = vtkMapper.newInstance(); const actor = vtkActor.newInstance(); mapper.setInputData(reader.getOutputData()); actor.setMapper(mapper); renderer.addActor(actor); renderer.resetCamera(); }); } // 加载ITK图像 async function loadITKImage(renderer, filePath) { const arrayBuffer = await readImageArrayBuffer(filePath); // TODO: 在这里添加ITK图像的处理代码 } // 创建四个渲染器 function createRenderers(container) { const renderers = []; for (let i = 0; i < 4; i++) { const renderer = vtkRenderer.newInstance(); renderer.setViewport([(i % 2) * 0.5, Math.floor(i / 2) * 0.5, (i % 2) * 0.5 + 0.5, Math.floor(i / 2) * 0.5 + 0.5]); renderers.push(renderer); } const fullScreenRenderWindow = vtkFullScreenRenderWindow.newInstance({ rootContainer: container, containerStyle: { height: '100%', display: 'flex', }, }); renderers.forEach((renderer) => { fullScreenRenderWindow.addRenderer(renderer); }); return renderers; } // 初始化交互器 function initInteractor(renderer) { const interactor = renderer.getRenderWindow().getInteractor(); const style = vtkInteractorStyleTrackballCamera.newInstance(); interactor.setInteractorStyle(style); } // 在四个渲染器中分别加载STL模型和ITK图像 function loadModels(container, stlFilePath, itkFilePath) { const renderers = createRenderers(container); renderers.forEach((renderer) => { initInteractor(renderer); loadSTLModel(renderer, stlFilePath); loadITKImage(renderer, itkFilePath); }); } // 加载模型 loadModels(document.getElementById('container'), 'path/to/stl/file.stl', 'path/to/itk/file.mha'); ``` 在上述代码中,我们首先导入了所需的Vtk.js和Itk.js模块。然后,我们定义了三个函数:`loadSTLModel`用于加载STL模型,`loadITKImage`用于加载ITK图像,`createRenderers`用于创建四个渲染器。接下来,我们定义了`initInteractor`函数来初始化交互器。最后,我们定义了`loadModels`函数来在四个渲染器中分别加载STL模型和ITK图像。 你可以将上述代码复制到你的项目中,并根据实际情况修改文件路径和其他参数。希望这可以帮助你实现加载STL模型并进行四视图分割功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值