Hi,<br><br><br>I've done a very simple MIP-visualizer with VTK 5.2 (Thanks to Aurélie for the help).<br><br>But I'm a little disappointed because it's very slow. The refresh time of the window is very long.<br>
<br>I make tests with a DICOM Series (36 CT-slices).<br><br>Here's the program very simplified :<br><br><span style="font-family: courier new,monospace;">#include "vtkDICOMImageReader.h"</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">#include "vtkImageData.h"</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">#include "vtkImageShiftScale.h"</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">#include "vtkPiecewiseFunction.h"</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">#include "vtkRenderer.h"</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">#include "vtkRenderWindow.h"</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">#include "vtkRenderWindowInteractor.h"</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">#include "vtkVolume.h"</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">#include "vtkVolumeProperty.h"</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">#include "vtkVolumeRayCastMapper.h"</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">#include "vtkVolumeRayCastMIPFunction.h"</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">#include <sstream></span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">using namespace std;</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">int main (int argc, char **argv)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">{</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">if( argc < 2 )</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">{</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">std::cerr << argv[0] << " rep";</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">return 1;</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">}</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">else</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">{</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">string rep;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">rep = argv[1];</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">vtkDICOMImageReader * reader; </span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">reader = vtkDICOMImageReader::New(); </span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">string dir(""); </span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">ostringstream oss(dir.c_str());</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">oss << rep ;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">dir = oss.str(); </span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">const char* adresse = dir.c_str(); </span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">reader->SetDirectoryName(adresse);</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">cout << adresse << endl;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">reader->Update();</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">reader->SetDataScalarTypeToShort();</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">reader->UpdateWholeExtent(); </span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">reader->GetOutput()->UpdateInformation(); </span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">vtkRenderer* renderer = vtkRenderer::New();</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">vtkRenderWindow* renWin = vtkRenderWindow::New();</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">renWin->AddRenderer(renderer);</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">vtkRenderWindowInteractor* iren = vtkRenderWindowInteractor::New();</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">iren->SetRenderWindow(renWin);</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">double range[2];</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">reader->GetOutput()->GetScalarRange(range);</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">double min = range[0];</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">double max = range[1];</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">double diff = max-min;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">double slope = 255.0/diff;</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">double inter = -slope*min;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">double shift = inter/slope;</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">vtkImageShiftScale *vtkImageCast = vtkImageShiftScale::New();</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">vtkImageCast->SetInput(reader->GetOutput());</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">vtkImageCast->SetShift(shift);</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">vtkImageCast->SetScale(slope);</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">vtkImageCast->SetOutputScalarTypeToUnsignedShort();</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">vtkImageCast->Update(); </span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">vtkImageCast->GetOutput()->GetScalarRange(range);</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">double level = 0.5 * (range[1] + range[0]);</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">double window = range[1] - range[0];</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">vtkPiecewiseFunction *opacityTransferFunction = vtkPiecewiseFunction::New();</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">opacityTransferFunction->AddPoint( level - window/2 , 0.0 );</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">opacityTransferFunction->AddPoint( level + window/2 , 1.0 );</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">vtkPiecewiseFunction *grayTransferFunction = vtkPiecewiseFunction::New();</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">grayTransferFunction->AddSegment( level - window/2, 0.0 , level + window/2, 1.0 );</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">vtkVolumeProperty *mipProperty;</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">mipProperty = vtkVolumeProperty::New();</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">mipProperty->SetScalarOpacity( opacityTransferFunction );</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">mipProperty->SetColor( grayTransferFunction );</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">mipProperty->SetInterpolationTypeToLinear();</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">vtkVolumeRayCastMIPFunction* mipFunction = vtkVolumeRayCastMIPFunction::New();</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">mipFunction->SetMaximizeMethodToOpacity();</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">vtkVolumeRayCastMapper* volumeMapper = vtkVolumeRayCastMapper::New();</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">volumeMapper->SetVolumeRayCastFunction( mipFunction ); </span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">volumeMapper->SetInput( vtkImageCast->GetOutput() );</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">vtkVolume* volume = vtkVolume::New();</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">volume->SetMapper( volumeMapper );</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">volume->SetProperty( mipProperty );</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">renderer->AddViewProp( volume );</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">renderer->Render();</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">renWin->SetSize( 1000 , 700 );</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">iren->Initialize();</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">iren->Start();</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">iren->Delete();</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">renWin->Delete();</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">renderer->Delete();</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">return 0;</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">}</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">}</span><br><br><br><font face="arial,helvetica,sans-serif">and here's the CMakeLists.txt :<br>
<br><br><span style="font-family: courier new,monospace;">PROJECT (Project)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">FIND_PACKAGE(VTK REQUIRED)</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">IF(NOT VTK_USE_RENDERING)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> MESSAGE(FATAL_ERROR "Example ${PROJECT_NAME} requires VTK_USE_RENDERING.")</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">ENDIF(NOT VTK_USE_RENDERING)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">INCLUDE(${VTK_USE_FILE})</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">ADD_EXECUTABLE(MIP_TEST MIP_TEST.cxx)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">TARGET_LINK_LIBRARIES(MIP_TEST vtkVolumeRendering)</span><br>
<br><br>To test you just have to give as input a repertory of a DICOM Serie.<br><br><br><br>My porpose is </font><font face="arial,helvetica,sans-serif">obviously </font><font face="arial,helvetica,sans-serif">to create a program more "complicated" than this one, but it will be impossible if it's so slow.<br>
<br>Do you have any advice, remarks,...? to make it quicker ?<br><br><br>Thank you very much,<br><br>Regards,<br><br><br><br>Stéphane<br></font>