X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=vtk%2FvtkGdcm4DSplitter.cxx;h=3f632c28c2d575274924f1c0cd26392df6f7bee2;hb=c9387641191b32da1ca5088cdb262819a55281ca;hp=6ab01f6aad2ecc941319fc0cd8dd4ce8c8f90b86;hpb=9c2a69fd5efbcd96f0130811bc0043a0b5d69c92;p=gdcm.git diff --git a/vtk/vtkGdcm4DSplitter.cxx b/vtk/vtkGdcm4DSplitter.cxx index 6ab01f6a..3f632c28 100644 --- a/vtk/vtkGdcm4DSplitter.cxx +++ b/vtk/vtkGdcm4DSplitter.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: vtkGdcm4DSplitter.cxx,v $ Language: C++ - Date: $Date: 2011/03/29 12:49:27 $ - Version: $Revision: 1.1 $ + Date: $Date: 2011/03/30 14:49:04 $ + Version: $Revision: 1.5 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -27,6 +27,76 @@ On Wed, Feb 16, 2011 at 11:51 AM, Roger Bramon Feixas (ImageSeriesReader::GenerateData() line 393). */ + +/* ==================================================================== +vtkGdcm4DSplitter + +3D, 2D+T, 3D+T, n*2D+T, 4D images are not always stored the same way : + a single 'Dicom Serie', + several 'Dicom series' within a single directory + several 'Dicom series' within several directories +A 'Dicom Serie' doesn't mean always the same thing : + a given Slice along the time + a given Volume at a given time +Sometimes, an image within a serie is so artefacted than user decides to replace +it by an other image. + +User needs to be aware, *only him* knows want he wants to do. +vtkGdcm4DSplitter class does the job for hom +(despite its name, it works on 3D or 2D+T images too) + +User will have to specify some points + +. Choose input data +------------------- + +- a single directory + bool setDirName(std::string &dirName); +- a list of directories + bool setVectDirName(std::vector &vectDirName); +- a list of files + bool setVectFileName(std::vector &vectFileName); + +- Recursive directory exploration + void setRecursive(bool recursive); + +. Choose 'split' criterion : +--------------------------- + + - ImagePositionPatient + void setSplitOnPosition(); + - ImageOrientationPatient + void setSplitOnOrientation(); + - User choosen tag + ==> WARNING : This one has troubles; do NOT use it, right now! + void setSplitOnTag(unsigned short splitGroup, unsigned short splitElem); + void setSplitConvertToFloat(bool conv); + - UserDefined Function + void setSortOnUserFunction (FoncComp f); + +. Choose 'sort' criterion : +-------------------------- + + - ImagePositionPatient + void setSortOnPosition(); + - User choosen tag + void setSortOnTag(unsigned short sortGroup, unsigned short sortElem); + void setSortConvertToFloat(bool conv) + +. Execute +----------- + bool Go(); + +. Get the result +---------------- + + -a single vtkImageData: + vtkImageData *GetImageData(); +- a vector of vtkImageData + std::vector *GetImageDataVector(); + + ===================================================================== */ + #include "gdcmSerieHelper.h" #include "vtkGdcmReader.h" @@ -119,18 +189,20 @@ On Wed, Feb 16, 2011 at 11:51 AM, Roger Bramon Feixas return true; } - bool vtkGdcm4DSplitter::CompareOnSortTagConvertToFloat(GDCM_NAME_SPACE::File *file1, GDCM_NAME_SPACE::File *file2) + /*static */bool vtkGdcm4DSplitter::CompareOnSortTagConvertToFloat(GDCM_NAME_SPACE::File *file1, GDCM_NAME_SPACE::File *file2) { - if (verbose) printf ("%04x %04x\n", this->SortGroup,this->SortElem); + /* if (verbose) printf ("%04x %04x\n", this->SortGroup,this->SortElem); if (verbose) std :: cout << file1->GetEntryString(SortGroup,SortElem).c_str() << " : " << atof(file1->GetEntryString(SortGroup,SortElem).c_str()) << std::endl; - return atof(file1->GetEntryString(SortGroup,SortElem).c_str()) < atof(file2->GetEntryString(SortGroup,SortElem).c_str()); +*/ +// return atof(file1->GetEntryString(vtkGdcm4DSplitter::SortGroup,vtkGdcm4DSplitter::SortElem).c_str()) < atof(file2->GetEntryString(vtkGdcm4DSplitter::SortGroup,vtkGdcm4DSplitter::SortElem).c_str()); + return atof(file1->GetEntryString(SortGroup,SortElem).c_str()) < atof(file2->GetEntryString(SortGroup,SortElem).c_str()); } - bool vtkGdcm4DSplitter::CompareOnSortTag(GDCM_NAME_SPACE::File *file1, GDCM_NAME_SPACE::File *file2) + /*static */bool vtkGdcm4DSplitter::CompareOnSortTag(GDCM_NAME_SPACE::File *file1, GDCM_NAME_SPACE::File *file2) { - return file1->GetEntryString(SortGroup,SortElem) < file2->GetEntryString(SortGroup,SortElem); + return file1->GetEntryString(vtkGdcm4DSplitter::SortGroup,vtkGdcm4DSplitter::SortElem) < file2->GetEntryString(vtkGdcm4DSplitter::SortGroup,vtkGdcm4DSplitter::SortElem); } bool vtkGdcm4DSplitter::Go() @@ -245,7 +317,8 @@ On Wed, Feb 16, 2011 at 11:51 AM, Roger Bramon Feixas TypeResult=2; ImageDataVector = new std::vector; - vtkGdcmReader *reader = vtkGdcmReader::New(); + // vtkGdcmReader *reader = vtkGdcmReader::New(); // move inside the loop, or be clever using vtk! + for (GDCM_NAME_SPACE::XCoherentFileSetmap::iterator i = xcm.begin(); i != xcm.end(); ++i) @@ -259,19 +332,22 @@ On Wed, Feb 16, 2011 at 11:51 AM, Roger Bramon Feixas i != xcm.end(); ++i) { - if (verbose) + + vtkGdcmReader *reader = vtkGdcmReader::New(); /// \FIXME : unable to delete! + + if (verbose) std::cout << "==========================================xCoherentName = [" << (*i).first << "]" << std::endl; - if (SortOnPosition) - { + if (SortOnPosition) + { if (verbose) std::cout << "SortOnPosition" << std::endl; // (will be IPPSorter, in GDCM2) s->ImagePositionPatientOrdering((*i).second); - if (verbose) std::cout << "out of SortOnPosition" << std::endl - } + if (verbose) std::cout << "out of SortOnPosition" << std::endl; + } - if (SortOnOrientation) - { + else if (SortOnOrientation) + { if (verbose) std::cout << "SortOnOrientation" << std::endl; /// \TODO SortOnOrientation() // Within a 'just to see' program, @@ -284,48 +360,70 @@ On Wed, Feb 16, 2011 at 11:51 AM, Roger Bramon Feixas // 0020,0030 : Image Position (RET) // we still miss an algo to sort an Orientation, given by 6 cosines! - // Anything like this, in GDCM2? - std::cout << "SortOnOrientation : not so easy - I(mage)O(rientation)P(atient)Sorter still missing! -" << std::endl; - // have a look at SerieHelper::SplitOnPosition() to have an idea of the mess! + // Anything like this, in GDCM2? + std::cout << "SortOnOrientation : not so easy - I(mage)O(rientation)P(atient)Sorter still missing! -" << std::endl; + // have a look at SerieHelper::SplitOnOrientation() to have an idea of the mess! - //Better sort on the file name, right now... - s->FileNameOrdering((*i).second); - } + //Better sort on the file name, right now... + s->FileNameOrdering((*i).second); + } - if (SortOnFileName) - { - if (verbose) std::cout << "SortOnFileName" << std::endl; - if (verbose) std::cout << "taille " << ((*i).second)->size() << std::endl; - s->FileNameOrdering((*i).second); - if (verbose) std::cout << "Out of SortOnFileName" << std::endl; - } + else if (SortOnFileName) + { + if (verbose) std::cout << "SortOnFileName" << std::endl; + if (verbose) std::cout << "taille " << ((*i).second)->size() << std::endl; - if (SortOnTag) - { - if (verbose) std::cout << "SortOnTag" << std::endl; - printf ("--> %04x %04x\n", SortGroup,SortElem); - if ( SortConvertToFloat ) - s->SetUserLessThanFunction( reinterpret_cast - ( &vtkGdcm4DSplitter::CompareOnSortTagConvertToFloat)); - else - s->SetUserLessThanFunction( reinterpret_cast - ( &vtkGdcm4DSplitter::CompareOnSortTag)); + s->FileNameOrdering((*i).second); + if (verbose) std::cout << "Out of SortOnFileName" << std::endl; + } + + else if (SortOnTag) + { + if (verbose) std::cout << "SortOnTag" << std::endl; + printf ("--> %04x %04x\n", SortGroup,SortElem); + std::cout << "Sorry, troubles not solved yet; use SortOnUserFunction, right now!" << std::endl; + + /* ==> WARNING : This one has troubles; do NOT use it, right now! + if ( SortConvertToFloat ) + s->SetUserLessThanFunction( reinterpret_cast + ( &vtkGdcm4DSplitter::CompareOnSortTagConvertToFloat)); + else + s->SetUserLessThanFunction( reinterpret_cast + ( &vtkGdcm4DSplitter::CompareOnSortTag)); - // Anything like this, in GDCM2? - s->UserOrdering((*i).second); - if (verbose) std::cout << "Out of SortOnTag" << std::endl; - } + // Anything like this, in GDCM2? + s->UserOrdering((*i).second); + */ + + //if (verbose) std::cout << "Out of SortOnTag" << std::endl; + std::cout << "NO ordering performed :-( " << std::endl; + } + + else if (SortOnUserFunction) + { + if (verbose) std::cout << "SortOnUserFunction" << std::endl; + s->SetUserLessThanFunction( UserCompareFunction ); + // Anything like this, in GDCM2? + s->UserOrdering((*i).second); + if (verbose) std::cout << "Out of SortOnUserFunction" << std::endl; + } - reader->SetCoherentFileList((*i).second); - reader->Update(); - ImageDataVector->push_back(reader->GetOutput() ); + reader->SetCoherentFileList((*i).second); + reader->Update(); + + /// \TODO : remove the following + //if (verbose) reader->GetOutput()->PrintSelf(std::cout, vtkIndent(2)); + + ImageDataVector->push_back(reader->GetOutput() ); - std::cout << std::endl; + std::cout << std::endl; } - reader->Delete(); + //reader->Delete(); // \TODO : fix s->Delete(); f->Delete(); delete l; + + return true; }