GenerateRTSTRUCT.cxx
/*=========================================================================
Program: GDCM (Grassroots DICOM). A DICOM library
Copyright (c) 2006-2011 Mathieu Malaterre
All rights reserved.
See Copyright.txt or http://gdcm.sourceforge.net/Copyright.html for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include "vtkGDCMPolyDataWriter.h"
#include "vtkGDCMPolyDataReader.h"
#include "vtkPolyData.h"
#include "vtkPolyDataReader.h"
#include "vtkMedicalImageProperties.h"
#include "vtkRTStructSetProperties.h"
#include "vtkStringArray.h"
#include "vtkAppendPolyData.h"
#include "vtkPolyDataWriter.h"
#include "vtkPolyDataMapper.h"
#include "vtkPolyDataMapper2D.h"
#include "vtkActor2D.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkMedicalImageProperties.h"
#include "vtkRenderWindow.h"
#include "vtkRenderer.h"
#include "vtkCamera.h"
#include "vtkProperty.h"
#include "vtkProperty2D.h"
#include "vtkImageData.h"
#include "vtkVersion.h"
#include <algorithm> //for std::find
#include "gdcmDirectoryHelper.h"
using namespace gdcm;
//view each organ independently of the others, to make sure that
//organ names correspond to actual segmentations.
void ShowOrgan(vtkPolyData* inData)
{
// Now we'll look at it.
vtkPolyDataMapper *cubeMapper = vtkPolyDataMapper::New();
#if (VTK_MAJOR_VERSION >= 6)
cubeMapper->SetInputData( inData );
#else
cubeMapper->SetInput( inData );
#endif
cubeMapper->SetScalarRange(0,7);
vtkActor *cubeActor = vtkActor::New();
cubeActor->SetMapper(cubeMapper);
vtkProperty * property = cubeActor->GetProperty();
property->SetRepresentationToWireframe();
vtkRenderer *renderer = vtkRenderer::New();
vtkRenderWindow *renWin = vtkRenderWindow::New();
renWin->AddRenderer(renderer);
vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New();
iren->SetRenderWindow(renWin);
renderer->AddActor(cubeActor);
renderer->ResetCamera();
renderer->SetBackground(1,1,1);
renWin->SetSize(300,300);
renWin->Render();
iren->Start();
cubeMapper->Delete();
cubeActor->Delete();
renderer->Delete();
renWin->Delete();
iren->Delete();
}
/*
* Full application which ... RTSTUCT
*/
int main(int argc, char *argv[])
{
if( argc < 2 )
{
std::cerr << argv[0] << " directory-with-rtstruct-and-ct-images\n";
return 1;
}
std::string theDirName(argv[1]);
Directory::FilenamesType theRTSeries =
DirectoryHelper::GetRTStructSeriesUIDs(theDirName);
gdcm::Directory theDir;
theDir.Load(argv[1]);
if (theRTSeries.empty())
{
std::cerr << "No RTStructs found for the test, ending." << std::endl;
return 1;
}
for (size_t q = 0; q < theRTSeries.size(); q++)
{
Directory::FilenamesType theRTNames =
DirectoryHelper::GetFilenamesFromSeriesUIDs(theDirName, theRTSeries[q]);
if (theRTNames.empty()){
std::cerr << "Unable to load RT Series " << theRTSeries[q] << ", continuing. " << std::endl;
continue;
}
vtkGDCMPolyDataReader * reader = vtkGDCMPolyDataReader::New();
reader->SetFileName( theRTNames[0].c_str() );
reader->Update();
//std::cout << reader->GetMedicalImageProperties()->GetStudyDate() << std::endl;
vtkGDCMPolyDataWriter * writer = vtkGDCMPolyDataWriter::New();
int numMasks = reader->GetNumberOfOutputPorts() + 1;//add a blank one in
writer->SetNumberOfInputPorts( numMasks );
std::string thePotentialName = theDirName + "/" + "GDCMTestRTStruct." + theRTSeries[q] + ".dcm";
gdcm::Directory::FilenamesType theFileNames = theDir.GetFilenames();
//keep renaming the output until we get something that doesn't overwrite what was there already
int count = 0;
while (std::find(theFileNames.begin(), theFileNames.end(), thePotentialName) != theFileNames.end())
{
char buff[255];
snprintf(buff,sizeof(buff),"%d",count);
thePotentialName = theDirName + "/" + "GDCMTestRTStruct." + buff + "." + theRTSeries[q] + ".dcm";
}
writer->SetFileName( thePotentialName.c_str());
writer->SetMedicalImageProperties( reader->GetMedicalImageProperties() );
//this line is cheating, we won't have the same stuff, and may not have a struct
//to start with.
//have to go back to the original data to reconstruct the RTStructureSetProperties
//writer->SetRTStructSetProperties( reader->GetRTStructSetProperties() );
//writer->Write();
//loop through the outputs in order to write them out as if they had been created and appended
vtkStringArray* roiNames = vtkStringArray::New();
vtkStringArray* roiAlgorithms = vtkStringArray::New();
vtkStringArray* roiTypes = vtkStringArray::New();
roiNames->SetNumberOfValues(numMasks);
roiAlgorithms->SetNumberOfValues(numMasks);
roiTypes->SetNumberOfValues(numMasks);
vtkAppendPolyData* append = vtkAppendPolyData::New();
//ok, now we'll add a blank organ
//the blank organ is to test to ensure that blank organs work; there have been crash reports
//this code is added at the beginning to ensure that the blank organs are read
//and preserved as individual organs.
vtkPolyData* blank = vtkPolyData::New();
#if (VTK_MAJOR_VERSION >= 6)
writer->SetInputData(0, blank);
#else
writer->SetInput(0, blank);
#endif
roiNames->InsertValue(0, "blank");
roiAlgorithms->InsertValue(0, "blank");
roiTypes->InsertValue(0, "ORGAN");
//note the offsets used to place the blank rtstruct at the beginning of the newly generated RT.
//the idea is to run the program twice; first to generate an rtstruct with a blank mask (making
//sure that that functionality works), and then a second time to make sure that everything is
//being read properly. Multiple organs with the same name could cause some strangenesses.
for (int i = 1; i < numMasks; ++i)
{
#if (VTK_MAJOR_VERSION >= 6)
writer->SetInputConnection(i, reader->GetOutputPort(i-1));
append->AddInputConnection(reader->GetOutputPort(i-1));
#else
writer->SetInput(i, reader->GetOutput(i-1));
append->AddInput(reader->GetOutput(i-1));
#endif
std::string theString = reader->GetRTStructSetProperties()->GetStructureSetROIName(i-1);
roiNames->InsertValue(i, theString);
theString = reader->GetRTStructSetProperties()->GetStructureSetROIGenerationAlgorithm(i-1);
roiAlgorithms->InsertValue(i, theString);
theString = reader->GetRTStructSetProperties()->GetStructureSetRTROIInterpretedType(i-1);
roiTypes->InsertValue(i, theString);
ShowOrgan(reader->GetOutput(i-1));
}
vtkRTStructSetProperties* theProperties = vtkRTStructSetProperties::New();
writer->SetRTStructSetProperties(theProperties);
writer->InitializeRTStructSet(theDirName,
reader->GetRTStructSetProperties()->GetStructureSetLabel(),
reader->GetRTStructSetProperties()->GetStructureSetName(),
roiNames, roiAlgorithms, roiTypes);
writer->SetRTStructSetProperties(theProperties);
writer->Write();
// print reader output:
reader->Print( std::cout );
// print first output:
reader->GetOutput()->Print( std::cout );
reader->Delete();
append->Delete();
roiNames->Delete();
roiTypes->Delete();
theProperties->Delete();
roiAlgorithms->Delete();
blank->Delete();
writer->Delete();
}
return 0;
}
gdcm::DirectoryHelper::GetFilenamesFromSeriesUIDs
static Directory::FilenamesType GetFilenamesFromSeriesUIDs(const std::string &inDirectory, const std::string &inSeriesUID)
gdcm::DirectoryHelper::GetRTStructSeriesUIDs
static Directory::FilenamesType GetRTStructSeriesUIDs(const std::string &inDirectory)
gdcm::Directory
Class for manipulation directories.
Definition gdcmDirectory.h:43
gdcm::Directory::FilenamesType
std::vector< FilenameType > FilenamesType
Definition gdcmDirectory.h:49
gdcm::Directory::Load
unsigned int Load(FilenameType const &name, bool recursive=false)
gdcm::Directory::GetFilenames
FilenamesType const & GetFilenames() const
Set/Get the file names within the directory.
Definition gdcmDirectory.h:58
vtkGDCMPolyDataReader
Definition vtkGDCMPolyDataReader.h:40
vtkGDCMPolyDataReader::New
static vtkGDCMPolyDataReader * New()
vtkGDCMPolyDataWriter
Definition vtkGDCMPolyDataWriter.h:40
vtkGDCMPolyDataWriter::SetNumberOfInputPorts
void SetNumberOfInputPorts(int n)
vtkGDCMPolyDataWriter::InitializeRTStructSet
void InitializeRTStructSet(vtkStdString inDirectory, vtkStdString inStructLabel, vtkStdString inStructName, vtkStringArray *inROINames, vtkStringArray *inROIAlgorithmName, vtkStringArray *inROIType)
vtkGDCMPolyDataWriter::SetRTStructSetProperties
virtual void SetRTStructSetProperties(vtkRTStructSetProperties *pd)
vtkGDCMPolyDataWriter::SetMedicalImageProperties
virtual void SetMedicalImageProperties(vtkMedicalImageProperties *pd)
vtkGDCMPolyDataWriter::New
static vtkGDCMPolyDataWriter * New()
vtkRTStructSetProperties
Definition vtkRTStructSetProperties.h:29
vtkRTStructSetProperties::New
static vtkRTStructSetProperties * New()
gdcmDirectoryHelper.h
gdcm
Definition gdcmASN1.h:21
vtkGDCMPolyDataReader.h
vtkGDCMPolyDataWriter.h
vtkRTStructSetProperties.h