X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=vtk%2FvtkgdcmSerieViewer.cxx;h=790ca4666e3e58f6d1819c34032d38a09620975b;hb=af52d821b66539803b39c1ca733ae8a09aa85379;hp=27cd1f41477badf92f9f32609d73c127d22ffe60;hpb=f9d9a7792af5b583c9e5ed6a289cab94b7a1239b;p=gdcm.git diff --git a/vtk/vtkgdcmSerieViewer.cxx b/vtk/vtkgdcmSerieViewer.cxx index 27cd1f41..790ca466 100644 --- a/vtk/vtkgdcmSerieViewer.cxx +++ b/vtk/vtkgdcmSerieViewer.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: vtkgdcmSerieViewer.cxx,v $ Language: C++ - Date: $Date: 2005/07/17 04:36:14 $ - Version: $Revision: 1.1 $ + Date: $Date: 2005/08/22 12:21:03 $ + 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 @@ -23,8 +23,8 @@ // a stack of Dicom images into a native vtk volume. // // Usage: -// * the filenames of the Dicom images constituting the stack should be -// given as command line arguments, +// * the Directory name that contains the Dicom images constituting the stack +// should be given as command line argument, // * you can navigate through the stack by hitting any character key, // * the produced vtk file is named "foo.vtk" (in the invocation directory). // @@ -42,10 +42,14 @@ #include "gdcmDocument.h" // for NO_SHADOWSEQ #include "gdcmSerieHelper.h" #include "gdcmDebug.h" +#include "gdcmArgMgr.h" // for Argument Manager functions #ifndef vtkFloatingPointType #define vtkFloatingPointType float #endif +void userSuppliedMirrorFunction (uint8_t *im, gdcm::File *f); +void userSuppliedTopDownFunction(uint8_t *im, gdcm::File *f); + //---------------------------------------------------------------------------- // Callback for the interaction class vtkgdcmObserver : public vtkCommand @@ -55,14 +59,17 @@ public: { return "vtkgdcmObserver"; } + static vtkgdcmObserver *New() { return new vtkgdcmObserver; } + vtkgdcmObserver() { this->ImageViewer = NULL; } + virtual void Execute(vtkObject *, unsigned long event, void* ) { if ( this->ImageViewer ) @@ -80,24 +87,92 @@ public: vtkImageViewer *ImageViewer; }; - int main(int argc, char *argv[]) { - if( argc < 2 ) - return 0; + START_USAGE(usage) + " \n vtkgdcmSerieViewer : \n", + " Display a 'Serie' (same Serie UID) within a Directory ", + " You can navigate through the stack by hitting any character key. ", + " usage: vtkgdcmSerieViewer dirname=sourcedirectory ", + " [noshadowseq][noshadow][noseq] ", + " [reverse] [{[mirror]|[topdown]|[rotate]}] ", + " [check][debug] ", + " sourcedirectory : name of the directory holding the images ", + " if it holds more than one serie, ", + " only the first one id displayed. ", + " noshadowseq: user doesn't want to load Private Sequences ", + " noshadow : user doesn't want to load Private groups (odd number) ", + " noseq : user doesn't want to load Sequences ", + " reverse : user wants to sort the images reverse order ", + " mirror : user wants to 'mirror' the images | just some simple ", + " topdown : user wants to 'topdown' the images| examples of user ", + " rotate : user wants NOT YET MADE | supplied functions ", + " check : user wants to force more coherence checking ", + " debug : user wants to run the program in 'debug mode' ", + FINISH_USAGE - if( argc > 2 ) - gdcm::Debug::DebugOn(); + // Initialize Arguments Manager + gdcm::ArgMgr *am= new gdcm::ArgMgr(argc, argv); - vtkGdcmReader *reader = vtkGdcmReader::New(); - reader->AllowLookupTableOff(); + if (argc == 1 || am->ArgMgrDefined("usage") ) + { + am->ArgMgrUsage(usage); // Display 'usage' + delete am; + return 0; + } + + char *dirName = am->ArgMgrWantString("dirname",usage); + + int loadMode = 0x00000000; + if ( am->ArgMgrDefined("noshadowseq") ) + loadMode |= NO_SHADOWSEQ; + else + { + if ( am->ArgMgrDefined("noshadow") ) + loadMode |= NO_SHADOW; + if ( am->ArgMgrDefined("noseq") ) + loadMode |= NO_SEQ; + } + bool reverse = am->ArgMgrDefined("reverse"); + + bool mirror = am->ArgMgrDefined("mirror"); + bool topdown = am->ArgMgrDefined("topdown"); + bool rotate = am->ArgMgrDefined("rotate"); + + bool check = am->ArgMgrDefined("check"); + + if ( (int)mirror + (int)topdown + (int)rotate > 1) + { + std::cout << "mirror *OR* topDown *OR* rotate !" + << std::endl; + delete am; + return 0; + } + + if (am->ArgMgrDefined("debug")) + gdcm::Debug::DebugOn(); + + /* if unused Param we give up */ + if ( am->ArgMgrPrintUnusedLabels() ) + { + am->ArgMgrUsage(usage); + delete am; + return 0; + } + + delete am; // we don't need Argument Manager any longer + + // ----------------------- End Arguments Manager ---------------------- + // ------------ to check Coherent File List as a parameter gdcm::SerieHelper *sh = new gdcm::SerieHelper(); - sh->SetLoadMode(NO_SHADOWSEQ); - sh->SetDirectory( argv[1], true); + sh->SetLoadMode(loadMode); + if (reverse) + sh->SetSortOrderToReverse(); + sh->SetDirectory( dirName, true); // Just to see @@ -112,7 +187,7 @@ int main(int argc, char *argv[]) while (l) { nbFiles = l->size() ; - if ( l->size() > 0 ) // Why not ? Just an example, for testing + if ( l->size() > 1 ) { std::cout << "Sort list : " << nbFiles << " long" << std::endl; sh->OrderFileList(l); // sort the list @@ -125,19 +200,34 @@ int main(int argc, char *argv[]) l = sh->GetNextCoherentFileList(); } - reader->SetCoherentFileList(l); + if (check) + { + if ( !sh->IsCoherent(l) ) // just be sure (?) + { + std::cout << "Files are not coherent. Stop everything " << std::endl; + delete sh; + return 0; + } + } -/* - if( argc == 2 ) - reader->SetFileName( argv[1] ); - else - for(int i=1; i< argc; i++) - reader->AddFileName( argv[i] ); -*/ + vtkGdcmReader *reader = vtkGdcmReader::New(); + reader->AllowLookupTableOff(); + + if (mirror) + reader->SetUserFunction (userSuppliedMirrorFunction); + else if (topdown) + reader->SetUserFunction (userSuppliedTopDownFunction); -// TODO : allow user to choose Load Mode + // Only the first FileList is dealt with (just an example) + // (The files will not be parsed twice by the reader) + + //--------------------------------------------------------- + reader->SetCoherentFileList(l); + //--------------------------------------------------------- - // reader->SetLoadMode(NO_SHADOWSEQ); + // because we passed a Coherent File List from a SerieHelper, + // setting LoadMode is useless in this case + // reader->SetLoadMode(NO_SHADOWSEQ); reader->Update(); //print debug info: @@ -195,3 +285,126 @@ int main(int argc, char *argv[]) return 0; } + + +// -------------------------------------------------------- +// This is just a *very* simple example of user supplied function +// to mirror (why not ?) the image +// It's *not* part of gdcm. +// -------------------------------------------------------- + +#define UF(ty) \ + int i, j; \ + ty *imj; \ + ty tamp; \ + for (j=0;jGetZSize() != 1) + { + std::cout << "mirror : Multiframe images not yet dealt with" << std::endl; + return; + } + + if (f->GetSamplesPerPixel() != 1 || f->GetBitsAllocated() == 24) + { + std::cout << "mirror : RGB / YBR not yet dealt with" << std::endl; + return; + } + int nx = f->GetXSize(); + int ny = f->GetYSize(); + + std::string pixelType = f->GetPixelType(); + if ( pixelType == "8U" || pixelType == "8S" ) + { + UF(uint8_t) + return; + } + if ( pixelType == "16U" || pixelType == "16S") + { + UF(uint16_t) + return; + } + std::cout << "mirror : Pixel Size (!=8, !=16) not yet dealt with" + << std::endl; + return; +} + + +// -------------------------------------------------------- +// This is just a *very* simple example of user supplied function +// to topdown (why not ?) the image +// It's *not* part of gdcm. +// -------------------------------------------------------- + +#define UF2(ty) \ + int i, j; \ + ty *imj, *imJ; \ + ty tamp; \ + for (j=0;jGetZSize() != 1) + { + std::cout << "mirror : Multiframe images not yet dealt with" << std::endl; + return; + } + + if (f->GetSamplesPerPixel() != 1 || f->GetBitsAllocated() == 24) + { + std::cout << "mirror : RGB / YBR not yet dealt with" << std::endl; + return; + } + int nx = f->GetXSize(); + int ny = f->GetYSize(); + + std::string pixelType = f->GetPixelType(); + if ( pixelType == "8U" || pixelType == "8S" ) + { + UF2(uint8_t) + return; + } + if ( pixelType == "16U" || pixelType == "16S") + { + UF2(uint16_t) + return; + } + std::cout << "topdown : Pixel Size (!=8, !=16) not yet dealt with" + << std::endl; + return; +} + + + +