From b7ecfab842d12fb1623660e74b859c609293beb3 Mon Sep 17 00:00:00 2001 From: dsarrut Date: Thu, 22 Jul 2010 09:22:08 +0000 Subject: [PATCH] convert a DicomStruct into a binary image --- tools/clitkDicomRTStruct2BinaryImage.cxx | 65 ++++++ tools/clitkDicomRTStruct2BinaryImage.ggo | 17 ++ tools/clitkDicomRTStructInfo.cxx | 36 ++++ tools/clitkDicomRTStructInfo.ggo | 11 + tools/clitkDicomRT_ROI.cxx | 117 +++++++++++ tools/clitkDicomRT_ROI.h | 55 +++++ .../clitkDicomRT_ROI_ConvertToImageFilter.cxx | 191 ++++++++++++++++++ tools/clitkDicomRT_ROI_ConvertToImageFilter.h | 58 ++++++ 8 files changed, 550 insertions(+) create mode 100644 tools/clitkDicomRTStruct2BinaryImage.cxx create mode 100644 tools/clitkDicomRTStruct2BinaryImage.ggo create mode 100644 tools/clitkDicomRTStructInfo.cxx create mode 100644 tools/clitkDicomRTStructInfo.ggo create mode 100644 tools/clitkDicomRT_ROI.cxx create mode 100644 tools/clitkDicomRT_ROI.h create mode 100644 tools/clitkDicomRT_ROI_ConvertToImageFilter.cxx create mode 100644 tools/clitkDicomRT_ROI_ConvertToImageFilter.h diff --git a/tools/clitkDicomRTStruct2BinaryImage.cxx b/tools/clitkDicomRTStruct2BinaryImage.cxx new file mode 100644 index 0000000..1201bd5 --- /dev/null +++ b/tools/clitkDicomRTStruct2BinaryImage.cxx @@ -0,0 +1,65 @@ +/*========================================================================= + Program: vv http://www.creatis.insa-lyon.fr/rio/vv + Main authors : XX XX XX + + Authors belongs to: + - University of LYON http://www.universite-lyon.fr/ + - Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr + - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the copyright notices for more information. + + It is distributed under dual licence + - BSD http://www.opensource.org/licenses/bsd-license.php + - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html + + =========================================================================*/ + +#include "clitkDicomRT_ROI_ConvertToImageFilter.h" +#include "clitkDicomRT_StructureSet.h" +#include "clitkDicomRTStruct2BinaryImage_ggo.h" + +//-------------------------------------------------------------------- +int main(int argc, char * argv[]) { + + // Init command line + GGO(clitkDicomRTStruct2BinaryImage, args_info); + + // Read and display information + clitk::DicomRT_StructureSet s; + s.Read(args_info.input_arg); + // s.Print(std::cout); + + // New filter to convert to binary image + clitk::DicomRT_ROI_ConvertToImageFilter filter; + filter.SetCropMaskEnabled(args_info.crop_flag); + filter.SetImageFilename(args_info.image_arg); // Used to get spacing + origin + if (args_info.roi_arg != -1) { + filter.SetROI(s.GetROI(args_info.roi_arg)); + filter.SetOutputImageFilename(args_info.output_arg); + filter.Update(); + } + else { + for(unsigned int i=0; iGetName(); + int num = s.GetListOfROI()[i]->GetROINumber(); + filter.SetROI(s.GetListOfROI()[i]); + name.erase(remove_if(name.begin(), name.end(), isspace), name.end()); + std::string n = std::string(args_info.output_arg).append + (clitk::toString(num)).append + ("_").append + (name).append + (".mhd"); + if (args_info.verbose_flag) { + std::cout << i << " " << s.GetListOfROI()[i]->GetName() << " num=" << num << " : " << n << std::endl; + } + filter.SetOutputImageFilename(n); + filter.Update(); + } + } + + // This is the end my friend + return 0; +} diff --git a/tools/clitkDicomRTStruct2BinaryImage.ggo b/tools/clitkDicomRTStruct2BinaryImage.ggo new file mode 100644 index 0000000..74e5a7e --- /dev/null +++ b/tools/clitkDicomRTStruct2BinaryImage.ggo @@ -0,0 +1,17 @@ +# file clitkDicomRTStruct2BinaryImage.ggo +Package "clitk" +version "Convert DICOM RT Structure Set (contours) to binary image" + +option "config" - "Config file" string no +option "verbose" v "Verbose" flag off +option "input" i "Input Dicom file" string yes +option "image" j "Used to read image info (spacing, origin)" string yes +option "roi" r "ROI to binarize (if -1 = all roi)" int no default="-1" +option "output" o "Output image filename" string yes + +option "crop" c "Crop binary mask" flag off + +#option "roi" r "ROI to print (ID)" int no +#option "contour" c "contour to print (ID)" int no +#option "offset" o "to display points as image offsets" flag off + diff --git a/tools/clitkDicomRTStructInfo.cxx b/tools/clitkDicomRTStructInfo.cxx new file mode 100644 index 0000000..e449348 --- /dev/null +++ b/tools/clitkDicomRTStructInfo.cxx @@ -0,0 +1,36 @@ +/*========================================================================= + Program: vv http://www.creatis.insa-lyon.fr/rio/vv + Main authors : XX XX XX + + Authors belongs to: + - University of LYON http://www.universite-lyon.fr/ + - Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr + - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the copyright notices for more information. + + It is distributed under dual licence + - BSD http://www.opensource.org/licenses/bsd-license.php + - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html + + =========================================================================*/ + +#include "clitkDicomRT_StructureSet.h" +#include "clitkDicomRTStructInfo_ggo.h" + +//-------------------------------------------------------------------- +int main(int argc, char * argv[]) { + + // Init command line + GGO(clitkDicomRTStructInfo, args_info); + + // Read and display information + clitk::DicomRT_StructureSet s; + s.Read(args_info.input_arg); + s.Print(std::cout); + + // This is the end my friend + return 0; +} diff --git a/tools/clitkDicomRTStructInfo.ggo b/tools/clitkDicomRTStructInfo.ggo new file mode 100644 index 0000000..594de5d --- /dev/null +++ b/tools/clitkDicomRTStructInfo.ggo @@ -0,0 +1,11 @@ +# file clitkDicomRTStructInfo.ggo +Package "clitk" +version "Read and print DICOM RT Structure set file (contours)" + +option "config" - "Config file" string no +option "input" i "Input Dicom file" string yes + +#option "roi" r "ROI to print (ID)" int no +#option "contour" c "contour to print (ID)" int no +#option "offset" o "to display points as image offsets" flag off + diff --git a/tools/clitkDicomRT_ROI.cxx b/tools/clitkDicomRT_ROI.cxx new file mode 100644 index 0000000..d140398 --- /dev/null +++ b/tools/clitkDicomRT_ROI.cxx @@ -0,0 +1,117 @@ +/*========================================================================= + Program: vv http://www.creatis.insa-lyon.fr/rio/vv + Main authors : XX XX XX + + Authors belongs to: + - University of LYON http://www.universite-lyon.fr/ + - Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr + - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the copyright notices for more information. + + It is distributed under dual licence + - BSD http://www.opensource.org/licenses/bsd-license.php + - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html + + =========================================================================*/ + +#include "clitkDicomRT_ROI.h" +#include +#include + +//-------------------------------------------------------------------- +clitk::DicomRT_ROI::DicomRT_ROI() { + mName = "NoName"; + mNumber = -1; + mColor.resize(3); + mColor[0] = mColor[1] = mColor[2] = 0; + mMeshIsUpToDate = false; +} +//-------------------------------------------------------------------- + + +//-------------------------------------------------------------------- +clitk::DicomRT_ROI::~DicomRT_ROI() { + +} +//-------------------------------------------------------------------- + + +//-------------------------------------------------------------------- +int clitk::DicomRT_ROI::GetROINumber() const { + return mNumber; +} +//-------------------------------------------------------------------- + + +//-------------------------------------------------------------------- +const std::string & clitk::DicomRT_ROI::GetName() const { + return mName; +} +//-------------------------------------------------------------------- + + +//-------------------------------------------------------------------- +const std::vector & clitk::DicomRT_ROI::GetDisplayColor() const { + return mColor; +} +//-------------------------------------------------------------------- + + + +//-------------------------------------------------------------------- +void clitk::DicomRT_ROI::Print(std::ostream & os) const { + os << "ROI " << mNumber << "\t" << mName + << "\t(" << mColor[0] << " " << mColor[1] << " " << mColor[2] << ")" + << "\t Contours = " << mListOfContours.size() << std::endl; +} +//-------------------------------------------------------------------- + + +//-------------------------------------------------------------------- +void clitk::DicomRT_ROI::Read(std::map & rois, gdcm::SQItem * item) { + + // ROI number [Referenced ROI Number] + mNumber = atoi(item->GetEntryValue(0x3006,0x0084).c_str()); + + // Retrieve ROI Name + mName = rois[mNumber]; + + // ROI Color [ROI Display Color] + mColor = clitk::parse_string(item->GetEntryValue(0x3006,0x002a),'\\'); + + // Read contours [Contour Sequence] + gdcm::SeqEntry * contours=item->GetSeqEntry(0x3006,0x0040); + for(gdcm::SQItem* j=contours->GetFirstSQItem();j!=0;j=contours->GetNextSQItem()) { + DicomRT_Contour * c = new DicomRT_Contour; + bool b = c->Read(j); + if (b) mListOfContours.push_back(c); + } +} +//-------------------------------------------------------------------- + + +//-------------------------------------------------------------------- +vtkPolyData * clitk::DicomRT_ROI::GetMesh() { + if (!mMeshIsUpToDate) { + ComputeMesh(); + } + return mMesh; +} +//-------------------------------------------------------------------- + + +//-------------------------------------------------------------------- +void clitk::DicomRT_ROI::ComputeMesh() { + vtkAppendPolyData * append = vtkAppendPolyData::New(); + for(unsigned int i=0; iAddInput(mListOfContours[i]->GetMesh()); + } + append->Update(); + mMesh = append->GetOutput(); + mMeshIsUpToDate = true; +} +//-------------------------------------------------------------------- + diff --git a/tools/clitkDicomRT_ROI.h b/tools/clitkDicomRT_ROI.h new file mode 100644 index 0000000..0b8d6dc --- /dev/null +++ b/tools/clitkDicomRT_ROI.h @@ -0,0 +1,55 @@ +/*========================================================================= + Program: vv http://www.creatis.insa-lyon.fr/rio/vv + Main authors : XX XX XX + + Authors belongs to: + - University of LYON http://www.universite-lyon.fr/ + - Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr + - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the copyright notices for more information. + + It is distributed under dual licence + - BSD http://www.opensource.org/licenses/bsd-license.php + - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html + + =========================================================================*/ + +#ifndef CLITKDICOMRT_ROI_H +#define CLITKDICOMRT_ROI_H + +#include "clitkDicomRT_Contour.h" + +namespace clitk { + + //-------------------------------------------------------------------- + class DicomRT_ROI { + + public: + DicomRT_ROI(); + ~DicomRT_ROI(); + + void Print(std::ostream & os = std::cout) const; + void Read(std::map & rois, gdcm::SQItem * item); + + int GetROINumber() const; + const std::string & GetName() const; + const std::vector & GetDisplayColor() const; + vtkPolyData * GetMesh(); + + protected: + void ComputeMesh(); + std::string mName; + int mNumber; + std::vector mColor; + std::vector mListOfContours; + vtkPolyData * mMesh; + bool mMeshIsUpToDate; + }; + //-------------------------------------------------------------------- + +} // end namespace clitk +#endif // CLITKDICOMRT_ROI_H + diff --git a/tools/clitkDicomRT_ROI_ConvertToImageFilter.cxx b/tools/clitkDicomRT_ROI_ConvertToImageFilter.cxx new file mode 100644 index 0000000..cedef81 --- /dev/null +++ b/tools/clitkDicomRT_ROI_ConvertToImageFilter.cxx @@ -0,0 +1,191 @@ +/*========================================================================= + Program: vv http://www.creatis.insa-lyon.fr/rio/vv + Main authors : XX XX XX + + Authors belongs to: + - University of LYON http://www.universite-lyon.fr/ + - Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr + - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the copyright notices for more information. + + It is distributed under dual licence + - BSD http://www.opensource.org/licenses/bsd-license.php + - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html + + =========================================================================*/ + +#include "clitkDicomRT_ROI_ConvertToImageFilter.h" +#include +#include +#include +#include +#include +#include "clitkImageCommon.h" + +//-------------------------------------------------------------------- +clitk::DicomRT_ROI_ConvertToImageFilter::DicomRT_ROI_ConvertToImageFilter() { + mROI = NULL; + mImageInfoIsSet = false; + mWriteOutput = false; + mCropMask = true; +} +//-------------------------------------------------------------------- + + +//-------------------------------------------------------------------- +clitk::DicomRT_ROI_ConvertToImageFilter::~DicomRT_ROI_ConvertToImageFilter() { + +} +//-------------------------------------------------------------------- + + +//-------------------------------------------------------------------- +void clitk::DicomRT_ROI_ConvertToImageFilter::SetROI(clitk::DicomRT_ROI * roi) { + mROI = roi; +} +//-------------------------------------------------------------------- + + +//-------------------------------------------------------------------- +void clitk::DicomRT_ROI_ConvertToImageFilter::SetCropMaskEnabled(bool b) { + mCropMask = b; +} +//-------------------------------------------------------------------- + + +//-------------------------------------------------------------------- +void clitk::DicomRT_ROI_ConvertToImageFilter::SetOutputImageFilename(std::string s) { + mOutputFilename = s; + mWriteOutput = true; +} +//-------------------------------------------------------------------- + + +//-------------------------------------------------------------------- +void clitk::DicomRT_ROI_ConvertToImageFilter::SetImageFilename(std::string f) { + itk::ImageIOBase::Pointer header = clitk::readImageHeader(f); + if (header->GetNumberOfDimensions() < 3) { + std::cerr << "Error. Please provide a 3D image instead of " << f << std::endl; + exit(0); + } + if (header->GetNumberOfDimensions() > 3) { + std::cerr << "Warning dimension > 3 are ignored" << std::endl; + } + mSpacing.resize(3); + mOrigin.resize(3); + mSize.resize(3); + for(unsigned int i=0; i<3; i++) { + mSpacing[i] = header->GetSpacing(i); + mOrigin[i] = header->GetOrigin(i); + mSize[i] = header->GetDimensions(i); + } + mImageInfoIsSet = true; +} +//-------------------------------------------------------------------- + + +//-------------------------------------------------------------------- +void clitk::DicomRT_ROI_ConvertToImageFilter::Update() { + if (!mROI) { + std::cerr << "Error. No ROI set, please use SetROI." << std::endl; + exit(0); + } + if (!mImageInfoIsSet) { + std::cerr << "Error. Please provide image info (spacing/origin) with SetImageFilename" << std::endl; + exit(0); + } + // DD("Update"); + + // Get Mesh + vtkPolyData * mesh = mROI->GetMesh(); + // DD(mesh->GetNumberOfCells()); + + // Get bounds + double *bounds=mesh->GetBounds(); + // for(int i=0; i<6; i++){ +// DD(bounds[i]); +// } + + // Compute origin + std::vector origin; + origin.resize(3); + origin[0] = floor((bounds[0]-mOrigin[0])/mSpacing[0]-2)*mSpacing[0]+mOrigin[0]; + origin[1] = floor((bounds[2]-mOrigin[1])/mSpacing[1]-2)*mSpacing[1]+mOrigin[1]; + origin[2] = floor((bounds[4]-mOrigin[2])/mSpacing[2]-2)*mSpacing[2]+mOrigin[2]; + + // Compute extend + std::vector extend; + extend.resize(3); + extend[0] = ceil((bounds[1]-origin[0])/mSpacing[0]+4); + extend[1] = ceil((bounds[3]-origin[1])/mSpacing[1]+4); + extend[2] = ceil((bounds[5]-origin[2])/mSpacing[2]+4); + + // If no crop, set initial image size/origin + if (!mCropMask) { + for(int i=0; i<3; i++) { + origin[i] = mOrigin[i]; + extend[i] = mSize[i]-1; + } + } + + // Create new output image + mBinaryImage = vtkImageData::New(); + mBinaryImage->SetScalarTypeToUnsignedChar(); + mBinaryImage->SetOrigin(&origin[0]); + mBinaryImage->SetSpacing(&mSpacing[0]); + mBinaryImage->SetExtent(0, extend[0], + 0, extend[1], + 0, extend[2]); + mBinaryImage->AllocateScalars(); + + // for(int i=0; i<3; i++){ + // DD(origin[i]); + // DD(extend[i]); + // DD(mBinaryImage->GetDimensions()[i]); + // } + memset(mBinaryImage->GetScalarPointer(), 0, + mBinaryImage->GetDimensions()[0]*mBinaryImage->GetDimensions()[1]*mBinaryImage->GetDimensions()[2]*sizeof(unsigned char)); + + // Extrude + vtkSmartPointer extrude=vtkSmartPointer::New(); + extrude->SetInput(mesh); + ///We extrude in the -slice_spacing direction to respect the FOCAL convention // ????????????? + extrude->SetVector(0, 0, -mSpacing[2]); + + // Binarization + vtkSmartPointer sts=vtkSmartPointer::New(); + //The following line is extremely important + //http://www.nabble.com/Bug-in-vtkPolyDataToImageStencil--td23368312.html#a23370933 + sts->SetTolerance(0); + sts->SetInformationInput(mBinaryImage); + sts->SetInput(extrude->GetOutput()); + //sts->SetInput(mesh); + + vtkSmartPointer stencil=vtkSmartPointer::New(); + stencil->SetStencil(sts->GetOutput()); + stencil->SetInput(mBinaryImage); + stencil->ReverseStencilOn(); + stencil->Update(); + mBinaryImage->ShallowCopy(stencil->GetOutput()); + + if (mWriteOutput) { + typedef itk::Image ImageType; + typedef itk::VTKImageToImageFilter ConnectorType; + ConnectorType::Pointer connector = ConnectorType::New(); + connector->SetInput(GetOutput()); + connector->Update(); + clitk::writeImage(connector->GetOutput(), mOutputFilename); + } +} +//-------------------------------------------------------------------- + + + +//-------------------------------------------------------------------- +vtkImageData * clitk::DicomRT_ROI_ConvertToImageFilter::GetOutput() { + return mBinaryImage; +} +//-------------------------------------------------------------------- diff --git a/tools/clitkDicomRT_ROI_ConvertToImageFilter.h b/tools/clitkDicomRT_ROI_ConvertToImageFilter.h new file mode 100644 index 0000000..d5d27b3 --- /dev/null +++ b/tools/clitkDicomRT_ROI_ConvertToImageFilter.h @@ -0,0 +1,58 @@ +/*========================================================================= + Program: vv http://www.creatis.insa-lyon.fr/rio/vv + Main authors : XX XX XX + + Authors belongs to: + - University of LYON http://www.universite-lyon.fr/ + - Léon Bérard cancer center http://oncora1.lyon.fnclcc.fr + - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the copyright notices for more information. + + It is distributed under dual licence + - BSD http://www.opensource.org/licenses/bsd-license.php + - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html + + =========================================================================*/ + +#ifndef CLITKDICOMRT_ROI_CONVERTTOIMAGEFILTER_H +#define CLITKDICOMRT_ROI_CONVERTTOIMAGEFILTER_H + +#include "clitkDicomRT_ROI.h" +#include "clitkImageCommon.h" +#include + +namespace clitk { + + //-------------------------------------------------------------------- + class DicomRT_ROI_ConvertToImageFilter { + + public: + DicomRT_ROI_ConvertToImageFilter(); + ~DicomRT_ROI_ConvertToImageFilter(); + + void SetROI(clitk::DicomRT_ROI * roi); + void SetImageFilename(std::string s); + void SetOutputImageFilename(std::string s); + void Update(); + vtkImageData * GetOutput(); + void SetCropMaskEnabled(bool b); + + protected: + bool mImageInfoIsSet; + bool mWriteOutput; + bool mCropMask; + std::string mOutputFilename; + std::vector mSpacing; + std::vector mOrigin; + std::vector mSize; + clitk::DicomRT_ROI * mROI; + vtkImageData * mBinaryImage; + }; + //-------------------------------------------------------------------- + +} // end namespace clitk +#endif // CLITKDICOMRT_ROI_CONVERTTOIMAGEFILTER_H + -- 2.47.1