- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我想对 dicom 体绘制有更好的了解。
我有一组 dicom 图像,我已经能够从中提取轴向、冠状和矢状切面,如下所示:
我最初想从头开始生成一个 3D 模型,但似乎太难了。
所以我听说了 VTK/ITK,并且我一直在使用这段代码从我的图像集中生成一个 .vtk 文件:
http://www.itk.org/Doxygen46/html/IO_2DicomSeriesReadImageWrite2_8cxx-example.html
它有效,但我需要一些解释:
当我用 ParaView 打开这个文件时,我得到以下结果:
首先,这可能是一个愚蠢的问题,但为什么它是蓝色的?
有没有办法切开并看到模型的内部?
我的目标不是使用 ParaView,我想制作自己的 .vtk 阅读器,我发现这段代码我不记得在哪里,我认为它应该可以工作,但我得到的只是绿色背景,仅此而已:
#include <vtkPolyDataReader.h>
#include <vtkSmartPointer.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
int main ( int argc, char *argv[] ) {
// Parse command line arguments
if (argc != 2) {
std::cerr << "Usage: " << argv[0] << " Filename(.vtk)" << std::endl;
return EXIT_FAILURE;
}
std::string filename = argv[1];
// Read all the data from the file
vtkSmartPointer<vtkPolyDataReader> reader = vtkSmartPointer<vtkPolyDataReader>::New();
reader->SetFileName(filename.c_str());
reader->Update();
// Visualize
vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(reader->GetOutputPort());
vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(renderer);
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindowInteractor->SetRenderWindow(renderWindow);
renderer->AddActor(actor);
renderer->SetBackground(.3, .6, .3); // Background color green
renderWindow->Render();
renderWindowInteractor->Start();
return EXIT_SUCCESS;
}
知道为什么吗?我在 ParaView 中看到我必须激活“音量”模式才能看到我的模型,这里有类似的处理吗?
最后一点非常重要:是否可以修改 .vtk 文件中的 3D 体积?例如,如果我想更改模型特定部分的颜色,VTK 是否提供允许这样做的工具?
最佳答案
这里有很多问题!这里有一些答案。
这是一个完整的示例,它读取一个目录下的所有 DICOM 文件,构建一个体积,使用体积渲染器渲染它,并启用一个盒子小部件以交互方式剪辑体积。
#include "vtkBoxRepresentation.h"
#include "vtkBoxWidget2.h"
#include "vtkCamera.h"
#include "vtkColorTransferFunction.h"
#include "vtkCommand.h"
#include "vtkDICOMImageReader.h"
#include "vtkGPUVolumeRaycastMapper.h"
#include "vtkImageData.h"
#include "vtkInteractorStyle.h"
#include "vtkInteractorStyleTrackballCamera.h"
#include "vtkMath.h"
#include "vtkPiecewiseFunction.h"
#include "vtkPlanes.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkRenderer.h"
#include "vtkVolume.h"
#include "vtkVolumeProperty.h"
// Box interaction callback
class vtkBoxCallback : public vtkCommand
{
public:
static vtkBoxCallback *New(){ return new vtkBoxCallback; }
vtkGPUVolumeRayCastMapper* m_mapper;
vtkPlanes* m_planes;
virtual void Execute( vtkObject* a_caller, unsigned long, void* ){
vtkBoxWidget2* l_box_wdget = vtkBoxWidget2::SafeDownCast( a_caller );
( (vtkBoxRepresentation*)l_box_wdget->GetRepresentation() )->GetPlanes( m_planes );
this->m_mapper->SetClippingPlanes( m_planes );
}
vtkBoxCallback(){}
};
int main( int argc, char *argv[] ){
// Read volume
vtkDICOMImageReader* l_reader = vtkDICOMImageReader::New();
l_reader->SetDirectoryName( "C:/PathToDicomFiles/" );
l_reader->Update();
// Setup rendering stuff
vtkRenderer* l_renderer = vtkRenderer::New();
l_renderer->SetBackground( 0.3, 0.3, 0.3 );
vtkRenderWindow* l_render_windows = vtkRenderWindow::New();
l_render_windows->AddRenderer( l_renderer );
l_render_windows->SetSize( 900, 900 );
vtkInteractorStyleTrackballCamera* l_trackball = vtkInteractorStyleTrackballCamera::New();
vtkRenderWindowInteractor* l_iren = vtkRenderWindowInteractor::New();
l_iren->SetInteractorStyle( l_trackball );
l_iren->SetRenderWindow( l_render_windows );
l_iren->GetInteractorStyle()->SetDefaultRenderer( l_renderer );
l_iren->SetDesiredUpdateRate( 15 );
// Make sure we have an opengl context
l_render_windows->Render();
// Setup GPU volume raycast mapper
vtkGPUVolumeRayCastMapper* l_gpu_mapper = vtkGPUVolumeRayCastMapper::New();
l_gpu_mapper->SetInputConnection( l_reader->GetOutputPort() );
// Setup Volume property
// Window/Level
double wl = 260;
double ww = 270;
// Color function
vtkColorTransferFunction* l_color = vtkColorTransferFunction::New();
l_color->SetColorSpaceToRGB();
l_color->AddRGBPoint( wl - ww / 2, 0, 0, 0 );
l_color->AddRGBPoint( wl - ww / 2 + 94 * ( ww / 255.0 ), 1., 21. / 255.0, 27. / 255.0 );
l_color->AddRGBPoint( wl - ww / 2 + 147 * ( ww / 255.0 ), 1., 176. / 255.0, 9. / 255.0 );
l_color->AddRGBPoint( wl - ww / 2 + 201 * ( ww / 255.0 ), 1., 241. / 255.0, 39. / 255.0 );
l_color->AddRGBPoint( wl - ww / 2 + 255 * ( ww / 255.0 ), 1, 1, 1. );
l_color->Build();
// Opacity function
vtkPiecewiseFunction* l_opacity = vtkPiecewiseFunction::New();
l_opacity->AddPoint( wl - ww / 2, 0 );
l_opacity->AddPoint( wl + ww / 2, 1 );
// Volume property, light, shading
vtkVolumeProperty* l_volume_property = vtkVolumeProperty::New();
l_volume_property->SetColor( l_color );
l_volume_property->SetScalarOpacity( l_opacity );
l_volume_property->SetInterpolationTypeToLinear();
l_volume_property->ShadeOn();
l_volume_property->SetAmbient( 0.15 );
l_volume_property->SetDiffuse( 0.8 );
l_volume_property->SetSpecular( 0.25 );
l_volume_property->SetSpecularPower( 40 );
// Put everything together
vtkVolume* l_volume = vtkVolume::New();
l_volume->SetProperty( l_volume_property );
l_volume->SetMapper( l_gpu_mapper );
l_renderer->AddVolume( l_volume );
l_renderer->ResetCamera();
// setup Box interactive widget
vtkBoxRepresentation* l_box_rep = vtkBoxRepresentation::New();
l_box_rep->SetInsideOut( true );
vtkBoxWidget2* l_voi_widget = vtkBoxWidget2::New();
l_voi_widget->SetRepresentation( l_box_rep );
l_voi_widget->SetInteractor( l_iren );
l_voi_widget->GetRepresentation()->SetPlaceFactor( 1. );
l_voi_widget->GetRepresentation()->PlaceWidget( l_reader->GetOutput()->GetBounds() );
l_voi_widget->SetEnabled( true );
vtkPlanes* l_planes = vtkPlanes::New();
vtkBoxCallback* l_callback = vtkBoxCallback::New();
l_callback->m_mapper = l_gpu_mapper;
l_callback->m_planes = l_planes;
l_voi_widget->AddObserver( vtkCommand::InteractionEvent, l_callback );
// Go rendering !
l_iren->Start();
// Memory cleanup
l_reader->Delete();
l_renderer->Delete();
l_render_windows->Delete();
l_trackball->Delete();
l_iren->Delete();
l_gpu_mapper->Delete();
l_color->Delete();
l_opacity->Delete();
l_volume_property->Delete();
l_volume->Delete();
l_voi_widget->Delete();
l_planes->Delete();
l_callback->Delete();
}
作为一般建议,我建议您阅读 VTK examples这应该可以帮助您了解所有 VTK 功能。
希望对您有所帮助:)
关于c++ - 从 .dcm 文件生成和读取 .vtk 文件,以及修改模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36193779/
我正在尝试创建一个用于查看和分析 DICOM 切片的应用程序。我已经在 MATLAB 中完成了这个应用程序,但 MATLAB 没有足够的工具来构建真正漂亮的 GUI,而且 3D 图像很糟糕。因此,我尝
我正在将应用程序移植到 FreePasal/Lazarus 并发现他们的表单转换器不好。我有一个小型实用程序应用程序,每次进行更改时,我都需要重新转换、重新布局和重新导入图形。另外,有些事情很困惑。
Closed. This question is off-topic。它当前不接受答案。 想改善这个问题吗? Update the question,因此它是on-topic,用于堆栈溢出。 已关闭8
我需要一些用于结构报告(超声波)的示例 dcm 文件。谁能帮帮我? 最佳答案 下面链接中的报告 19 表示美国结构化报告,但我不确定它是否正是您要查找的 SOP 类: http://www.dclun
也许是一个简单的问题,但我没有取得进展,希望得到帮助。 我有一个大小为 422 的列表。在索引 0 中,有 135 个 .dcm 图像的文件路径。例如 '~/images/0001.dcm','~/i
如何使用 DCMTK 库从 .dcm 文件获取像素数据作为数组变量?我正在使用 this site for preference 并不起作用,数据结果与原始图片有很大不同。 最佳答案 您引用的代码只是
我找到了一种使用 vtk 显示 dcm 图像的方法。但是 vtk 对我想要的来说太多了,我只想显示一个 dcm 图像。 dcmtk 将为我处理 dcm 图像。那么有没有一种简单的方法可以显示 dcm
我有低剂量 CT 图像数据库,是从 this link 下载的。 ,这些图像的格式为 .dcm,并且我无法使用 BurreredImage 读取这些图像,所以我的想法是使用任何编辑器打开这些图像,然后
我想对 dicom 体绘制有更好的了解。 我有一组 dicom 图像,我已经能够从中提取轴向、冠状和矢状切面,如下所示: 我最初想从头开始生成一个 3D 模型,但似乎太难了。 所以我听说了 VTK/I
JPEG 和 PNG 如何转换为 dicom 可读图像?网上好像没有这方面的信息。我看过关于将 dicom 图像转换为 JPEG 的帖子,但没有看到相反的帖子。我尝试了下面的代码,但是我得到的图像(d
我正在尝试从 PACS 服务器下载 dcm 镜像,但这会生成一个空的 dcm 文件。 代码如下: public void VisoresPacsController(string ipAddress,
我陷入了 1.2.840.10008.1.2.4.70 - JPEG Lossless, Non-Hierarchical, First-Order Prediction使用 ImageIo 将 DC
根据lesson 15我将 .dcm 文件传递给 volume。我没有收到任何错误(例如,我之前没有遇到任何解析错误)但没有显示任何内容。 .dcm 文件可能有什么问题? 这是我使用的代码的摘录:
DICOM - 医学数字成像和通信,是一种处理、存储、打印和传输医学成像信息的标准。它包括文件格式定义和网络通信协议(protocol)。 我想在我的 ios 项目中写入 .dcm 文件。请给我建议任
我看过官方的 pynetdicom 文档,但我没有正确的事件处理程序(用于 SCU)接收图像。 首先,我创建了所需的 .dcm 文件数据集并使用了 C-GET 命令,它实际上应该为我提供 .dcm 文
我想要访问 Azure Synapse Analytics 上 pyspark 笔记本中 ADLS gen2 上的容器中存储的 .dcm (dicom) 类型的文件。我正在使用 pydicom 访问文
我是一名优秀的程序员,十分优秀!