2016-03-24 8 views
2

Я хотел бы получить лучшее представление об рендеринг объема dicom.Создание и чтение файлов .vtk из .dcm-файлов и модифицирующей модели

У меня есть набор DICOM изображений, из которых я был в состоянии извлечь осевые, корональные и сагиттальные сокращения, следующим образом:

enter image description here

Я сначала хотел, чтобы создать 3D-модель с нуля , но, похоже, это слишком сложно.

Так что я слышал о ВТК/ИТК, и я использую этот код, чтобы сгенерировать .vtk файл из моего набора изображений:

http://www.itk.org/Doxygen46/html/IO_2DicomSeriesReadImageWrite2_8cxx-example.html

Это работает, но мне нужно несколько объяснений:

Когда я открываю этот файл с ParaView, я получаю следующий результат:

enter image description here

Во-первых, это может быть глупый вопрос, но почему он синий?

Есть ли способ отрезать и увидеть внутреннюю часть модели?

Моя цель - не использовать ParaView, и я хотел бы сделать свой собственный .vtk reader, я нашел этот код, я не помню, где, я думаю, предполагается работать, но все, что я получаю от него это зеленый фон с не более:

#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, что мне пришлось активировать режим «Volume», чтобы увидеть мою модель, есть ли что-то похожее на здесь?

Последнее, что очень важно: возможно ли изменить объем 3D в файле .vtk? Например, если я хочу изменить цвет определенной части модели, делает ли VTK инструменты, позволяющие это?

ответ

1

Много вопросов здесь! Вот некоторые ответы.

  • Отрисовка является синей, потому что таблица поиска является стандартной по умолчанию (от синего до красного) в парагенезе. Вы можете отредактировать его, используя color map editor
  • Есть действительно какой-то способ «вырезать» внутри данных, пожалуйста, посмотрите пример, опубликованный после.
  • пример не работает, потому что вы пытаетесь загрузить vtkImageData с помощью polydata (сетка) читатель
  • Именно поэтому вы должны выбрать «Volume» в ParaView, это потому, что ваши данные тома (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, что должно поможет вам понять все возможности ВТК.

Надежда, что помогает :)

+0

Спасибо за ваш ответ, я думаю, что вы сделали мой день: D есть тысяча новых вопросов о том, что в настоящее время, но я сначала попытаться понять, как этот код работает :) Действительно, редактирование значения внутри модели не сейчас, но мне просто нужно было знать, будет ли это возможно :) Еще раз спасибо! – Charrette

 Смежные вопросы

  • Нет связанных вопросов^_^