Environment: VTK8.2.0, ITK5.0.0
Here is a demo project to display DICOM data by ITK and VTK.
CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(vtkAndITK)
# Find ITK.
find_package( ITK REQUIRED )
include( ${ITK_USE_FILE} )
# Find VTK.
find_package( VTK REQUIRED )
include( ${VTK_USE_FILE} )
add_executable(${PROJECT_NAME} "main.cpp")
target_link_libraries( ${PROJECT_NAME} ${VTK_LIBRARIES} ${ITK_LIBRARIES} )
main.cpp
#include <iostream>
#include <itkImage.h>
#include <itkGDCMImageIO.h>
#include <itkGDCMSeriesFileNames.h>
#include <itkImageSeriesReader.h>
#include <itkImageToVTKImageFilter.h>
#include <itkPointSet.h>
#include <itkObject.h>
#include <vtkImageActor.h>
#include <vtkSmartPointer.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleImage.h>
#include <string>
#include <vtkImageMapToWindowLevelColors.h>
#include <vtkInformation.h>
#include <vtkStreamingDemandDrivenPipeline.h>
using namespace std;
using PixelType = signed short;
using ImageType3D = itk::Image<PixelType, 3>;
using ImageType2D = itk::Image<PixelType, 2>;
using ImageIoType = itk::GDCMImageIO;
using NamesGeneratorType = itk::GDCMSeriesFileNames;
using ReaderType3D = itk::ImageSeriesReader<ImageType3D>;
using ConnectorType3D = itk::ImageToVTKImageFilter<ImageType3D>;
using ConnectorType2D = itk::ImageToVTKImageFilter<ImageType2D>;
using MetaDataStringType = itk::MetaDataObject<std::string>;
int main( int argc, char *argv[] )
{
ReaderType3D::Pointer ImageReader3D = ReaderType3D::New();
ImageIoType::Pointer dicomIO = ImageIoType::New();
ImageReader3D->SetImageIO(dicomIO);
std::string folder = argv[1];
NamesGeneratorType::Pointer nameGenerator = NamesGeneratorType::New();
nameGenerator->SetDirectory(folder);
using FilenamesContainer = std::vector<std::string>;
FilenamesContainer fileNames = nameGenerator->GetInputFileNames();
ImageReader3D->SetFileNames(fileNames);
try
{
ImageReader3D->Update();
}
catch (itk::ExceptionObject &ex)
{
std::cout << ex << std::endl;
return -2;
}
ConnectorType3D::Pointer ImageConnector3D = ConnectorType3D::New();
ImageConnector3D->SetInput(ImageReader3D->GetOutput());
try
{
ImageConnector3D->Update();
}
catch (itk::ExceptionObject & ex)
{
std::cout << ex << std::endl;
return -3;
}
double ColorLevel;
double ColorWindow;
const itk::MetaDataDictionary& dictionary = dicomIO->GetMetaDataDictionary();
auto itr = dictionary.Begin();
auto end = dictionary.End();
std::string entryId = "0028|1050";
auto tagItr = dictionary.Find(entryId);
if (tagItr != end)
{
MetaDataStringType::ConstPointer entryvalue =
dynamic_cast<const MetaDataStringType*> (tagItr->second.GetPointer());
if (entryvalue)
{
std::string tagvalue = entryvalue->GetMetaDataObjectValue();
ColorLevel = stod(tagvalue);
}
}
entryId = "0028|1051";
tagItr = dictionary.Find(entryId);
if (tagItr != end)
{
MetaDataStringType::ConstPointer entryvalue =
dynamic_cast<const MetaDataStringType*> (tagItr->second.GetPointer());
if (entryvalue)
{
std::string tagvalue = entryvalue->GetMetaDataObjectValue();
ColorWindow = stod(tagvalue);
}
}
vtkSmartPointer<vtkImageMapToWindowLevelColors> imgToColors = vtkSmartPointer<vtkImageMapToWindowLevelColors>::New();
imgToColors->SetInputData( ImageConnector3D->GetOutput() );
imgToColors->SetLevel( ColorLevel );
imgToColors->SetWindow( ColorWindow );
imgToColors->Update();
vtkAlgorithm *alg = imgToColors->GetInputAlgorithm();
vtkImageData *data = imgToColors->GetOutput();
vtkInformation* outInfo = alg->GetOutputInformation(0);
int *w_ext = outInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT());
vtkSmartPointer<vtkImageActor> actor = vtkSmartPointer<vtkImageActor>::New();
actor->SetInputData( data );
int slice = (w_ext[4] + w_ext[5])/2;
actor->SetDisplayExtent( w_ext[0], w_ext[1], w_ext[2], w_ext[3], slice, slice );
// w_ext: 0, 480, 0, 480, 0, 480
cout << "w_ext: " << w_ext[0] << ", " << w_ext[1] << ", " << w_ext[2] << ", " << w_ext[3]
<< ", " << w_ext[4] << ", " << w_ext[5] << endl;
vtkSmartPointer<vtkRenderer> ren = vtkSmartPointer<vtkRenderer>::New();
ren->AddActor( actor );
vtkSmartPointer<vtkRenderWindow> renWin = vtkSmartPointer<vtkRenderWindow>::New();
renWin->AddRenderer( ren );
vtkSmartPointer<vtkRenderWindowInteractor> iren = vtkSmartPointer<vtkRenderWindowInteractor>::New();
iren->SetRenderWindow( renWin );
iren->Initialize();
vtkSmartPointer<vtkInteractorStyleImage> iStyle = vtkSmartPointer<vtkInteractorStyleImage>::New();
iren->SetInteractorStyle( iStyle );
ren->AddActor( actor );
renWin->SetSize( 800, 800 );
renWin->Render();
ren->ResetCamera();
renWin->Render();
iren->Start();
return 0;
}
The folder contains a series of dcm files.
Run it.
./vtkAndITK.exe "D:\case\tmp"
Convert it to RGBA Image crudely.
vtkSmartPointer<vtkLookupTable> table = vtkSmartPointer<vtkLookupTable>::New();
table->SetNumberOfTableValues(256);
table->SetRange(0, 255);
table->Build();
vtkSmartPointer<vtkImageMapToColors> filter = vtkSmartPointer<vtkImageMapToColors>::New();
filter->SetLookupTable(table);
filter->SetOutputFormat(VTK_RGBA);
filter->SetInputData( ImageConnector3D->GetOutput() );
filter->Update();
actor->SetInputData( filter->GetOutput() );
[…] post is based on an old project Use ITK And VTK To Show DICOM Image. We want to add an above layer which drawed translucent red color on the gray […]