X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=Example%2FAnonymizeMultiPatient.cxx;h=3008aecaaa0b3a84344e78db327c5e544e28abd3;hb=8d0468bd872660b30ce957dd00004ea205a2b135;hp=4b57eb582d941a3be7edf0343c6fd1010f613877;hpb=ba4495175f2189e1cfba96f568d8c33053da8260;p=gdcm.git diff --git a/Example/AnonymizeMultiPatient.cxx b/Example/AnonymizeMultiPatient.cxx index 4b57eb58..3008aeca 100755 --- a/Example/AnonymizeMultiPatient.cxx +++ b/Example/AnonymizeMultiPatient.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: AnonymizeMultiPatient.cxx,v $ Language: C++ - Date: $Date: 2006/05/30 08:26:36 $ - Version: $Revision: 1.1 $ + Date: $Date: 2007/11/13 11:49:09 $ + Version: $Revision: 1.7 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -15,43 +15,53 @@ PURPOSE. See the above copyright notices for more information. =========================================================================*/ -#include "gdcmFile.h" -#include "gdcmFileHelper.h" -#include "gdcmCommon.h" -#include "gdcmUtil.h" -#include "gdcmDebug.h" -#include "gdcmDirList.h" - +#include "gdcmDocEntry.h" #include "gdcmDicomDir.h" #include "gdcmDicomDirPatient.h" #include "gdcmDicomDirStudy.h" +#include "gdcmDicomDirVisit.h" #include "gdcmDicomDirSerie.h" #include "gdcmDicomDirImage.h" +#include "gdcmDirList.h" +#include "gdcmDebug.h" +#include "gdcmUtil.h" +#include "gdcmFile.h" +#include "gdcmFileHelper.h" #include "gdcmArgMgr.h" #include +/** + * \brief Explores recursively the given directory + * orders the gdcm-readable found Files + * according their Patient/Study/Serie/Image characteristics + * and anomymizes (NoLoad) them, creates a different name for each Patient. + */ -int main(int argc, char *argv[]) +int main(int argc, char *argv[]) { START_USAGE(usage) " \n AnonymizeMultiPatient :\n ", " AnonymizeMultiPatient a full gdcm-readable Dicom image ", + " optionnaly, creates the DICOMDIR ", " Warning : the image is OVERWRITTEN ", " to preserve image integrity, use a copy. ", - " usage: AnonymizeMultiPatient dirin=inputDirectoryName dirout=outputDirectoryName", + " usage: AnonymizeMultiPatient dirin=inputDirectoryName dicomdir ", " listOfElementsToRubOut : group-elem,g2-e2,... (in hexa, no space) ", " of extra Elements to rub out ", + " dicomdir : user wants to generate a DICOMDIR ", " 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 ", - " verbose : user wants to run the program in 'verbose mode' ", + " verbose : user wants to run the program in 'verbose mode' ", " debug : user wants to run the program in 'debug mode' ", FINISH_USAGE + + // ----- Initialize Arguments Manager ------ - gdcm::ArgMgr *am = new gdcm::ArgMgr(argc, argv); + GDCM_NAME_SPACE::ArgMgr *am = new GDCM_NAME_SPACE::ArgMgr(argc, argv); if (argc == 1 || am->ArgMgrDefined("usage")) { @@ -59,42 +69,38 @@ int main(int argc, char *argv[]) delete am; return 0; } - const char *dirName = am->ArgMgrGetString("dirin"); - if ( dirName == NULL ) + const char * name = am->ArgMgrGetString("dirin"); + if ( name == NULL ) { delete am; return 0; } - /* - char *outputDirName = am->ArgMgrWantString("dirout",usage); - if ( outputDirName == NULL ) - { - delete am; - return 0; - } - */ + std::string dirName = name; - bool verbose = am->ArgMgrDefined("verbose"); + bool verbose = ( 0 != am->ArgMgrDefined("verbose") ); + bool dicomdir = ( 0 != am->ArgMgrDefined("dicomdir") ); if (am->ArgMgrDefined("debug")) - gdcm::Debug::DebugOn(); + GDCM_NAME_SPACE::Debug::DebugOn(); - int loadMode = gdcm::LD_ALL; + int loadMode = GDCM_NAME_SPACE::LD_ALL; + if ( am->ArgMgrDefined("noshadowseq") ) - loadMode |= gdcm::LD_NOSHADOWSEQ; + loadMode |= GDCM_NAME_SPACE::LD_NOSHADOWSEQ; else { if ( am->ArgMgrDefined("noshadow") ) - loadMode |= gdcm::LD_NOSHADOW; + loadMode |= GDCM_NAME_SPACE::LD_NOSHADOW; if ( am->ArgMgrDefined("noseq") ) - loadMode |= gdcm::LD_NOSEQ; + loadMode |= GDCM_NAME_SPACE::LD_NOSEQ; } + int rubOutNb; uint16_t *elemsToRubOut = am->ArgMgrGetXInt16Enum("rubout", &rubOutNb); - // if unused Param we give up + // ----------- if unused Param we give up if ( am->ArgMgrPrintUnusedLabels() ) { am->ArgMgrUsage(usage); @@ -103,145 +109,84 @@ int main(int argc, char *argv[]) } delete am; // we don't need Argument Manager any longer - + + // ---------------------------------------------------------- - // ----- Begin Processing ----- - gdcm::DicomDir *dcmdir; + // ----- Begin Processing ----- - // we ask for Directory parsing + GDCM_NAME_SPACE::DicomDir *dcmdir; - dcmdir = gdcm::DicomDir::New( ); + // we ask for Directory parsing + dcmdir = GDCM_NAME_SPACE::DicomDir::New( ); dcmdir->SetLoadMode(loadMode); dcmdir->SetDirectoryName(dirName); dcmdir->Load(); - - - gdcm::DicomDirPatient *pa; - gdcm::DicomDirStudy *st; - gdcm::DicomDirSerie *se; - gdcm::DicomDirVisit *vs; - gdcm::DicomDirImage *im; - - // Test if the DicomDir contains any Patient - pa = dcmdir->GetFirstPatient(); - if ( pa == 0) + if ( verbose ) + std::cout << "======================= End Parsing Directory" << std::endl; + + // ----- Check the result + + if ( !dcmdir->GetFirstPatient() ) { - std::cout<<" DicomDir '"<< dirName - <<" has no patient"<Delete(); return 1; - } - - if ( verbose ) - std::cout << "-------------------------- Directory [" << dirName << "] parsed" << std::endl; - -// Since files may be help in a Directory tree-like structure -// we should have to duplicate this structure. -// No time to code that stuff -// --> We 'AnonymizeNoLoad' (overwrite the files) - -// Do not remove the commented out lines. -// They will be usefull in a further program. -/* - std::string systemCommand; - - std::cout << "Check for output directory :[" << outputDirName << "]." - <GetEntryString(0x0010, 0x0010) <<"]"; // Patient's Name - std::cout << " Pat.ID:["; - std::cout << pa->GetEntryString(0x0010, 0x0020) << "]" << std::endl; // Patient ID - } - std::string patName = pa->GetEntryString(0x0010, 0x0010); - //codedName = "g^" + gdcm::Util::ConvertToMD5(patName); // just to be sure MD5 is not guilty - std::string fullFileName; - if (verbose) - std::cout << patName << " --> " << codedName << std::endl; - - st = pa->GetFirstStudy(); + GDCM_NAME_SPACE::DicomDirPatient *pa; + GDCM_NAME_SPACE::DicomDirStudy *st; + GDCM_NAME_SPACE::DicomDirSerie *se; + GDCM_NAME_SPACE::DicomDirImage *im; + + std::string codedName; + std::string codedID; + std::string fullFileName; + std::string patName; + std::string patID; + + GDCM_NAME_SPACE::File *f; + + pa = dcmdir->GetFirstPatient(); + while ( pa ) + { // on degouline les PATIENT du DICOMDIR + patName = pa->GetEntryString(0x0010, 0x0010); + codedName = "g^" + GDCM_NAME_SPACE::Util::ConvertToMD5(patName); + patID = pa->GetEntryString(0x0010, 0x0020); + codedID = GDCM_NAME_SPACE::Util::ConvertToMD5(patID); + + if (verbose) { + std::cout << "[" << patName << "] --> [" << codedName << "]" << std::endl; + std::cout << "[" << patID << "] --> [" << codedID << "]" << std::endl; + } + st = pa->GetFirstStudy(); while ( st ) { // on degouline les STUDY de ce patient - if (verbose) - { - std::cout << "--- Stud.descr:[" << st->GetEntryString(0x0008, 0x1030) << "]"; // Study Description - std::cout << " Stud.ID:[" << st->GetEntryString(0x0020, 0x0010) << "]"; // Study ID - std::cout << std::endl; - } se = st->GetFirstSerie(); while ( se ) { // on degouline les SERIES de cette study - if (verbose) - { - std::cout << "--- --- Ser.Descr:["<< se->GetEntryString(0x0008, 0x103e) << "]"; // Series Description - std::cout << " Ser.nb:[" << se->GetEntryString(0x0020, 0x0011) << "]"; // Series number - std::cout << " Mod.:[" << se->GetEntryString(0x0008, 0x0060) << "]"; // Modality - std::cout << " Serie Inst.UID.:[" << se->GetEntryString(0x0020, 0x000e) << "]"; // Series Instance UID - std::cout << std::endl; - } - im = se->GetFirstImage(); - std::string ReferencedFileID; while ( im ) - { // on degouline les IMAGEs de cette serie - ReferencedFileID = im->GetEntryString(0x0004, 0x1500); - if (verbose) - { - std::cout << "--- --- --- "<< " IMAGE Ref. File ID :[" << ReferencedFileID - << "]" << std::endl; // File name (Referenced File ID) - } - f = gdcm::File::New( ); - f->SetLoadMode(loadMode); + { // on degouline les Images de cette serie fullFileName = dirName; - - std::cout << "fullFileName (1) " << fullFileName << std::endl; - std::cout << "ReferencedFileID " << ReferencedFileID << std::endl; - fullFileName = fullFileName + "/" + ReferencedFileID; - std::cout << "fullFileName (2) " << fullFileName << std::endl; + fullFileName += GDCM_NAME_SPACE::GDCM_FILESEPARATOR; + fullFileName += im->GetEntryString(0x0004, 0x1500); + if (verbose) + std::cout << "FileName " << fullFileName << std::endl; + f = GDCM_NAME_SPACE::File::New( ); + f->SetLoadMode(loadMode); f->SetFileName( fullFileName ); - if ( !f->Load() ) - std::cout << "Load failed for [" << fullFileName << "]" << std::endl; + std::cout << "Load failed for [" << fullFileName << "]" << std::endl; else - std::cout << "Load successed for [" << fullFileName << "]" << std::endl; - + if (verbose) + std::cout << "Load successed for [" << fullFileName << "]" << std::endl; + // // Choose the fields to anonymize. // @@ -253,7 +198,8 @@ int main(int argc, char *argv[]) f->AddAnonymizeElement( 0x0010, 0x0010, codedName ); // Patient's ID - f->AddAnonymizeElement( 0x0010, 0x0020,"1515" ); + //f->AddAnonymizeElement( 0x0010, 0x0020,"1515" ); + f->AddAnonymizeElement( 0x0010, 0x0020,codedID ); // Patient's Birthdate f->AddAnonymizeElement( 0x0010, 0x0030,"11111111" ); // Patient's Adress @@ -264,83 +210,49 @@ int main(int argc, char *argv[]) // Study Instance UID // we may not brutaly overwrite it //f->AddAnonymizeElement( 0x0020, 0x000d, "9.99.999.9999" ); - + // Telephone f->AddAnonymizeElement(0x0010, 0x2154, "3615" ); // deal with user defined Elements set -std::cout << "rubOutNb " << rubOutNb << std::endl; for (int ri=0; riAddAnonymizeElement((uint32_t)elemsToRubOut[2*ri], - (uint32_t)elemsToRubOut[2*ri+1],"*" ); + (uint32_t)elemsToRubOut[2*ri+1],"*" ); } - - // The gdcm::File is modified in memory - // f->AnonymizeFile(); - - // - // Overwrite the file - // - // The gdcm::File remains untouched in memory - f->AnonymizeNoLoad(); - - // ============================================================ - // Write a new file - // ============================================================ - - // - // No need to load the pixels in memory. - // File will be overwritten - // Do not remove the commented out lines. - // They will be usefull in a further program. - // -/* - // Get the Pixels - fh = gdcm::FileHelper::New(f); - - // unit8_t DOESN'T mean it's mandatory for the image to be a 8 bits one ! - // Feel free to cast if you know it's not. - - uint8_t *imageData = fh->GetImageData(); - - if ( imageData == 0 ) - { - std::cerr << "Sorry, Pixels of" << im->GetEntryString(0x0004, 0x1500) <<" are not " - << " gdcm-readable." << std::endl - << "Use AnonymizeNoLoad" << std::endl; - f->Delete(); - fh->Delete(); - break; - } - - // Since we just Anonymized the file, we *know* no modification - // was performed on the pixels. - // The written image will not appear as a 'Secondary Captured image' - // nor as a DERIVED one - - fh->SetContentType(gdcm::UNMODIFIED_PIXELS_IMAGE); - outputFileName = outputDirName + "/" + im->GetEntryString(0x0004, 0x1500); - fh->WriteDcmExplVR(outputFileName); - std::cout <<"End Anonymize" << std::cout; - - fh->Delete(); -*/ + // + // Overwrite the file + // + // The GDCM_NAME_SPACE::File remains untouched in memory + + f->AnonymizeNoLoad(); - f->Delete(); - f->ClearAnonymizeList(); - - im = se->GetNextImage(); - } - se = st->GetNextSerie(); - } - st = pa->GetNextStudy(); - } - + f->ClearAnonymizeList(); + f->Delete(); + + im = se->GetNextImage(); + } + se = st->GetNextSerie(); + } + st = pa->GetNextStudy(); + } pa = dcmdir->GetNextPatient(); - } - -} + } + dcmdir->Delete(); + + if (dicomdir) + { + std::cout << "DICOMDIR creation in progress ..." << std::endl; + dcmdir = GDCM_NAME_SPACE::DicomDir::New( ); + dcmdir->SetLoadMode(loadMode); + dcmdir->SetDirectoryName(dirName); + dcmdir->Load(); + dcmdir->Write("DICOMDIR"); + } + + return 0; + +}