[vtkusers] Why multi-frame dicom can not be rendered correctly by VTK?
heyuanlie
heyuanlie at gmail.com
Sun Sep 23 22:56:05 EDT 2012
Hi everyone,
I use VTK to render the CT series (series dicom files) and SPECT multi-frame
(multi-frame in one dicom file) which came from the same study. The CT
series and SPECT multi-frame are belong to the same patient and the number
of slices are same.
The problem is the CT series can be rendered very well, but the SPECT
multi-frame can't be rendered correctly . The result of the SPECT
mutli-frame rendering just like all slices being squeezed together (compare
the CT and the SPECT rendering results blow).
<http://vtk.1045678.n5.nabble.com/file/n5716270/render.png>
I've try the following methods:
vtkImageResample::SetAxisOutputSpacing
vtkImageResample::SetOutputSpacing
vtkImageResize::SetOutputSpacing
vtkImageResize::SetMagnificationFactors
But can't make any better.
Could you help me, please!
The following codes are used to render CT series:
int QtItkVtkViewMDI::volumeRenderCTSeriesNormal()
{
if( directoryCTSeries.isEmpty()) // directoryCTSeries is a string
containing the path of the CT series.
return false;
int clip = 0;
double frameRate = 2.0;
const unsigned int Dimension = 3;
double opacityWindow = 1500; // window width
double opacityLevel = 450; // window level
bool independentComponents=true;
typedef signed short PixelType;
typedef itk::Image< PixelType, Dimension > ImageType; // define
image type
typedef itk::ImageSeriesReader< ImageType > ReaderType; // define
reader type
ReaderType::Pointer reader = ReaderType::New();
typedef itk::GDCMImageIO ImageIOType; // define itk::GDCMImageIO
object access the GDCM library for reading DICOM files
ImageIOType::Pointer dicomIO = ImageIOType::New();
reader->SetImageIO( dicomIO ); // connect the itk::GDCMImageIO object to
the reader
typedef itk::GDCMSeriesFileNames NamesGeneratorType;
NamesGeneratorType::Pointer nameGenerator = NamesGeneratorType::New();
nameGenerator->SetDirectory( directoryCTSeries.toStdString() ); // set the
directory which contains the DICOM files
try
{
typedef std::vector< std::string > SeriesIdContainer;
const SeriesIdContainer & seriesUID = nameGenerator->GetSeriesUIDs();
std::string seriesIdentifier;
seriesIdentifier = seriesUID.begin()->c_str();
typedef std::vector< std::string > FileNamesContainer;
FileNamesContainer fileNames;
fileNames = nameGenerator->GetFileNames( seriesIdentifier );
reader->SetFileNames( fileNames );
try
{
reader->Update();
}
catch (itk::ExceptionObject &ex)
{
//std::cout << ex << std::endl;
return EXIT_FAILURE;
}
}
catch (itk::ExceptionObject &ex)
{
//std::cout << ex << std::endl;
return EXIT_FAILURE;
}
typedef itk::ImageToVTKImageFilter<ImageType> ConnectorType;
//ReaderType::Pointer reader = ReaderType::New();
ConnectorType::Pointer connector = ConnectorType::New();
connector->SetInput( reader->GetOutput() );
vtkImageImport * readerImageImport = connector->GetImporter();
vtkImageResample * resample = vtkImageResample::New();
resample->SetInputConnection( readerImageImport->GetOutputPort() );
// Create the renderer, render window and interactor
vtkRenderer *renderer = vtkRenderer::New();
vtkRenderWindow *renWin = vtkRenderWindow::New();
interactor = vtkWin32RenderWindowInteractor::New();
interactorStyle = vtkInteractorStyleTrackballCamera::New();
interactor->SetInteractorStyle(interactorStyle);
interactor->SetRenderWindow(renWin);
interactor->SetDesiredUpdateRate(frameRate / (1+clip) );
interactor->GetInteractorStyle()->SetDefaultRenderer(renderer);
// Create our volume and mapper
vtkVolume *volume = vtkVolume::New();
vtkFixedPointVolumeRayCastMapper *mapper =
vtkFixedPointVolumeRayCastMapper::New();
mapper->SetInputConnection( resample->GetOutputPort() );
// Create our transfer function
vtkColorTransferFunction *colorFun = vtkColorTransferFunction::New();
vtkPiecewiseFunction *opacityFun = vtkPiecewiseFunction::New();
// Create the property and attach the transfer functions
vtkVolumeProperty *volumeProperty = vtkVolumeProperty::New();
volumeProperty->SetIndependentComponents(independentComponents);
volumeProperty->SetColor( colorFun );
volumeProperty->SetScalarOpacity( opacityFun );
volumeProperty->SetInterpolationTypeToLinear();
// connect up the volume to the property and the mapper
volume->SetProperty( volumeProperty );
volume->SetMapper( mapper );
// CT_Skin
// Use compositing and functions set to highlight skin in CT data
// Not for use on RGB data
colorFun->AddRGBPoint( -3024, 0, 0, 0, 0.5, 0.0 );
colorFun->AddRGBPoint( -1000, .62, .36, .18, 0.5, 0.0 );
colorFun->AddRGBPoint( -500, .88, .60, .29, 0.33, 0.45 );
colorFun->AddRGBPoint( 3071, .83, .66, 1, 0.5, 0.0 );
opacityFun->AddPoint(-3024, 0, 0.5, 0.0 );
opacityFun->AddPoint(-1000, 0, 0.5, 0.0 );
opacityFun->AddPoint(-500, 1.0, 0.33, 0.45 );
opacityFun->AddPoint(3071, 1.0, 0.5, 0.0);
mapper->SetBlendModeToComposite();
volumeProperty->ShadeOn();
volumeProperty->SetAmbient(0.1);
volumeProperty->SetDiffuse(0.9);
volumeProperty->SetSpecular(0.2);
volumeProperty->SetSpecularPower(10.0);
volumeProperty->SetScalarOpacityUnitDistance(0.8919);
// Add the volume to the scene
renderer->AddVolume( volume );
renderer->ResetCamera();
// Set the default window size
renWin->SetSize(512,512);
renWin->AddRenderer(renderer);
renWin->SetInteractor(interactor);
QVTKWidget widget;
widget.SetRenderWindow(renWin);
widget.resize(512,512);
QMdiSubWindow *subWindow = mdiArea->addSubWindow(&widget);
subWindow->resize(512,512);
subWindow->show();
// interact with data
renWin->Render();
interactor->Start();
return true;
}
The following codes are used to render SPECT frames:
int QtItkVtkViewMDI::volumeRenderSPECTFramesNormal()
{
if( fileNameSPECTFrames.isEmpty()) // fileNameSPECTFrames is a string
containing the file name of the SPECT multi-frame dicom.
return false;
int clip = 3;
double frameRate = 1.0;
const unsigned int Dimension = 3;
double opacityWindow = 353; // window width
double opacityLevel = 176; // window level
bool independentComponents=true;
typedef signed short PixelType;
typedef itk::Image< PixelType, Dimension > ImageType; // define
image type
typedef itk::ImageFileReader<ImageType> ReaderType; // define
reader type
ReaderType::Pointer reader = ReaderType::New();
reader->SetFileName(fileNameSPECTFrames.toStdString()); // whether
multi-frames or not, ITK can read it.
typedef itk::ImageToVTKImageFilter<ImageType> ConnectorType;
//ReaderType::Pointer reader = ReaderType::New();
ConnectorType::Pointer connector = ConnectorType::New();
connector->SetInput( reader->GetOutput() );
vtkImageImport * readerImageImport = connector->GetImporter();
vtkImageResample * resample = vtkImageResample::New();
resample->SetInputConnection( readerImageImport->GetOutputPort() );
// Create the renderer, render window and interactor
vtkRenderer *renderer = vtkRenderer::New();
vtkRenderWindow *renWin = vtkRenderWindow::New();
interactor = vtkWin32RenderWindowInteractor::New();
interactorStyle = vtkInteractorStyleTrackballCamera::New();
interactor->SetInteractorStyle(interactorStyle);
interactor->SetRenderWindow(renWin);
interactor->SetDesiredUpdateRate(frameRate / (1+clip) );
interactor->GetInteractorStyle()->SetDefaultRenderer(renderer);
// Create our volume and mapper
vtkVolume *volume = vtkVolume::New();
vtkFixedPointVolumeRayCastMapper *mapper =
vtkFixedPointVolumeRayCastMapper::New();
mapper->SetInputConnection( resample->GetOutputPort() );
// Create our transfer function
vtkColorTransferFunction *colorFun = vtkColorTransferFunction::New();
vtkPiecewiseFunction *opacityFun = vtkPiecewiseFunction::New();
// Create the property and attach the transfer functions
vtkVolumeProperty *volumeProperty = vtkVolumeProperty::New();
volumeProperty->SetIndependentComponents(independentComponents);
volumeProperty->SetColor( colorFun );
volumeProperty->SetScalarOpacity( opacityFun );
volumeProperty->SetInterpolationTypeToLinear();
// connect up the volume to the property and the mapper
volume->SetProperty( volumeProperty );
volume->SetMapper( mapper );
// MIP ( Maximum Intensity Projection )
// Create an opacity ramp from the window and level values.
// Color is white. Blending is MIP.
colorFun->AddRGBSegment(0.0, 1.0, 1.0, 1.0, 255.0, 1.0, 1.0, 1.0 );
opacityFun->AddSegment( opacityLevel - 0.5*opacityWindow, 0.0,
opacityLevel + 0.5*opacityWindow, 1.0 );
mapper->SetBlendModeToMaximumIntensity();
// Add the volume to the scene
renderer->AddVolume( volume );
renderer->ResetCamera();
// Set the default window size
renWin->SetSize(512,512);
renWin->AddRenderer(renderer);
renWin->SetInteractor(interactor);
QVTKWidget widget;
widget.SetRenderWindow(renWin);
widget.resize(512,512);
QMdiSubWindow *subWindow = mdiArea->addSubWindow(&widget);
subWindow->resize(512,512);
subWindow->show();
// interact with data
renWin->Render();
interactor->Start();
return true;
}
--
View this message in context: http://vtk.1045678.n5.nabble.com/Why-multi-frame-dicom-can-not-be-rendered-correctly-by-VTK-tp5716270.html
Sent from the VTK - Users mailing list archive at Nabble.com.
More information about the vtkusers
mailing list