From cb3a8e38ad6e95fad9c79b889bbe6ce972709b47 Mon Sep 17 00:00:00 2001 From: jpr Date: Sat, 30 Jul 2005 18:37:48 +0000 Subject: [PATCH] vtkgdcmSerieViewer shows an example for using user supplied function. (it uses now the Argument Manager) vtkgdcmSerieViewer : Display a Serie within a Directory You can navigate through the stack by hitting any character key. usage: vtkgdcmSerieViewer filein=fileName [noshadowseq][noshadow][noseq] [reverse] [{[mirror]|[topdown]|[rotate]}] [check][debug] --- vtk/vtkgdcmSerieViewer.cxx | 244 ++++++++++++++++++++++++++++++++++--- 1 file changed, 224 insertions(+), 20 deletions(-) diff --git a/vtk/vtkgdcmSerieViewer.cxx b/vtk/vtkgdcmSerieViewer.cxx index 7e2d3d31..322dae31 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/29 15:24:04 $ - Version: $Revision: 1.3 $ + Date: $Date: 2005/07/30 18:37:48 $ + Version: $Revision: 1.4 $ 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,29 +87,86 @@ public: vtkImageViewer *ImageViewer; }; - int main(int argc, char *argv[]) { - if( argc == 1 ) + START_USAGE(usage) + " \n vtkgdcmSerieViewer : \n", + " Display a Serie within a Directory ", + " You can navigate through the stack by hitting any character key. ", + " usage: vtkgdcmSerieViewer filein=fileName [noshadowseq][noshadow][noseq] ", + " [reverse] [{[mirror]|[topdown]|[rotate]}] ", + " [check][debug] ", + " 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 ", + " 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 ", + " debug : user wants to run the program in 'debug mode' ", + FINISH_USAGE + + + // Initialize Arguments Manager + gdcm::ArgMgr *am= new gdcm::ArgMgr(argc, argv); + + 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 << "Usage : vtkgdcmSerieViewer directoryName [reverse] [debug]" + std::cout << "mirror *OR* topDown *OR* rotate !" << std::endl; + delete am; return 0; } - if( argc > 3 ) - gdcm::Debug::DebugOn(); - - vtkGdcmReader *reader = vtkGdcmReader::New(); - reader->AllowLookupTableOff(); + 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); - if (argc > 2) - sh->SetSortOrderToReverse(); // just to check - sh->SetDirectory( argv[1], true); + sh->SetLoadMode(loadMode); + if (reverse) + sh->SetSortOrderToReverse(); + sh->SetDirectory( dirName, true); // Just to see @@ -130,6 +194,24 @@ int main(int argc, char *argv[]) l = sh->GetNextCoherentFileList(); } + if (check) + { + if ( !sh->IsCoherent(l) ) // just be sure (?) + { + std::cout << "Files are not coherent. Stop everything " << std::endl; + delete sh; + return 0; + } + } + + vtkGdcmReader *reader = vtkGdcmReader::New(); + reader->AllowLookupTableOff(); + + if (mirror) + reader->SetUserFunction (userSuppliedMirrorFunction); + else if (topdown) + reader->SetUserFunction (userSuppliedTopDownFunction); + // Only the first FileList is dealt with (just an example) // (The files will not be parsed twice by the reader) @@ -137,10 +219,9 @@ int main(int argc, char *argv[]) reader->SetCoherentFileList(l); //--------------------------------------------------------- - -// TODO : allow user to choose Load Mode - - // 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: @@ -198,3 +279,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; +} + + + + -- 2.45.1