From 2239ff118ba4e88d3b4c3ad35853b572d75f468e Mon Sep 17 00:00:00 2001 From: tbaudier Date: Thu, 11 Feb 2016 10:43:39 +0100 Subject: [PATCH] Can open Dicom RTStruct without an external gdcm --- common/clitkDicomRTStruct2ImageFilter.cxx | 4 +- common/clitkDicomRT_ROI.cxx | 2 +- common/clitkDicomRT_StructureSet.cxx | 192 ++++++---------------- vv/vvToolTest.cxx | 25 +++ 4 files changed, 77 insertions(+), 146 deletions(-) diff --git a/common/clitkDicomRTStruct2ImageFilter.cxx b/common/clitkDicomRTStruct2ImageFilter.cxx index c8d28bf..fcc9e2b 100644 --- a/common/clitkDicomRTStruct2ImageFilter.cxx +++ b/common/clitkDicomRTStruct2ImageFilter.cxx @@ -236,7 +236,7 @@ void clitk::DicomRTStruct2ImageFilter::Update() #if VTK_MAJOR_VERSION <= 5 sts->SetInput(extrude->GetOutput()); #else - sts->SetInputData(extrude->GetOutput()); + sts->SetInputConnection(extrude->GetOutputPort(0)); #endif //sts->SetInput(mesh); @@ -244,7 +244,7 @@ void clitk::DicomRTStruct2ImageFilter::Update() #if VTK_MAJOR_VERSION <= 5 stencil->SetStencil(sts->GetOutput()); #else - stencil->SetStencilData(sts->GetOutput()); + stencil->SetStencilConnection(sts->GetOutputPort(0)); #endif #if VTK_MAJOR_VERSION <= 5 stencil->SetInput(mBinaryImage); diff --git a/common/clitkDicomRT_ROI.cxx b/common/clitkDicomRT_ROI.cxx index 2e914d6..b6af9c3 100644 --- a/common/clitkDicomRT_ROI.cxx +++ b/common/clitkDicomRT_ROI.cxx @@ -151,7 +151,7 @@ double clitk::DicomRT_ROI::GetForegroundValueLabelImage() const #if GDCM_MAJOR_VERSION == 2 bool clitk::DicomRT_ROI::Read(gdcm::Item * itemInfo, gdcm::Item * itemContour) { - FATAL("Error : compile vv with itk4 + external gdcm"); + //FATAL("Error : compile vv with itk4 + external gdcm"); // Keep dicom item mItemInfo = itemInfo; mItemContour = itemContour; diff --git a/common/clitkDicomRT_StructureSet.cxx b/common/clitkDicomRT_StructureSet.cxx index 4945693..9fa96b3 100644 --- a/common/clitkDicomRT_StructureSet.cxx +++ b/common/clitkDicomRT_StructureSet.cxx @@ -311,66 +311,51 @@ void clitk::DicomRT_StructureSet::Write(const std::string & filename) //-------------------------------------------------------------------- void clitk::DicomRT_StructureSet::Read(const std::string & filename) { -#if CLITK_USE_SYSTEM_GDCM == 1 - vtkSmartPointer reader = vtkGDCMPolyDataReader::New(); - reader->SetFileName(filename.c_str()); - reader->Update(); - - // Get global information - vtkRTStructSetProperties * p = reader->GetRTStructSetProperties(); - mStudyID = p->GetStudyInstanceUID(); - mStudyDate = p->GetStructureSetDate(); - mLabel = p->GetStructureSetLabel(); - mName = p->GetStructureSetName(); - mTime = p->GetStructureSetTime(); - - int n = p->GetNumberOfStructureSetROIs(); - for(unsigned int i=0; iGetStructureSetROINumber(i); - // Create the roi - DicomRT_ROI::Pointer roi = DicomRT_ROI::New(); - roi->Read(reader, i); - // Insert in the map - mROIs[roinumber] = roi; - } - return; -#endif // END version with system gdcm (vtkGDCMPolyDataReader) - - // Open DICOM -#if GDCM_MAJOR_VERSION == 2 - FATAL("Error : compile vv with itk4 + external gdcm"); - - // Read gdcm file - mReader = new gdcm::Reader; - mReader->SetFileName(filename.c_str()); - mReader->Read(); - mFile = &(mReader->GetFile()); - const gdcm::DataSet & ds = mFile->GetDataSet(); +//Try to avoid to use extern GDCM library + + //check the RS file is available before conversion + gdcm::Reader RTreader; + RTreader.SetFileName( filename.c_str() ); + if( !RTreader.Read() ) + { + std::cout << "Problem reading file: " << filename << std::endl; + return; + } + + const gdcm::DataSet& ds = RTreader.GetFile().GetDataSet(); - // Check file type - //Verify if the file is a RT-Structure-Set dicom file gdcm::MediaStorage ms; - ms.SetFromFile(*mFile); - if( ms != gdcm::MediaStorage::RTStructureSetStorage ) - { - std::cerr << "Error. the file " << filename - << " is not a Dicom Struct ? (must have a SOP Class UID [0008|0016] = 1.2.840.10008.5.1.4.1.1.481.3 ==> [RT Structure Set Storage])" - << std::endl; - exit(0); - } + ms.SetFromFile( RTreader.GetFile() ); + + // (3006,0020) SQ (Sequence with explicit length #=4) # 370, 1 StructureSetROISequence + gdcm::Tag tssroisq(0x3006,0x0020); + if( !ds.FindDataElement( tssroisq ) ) + { + std::cout << "Problem locating 0x3006,0x0020 - Is this a valid RT Struct file?" << std::endl; + return; + } + gdcm::Tag troicsq(0x3006,0x0039); + if( !ds.FindDataElement( troicsq ) ) + { + std::cout << "Problem locating 0x3006,0x0039 - Is this a valid RT Struct file?" << std::endl; + return; + } - gdcm::Attribute<0x8,0x60> modality; - modality.SetFromDataSet( ds ); - if( modality.GetValue() != "RTSTRUCT" ) - { - std::cerr << "Error. the file " << filename - << " is not a Dicom Struct ? (must have 0x0008,0x0060 = RTSTRUCT [RT Structure Set Storage])" - << std::endl; - exit(0); - } + const gdcm::DataElement &roicsq = ds.GetDataElement( troicsq ); + gdcm::SmartPointer sqi = roicsq.GetValueAsSQ(); + if( !sqi || !sqi->GetNumberOfItems() ) + { + return; + } + const gdcm::DataElement &ssroisq = ds.GetDataElement( tssroisq ); + gdcm::SmartPointer ssqi = ssroisq.GetValueAsSQ(); + if( !ssqi || !ssqi->GetNumberOfItems() ) + { + return; + } + // Read global info gdcm::Attribute<0x20,0x10> studyid; studyid.SetFromDataSet( ds ); @@ -395,22 +380,13 @@ void clitk::DicomRT_StructureSet::Read(const std::string & filename) // Temporary store the list of items std::map mMapOfROIInfo; std::map mMapOfROIContours; - -std::map mROIs; - std::map mMapOfROIName; -#if GDCM_MAJOR_VERSION == 2 - gdcm::Reader * mReader; - gdcm::SmartPointer mROIInfoSequenceOfItems; - gdcm::SmartPointer mROIContoursSequenceOfItems; -#endif - gdcm::File * mFile; - + //---------------------------------- // Read all ROI Names and number // 0x3006,0x0020 = [ Structure Set ROI Sequence ] - gdcm::Tag tssroisq(0x3006,0x0020); - const gdcm::DataElement &ssroisq = ds.GetDataElement( tssroisq ); + //gdcm::Tag tssroisq(0x3006,0x0020); + //const gdcm::DataElement &ssroisq = ds.GetDataElement( tssroisq ); mROIInfoSequenceOfItems = ssroisq.GetValueAsSQ(); gdcm::SmartPointer & roi_seq = mROIInfoSequenceOfItems; assert(roi_seq); // TODO error message @@ -441,8 +417,8 @@ std::map mROIs; //---------------------------------- // Read all ROI item // 0x3006,0x0039 = [ ROI Contour Sequence ] - gdcm::Tag troicsq(0x3006,0x0039); - const gdcm::DataElement &roicsq = ds.GetDataElement( troicsq ); + //gdcm::Tag troicsq(0x3006,0x0039); + //const gdcm::DataElement &roicsq = ds.GetDataElement( troicsq ); gdcm::SmartPointer roi_contour_seq = roicsq.GetValueAsSQ(); mROIContoursSequenceOfItems = roi_contour_seq; assert(roi_contour_seq); // TODO error message @@ -462,82 +438,12 @@ std::map mROIs; for(std::map::iterator i = mMapOfROIInfo.begin(); i != mMapOfROIInfo.end(); i++) { int nb = i->first;//ReadROINumber(i);//mROIIndex[i]; // Create the roi - DicomRT_ROI::Pointer roi = DicomRT_ROI::New(); - roi->Read(mMapOfROIInfo[nb], mMapOfROIContours[nb]); - // mListOfROI.push_back(roi); - // mMapOfROIIndex[nb] = i; - mROIs[nb] = roi; - } - - //---------------------------------------------------------------------------------------- - //---------------------------------------------------------------------------------------- - //---------------------------------------------------------------------------------------- -#else - mFile = new gdcm::File; - mFile->SetFileName(filename.c_str()); - mFile->SetMaxSizeLoadEntry(16384); // Needed ... - mFile->SetLoadMode(gdcm::LD_NOSHADOW); // don't load shadow tags (in order to save memory) - mFile->Load(); - - // Check file type - //Verify if the file is a RT-Structure-Set dicom file - if (!gdcm::Util::DicomStringEqual(mFile->GetEntryValue(0x0008,0x0016),"1.2.840.10008.5.1.4.1.1.481.3")) { //SOP clas UID - std::cerr << "Error. the file " << filename - << " is not a Dicom Struct ? (must have a SOP Class UID [0008|0016] = 1.2.840.10008.5.1.4.1.1.481.3 ==> [RT Structure Set Storage])" - << std::endl; - exit(0); - } - if (!gdcm::Util::DicomStringEqual(mFile->GetEntryValue(0x0008,0x0060),"RTSTRUCT")) { //SOP clas UID - std::cerr << "Error. the file " << filename - << " is not a Dicom Struct ? (must have 0x0008,0x0060 = RTSTRUCT [RT Structure Set Storage])" - << std::endl; - exit(0); - } - - // Read global info - mStudyID = mFile->GetValEntry(0x0020,0x0010)->GetValue(); - mStudyTime = mFile->GetValEntry(0x008,0x0020)->GetValue(); - mStudyDate = mFile->GetValEntry(0x008,0x0030)->GetValue(); - mLabel = mFile->GetValEntry(0x3006,0x002)->GetValue(); - if (!mFile->GetValEntry(0x3006,0x004)) { - mName = "Anonymous"; - } - else { - mName = mFile->GetValEntry(0x3006,0x004)->GetValue(); - } - mTime = mFile->GetValEntry(0x3006,0x009)->GetValue(); - - //---------------------------------- - // Read all ROI Names and number - // 0x3006,0x0020 = [ Structure Set ROI Sequence ] - gdcm::SeqEntry * roi_seq=mFile->GetSeqEntry(0x3006,0x0020); - assert(roi_seq); // TODO error message - for (gdcm::SQItem* r=roi_seq->GetFirstSQItem(); r!=0; r=roi_seq->GetNextSQItem()) { - std::string name = r->GetEntryValue(0x3006,0x0026); // 0x3006,0x0026 = [ROI Name] - int nb = atoi(r->GetEntryValue(0x3006,0x0022).c_str()); // 0x3006,0x0022 = [ROI Number] - // Check if such a number already exist - if (mMapOfROIName.find(nb) != mMapOfROIName.end()) { - std::cerr << "WARNING. A Roi already exist with the number " - << nb << ". I replace." << std::endl; - } - // Add in map - mMapOfROIName[nb] = name; - } - - //---------------------------------- - // Read all ROI - // 0x3006,0x0039 = [ ROI Contour Sequence ] - gdcm::SeqEntry * roi_contour_seq=mFile->GetSeqEntry(0x3006,0x0039); - assert(roi_contour_seq); // TODO error message - int n=0; - for (gdcm::SQItem* r=roi_contour_seq->GetFirstSQItem(); r!=0; r=roi_contour_seq->GetNextSQItem()) { - DicomRT_ROI::Pointer roi = DicomRT_ROI::New(); - roi->Read(mMapOfROIName, r); - mROIs[roi->GetROINumber()] = roi; - n++; + mROIs[nb] = DicomRT_ROI::New(); + mROIs[nb]->Read(mMapOfROIInfo[nb], mMapOfROIContours[nb]); } + + return; -#endif } //-------------------------------------------------------------------- diff --git a/vv/vvToolTest.cxx b/vv/vvToolTest.cxx index e583ac4..b364d8b 100644 --- a/vv/vvToolTest.cxx +++ b/vv/vvToolTest.cxx @@ -35,6 +35,7 @@ #include #include +#include //------------------------------------------------------------------------------ // Create the tool and automagically (I like this word) insert it in @@ -190,6 +191,30 @@ void vvToolTest::InputIsSelected(vvSlicerManager * m) // connect(mCurrentSlicerManager, SIGNAL(LeftButtonReleaseSignal(int)), SLOT(LeftButtonReleaseEvent(int))); //InteractiveDisplayToggled(mInteractiveDisplayIsEnabled); + + + +typedef signed short InputPixelType; +const unsigned int Dimension = 3; +typedef itk::Image< InputPixelType, Dimension > InputImageType; +typedef itk::ImageFileReader< InputImageType > ReaderType; +ReaderType::Pointer reader = ReaderType::New(); +reader->SetFileName( "/home/tbaudier/BJ13/RTSTRUCT/1.2.840.113704.1.111.4140.1439902720.30/20160201/160325.000000_/2.16.840.1.113669.1919.1454339005/2.16.840.1.113669.1919.1454339005/1.2.840.10008.5.1.4.1.1.481.3.1454339000.dcm" ); +typedef itk::GDCMImageIO ImageIOType; +ImageIOType::Pointer gdcmImageIO = ImageIOType::New(); +reader->SetImageIO( gdcmImageIO ); +try +{ +reader->Update(); +} +catch (itk::ExceptionObject & e) +{ +std::cerr << "exception in file reader " << std::endl; +std::cerr << e.GetDescription() << std::endl; +std::cerr << e.GetLocation() << std::endl; +return; +} + } //------------------------------------------------------------------------------ -- 2.47.1