]> Creatis software - gdcm.git/commitdiff
Transform 'pcpdense' format files into Dicomfile (single or multiframes,
authorjpr <jpr>
Thu, 4 Sep 2008 14:10:44 +0000 (14:10 +0000)
committerjpr <jpr>
Thu, 4 Sep 2008 14:10:44 +0000 (14:10 +0000)
depending on users's choice)

Example/PcpdenseToDicom.cxx [new file with mode: 0644]

diff --git a/Example/PcpdenseToDicom.cxx b/Example/PcpdenseToDicom.cxx
new file mode 100644 (file)
index 0000000..359ad62
--- /dev/null
@@ -0,0 +1,511 @@
+/*=========================================================================
+                                                                                
+  Program:   gdcm
+  Module:    $RCSfile: PcpdenseToDicom.cxx,v $
+  Language:  C++
+  Date:      $Date: 2008/09/04 14:10:44 $
+  Version:   $Revision: 1.1 $
+                                                                                
+  Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
+  l'Image). All rights reserved. See Doc/License.txt or
+  http://www.creatis.insa-lyon.fr/Public/Gdcm/License.html for details.
+                                                                                
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notices for more information.
+                                                                                
+=========================================================================*/
+
+#include <fstream>
+#include <iostream>
+//#include <values.h>
+
+#if defined(__BORLANDC__)
+#include <ctype.h>
+#endif
+
+#include "gdcmFile.h"
+#include "gdcmFileHelper.h"
+#include "gdcmDebug.h"
+#include "gdcmDirList.h"
+#include "gdcmUtil.h"
+#include "gdcmArgMgr.h"
+
+/**
+  * \brief   
+  *  Converts the "pcpdense" ".txt" (2008 version)  files into 16 bits Dicom Files,
+  * Hope they don't change soon!
+  */  
+
+void MakeDicomImage(unsigned short int *tabVal, int X, int Y, std::string dcmImageName,
+                    const char * patientname, int nbFrames, std::string studyUID, std::string serieUID, std::string studyUID, int imgNum,bool m );
+
+void LoadImage(std::ifstream &from,  unsigned short int * );
+
+void LoadImageX2(std::ifstream &from, unsigned short int * );      
+bool verbose;
+
+int main(int argc, char *argv[])
+{
+   START_USAGE(usage)
+   " \n pcpdenseToDicom :\n                                                  ",
+   "        Converts the '.txt' files into 16 bits Dicom Files,               ",
+   " usage:                                                                   ",
+   " pcpdenseToDicom rootfilename=...                                        ",
+   "                 (e.g.. :   meas_MID380_DENSE_stacked_slices_aif_FID81637)",
+   "                 numberOfSlices =  (default : 3)                          ",
+   "                 X2 : multiply x 2 image size                             ",
+   "                 m :create multiframe files instead of image stacks       ", 
+   "                 [patientname = Patient's name]                           ",
+   "                 [verbose] [debug]                                        ",
+   "                                                                          ",
+   " verbose  : user wants to run the program in 'verbose mode'               ",
+   " debug    : *developer*  wants to run the program in 'debug mode'         ",
+   FINISH_USAGE
+
+   // ----- Initialize Arguments Manager ------
+      
+   GDCM_NAME_SPACE::ArgMgr *am = new GDCM_NAME_SPACE::ArgMgr(argc, argv);
+  
+   if (argc == 1 || am->ArgMgrDefined("usage")) 
+   {
+      am->ArgMgrUsage(usage); // Display 'usage'
+      delete am;
+      return 0;
+   }
+   // Seems that ArgMgrWantString doesn't work on MacOS   
+   if(!am->ArgMgrDefined("rootfilename"))
+   {
+      std::cout << "'rootfilename' is mandatory" << std::endl;
+      exit(0);   
+   }
+   const char *rootfilename = am->ArgMgrWantString("rootfilename",usage);
+   int numberOfSlices       = am->ArgMgrGetInt("numberOfSlices",3);
+   const char *patientName  = am->ArgMgrGetString("patientname", "Patient^Name");
+         
+   if (am->ArgMgrDefined("debug"))
+      GDCM_NAME_SPACE::Debug::DebugOn();
+
+   verbose         = ( 0 != am->ArgMgrDefined("verbose") );    
+   bool X2         = ( 0 != am->ArgMgrDefined("X2") );
+   bool multiframe = ( 0 != am->ArgMgrDefined("m") );
+
+   // 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
+
+   // ----- Begin Processing -----
+   
+   std::ostringstream Ecc;
+   std::ostringstream perf;
+   std::ostringstream WashoutTc;
+
+   std::string strSerieUID; 
+   std::string strStudyUID =  GDCM_NAME_SPACE::Util::CreateUniqueUID();
+   std::string dcmImageName, textFileName, patientname,/* studyUID, serieUID, */ serieDescr ;
+   std::string deb(rootfilename);
+   
+   unsigned short int *image;
+   
+   int NX, NY;
+     
+  // Get some info
+  // -------------
+
+     {
+        Ecc.str(rootfilename); 
+        Ecc   << Ecc.str() << "_s0" << "_Ecc.txt";
+
+        std::ifstream fromEcc( Ecc.str().c_str() );             
+        if ( !fromEcc )
+        {
+           std::cout << "Can't open file [" << Ecc.str() << "]" << std::endl;
+           exit(0);
+        }
+        std::string str1;
+
+         fromEcc >> str1;
+         fromEcc >> str1;
+
+         fromEcc >> NX;
+         fromEcc >> NY;
+         std::cout << "NX, NY : " << NX << ", " << NY << std::endl; 
+   }         
+
+   int mult;
+   if (X2)
+      mult=4;
+   else
+      mult=1;
+      
+   if (multiframe)
+      image = new unsigned short int[NX*NY*mult*numberOfSlices];
+   else
+      image = new unsigned short int[NX*NY*mult];        
+   
+   
+
+   // === Ecc ===
+   
+   strSerieUID =  GDCM_NAME_SPACE::Util::CreateUniqueUID();
+   if (!multiframe) {
+             
+     for (int i=0; i<numberOfSlices; i++)
+     {  
+        Ecc.str(rootfilename); 
+        Ecc   << Ecc.str()    << "_s" << i << "_Ecc.txt";
+      
+        std::ifstream fromEcc( Ecc.str().c_str() );             
+        if ( !fromEcc )
+        {
+           std::cout << "Can't open file [" << Ecc.str() << "]" << std::endl;
+           exit(0);
+        }
+        std::cout << "Open file [" << Ecc.str() << "] : OK" << std::endl;
+
+        if (X2)
+           LoadImageX2(fromEcc, image);
+        else
+           LoadImage(fromEcc, image);      
+        fromEcc.close();
+
+        dcmImageName = Ecc.str() + ".dcm";
+
+        MakeDicomImage(image, NX, NY, dcmImageName, patientName, 1, strStudyUID, strSerieUID, serieDescr, i, multiframe ); 
+   } // end : for (int i=0; i<numberOfSlices
+   delete []image;
+}
+
+      
+   if (multiframe) {
+     
+     for (int i=0; i<numberOfSlices; i++)
+     {  
+        Ecc.str(rootfilename);
+        Ecc   << Ecc.str()    << "_s" << i << "_Ecc.txt";
+      
+        std::ifstream fromEcc( Ecc.str().c_str() );             
+        if ( !fromEcc )
+        {
+           std::cout << "Can't open file [" << Ecc.str() << "]" << std::endl;
+           exit(0);
+        }
+
+        std::cout << "Open file [" << Ecc.str() << "] : OK" << std::endl;
+        if (X2)
+          LoadImageX2(fromEcc ,&image[NX*NY*i] );
+        else
+          LoadImage(fromEcc, &image[NX*NY*i] );
+        
+        fromEcc.close();
+     } // end : for (int i=0; i<numberOfSlices
+     
+     dcmImageName = deb + "_Ecc.dcm";
+     MakeDicomImage(image, NX, NY, dcmImageName, patientName, numberOfSlices, strStudyUID, strSerieUID, serieDescr, 0, multiframe ); 
+  
+   }  // end : if (multiframe) 
+
+
+
+// === perf ===
+
+   strSerieUID =  GDCM_NAME_SPACE::Util::CreateUniqueUID();
+
+   if (!multiframe) {    
+     for (int i=0; i<numberOfSlices; i++)
+     {      
+        perf.str(rootfilename);
+        perf  << perf.str()    << "_s" << i << "_perf.txt";
+
+        std::ifstream fromperf( perf.str().c_str() );             
+        if ( !fromperf )
+        {
+           std::cout << "Can't open file [" << perf.str() << "]" << std::endl;
+           exit(0);
+        }
+        std::cout << "Open file [" << perf.str() << "] : OK" << std::endl;
+
+        if (X2)
+          LoadImageX2(fromperf ,image );
+        else
+          LoadImage(fromperf, image );
+      
+        fromperf.close();
+        
+        dcmImageName = Ecc.str() + ".dcm";
+        MakeDicomImage(image, NX, NY, dcmImageName, patientName, 1, strStudyUID, strSerieUID, serieDescr, i, multiframe ); 
+
+     } // end : for (int i=0; i<numberOfSlices
+   }
+
+
+   if (multiframe) {
+     for (int i=0; i<numberOfSlices; i++)
+     {      
+        perf.str(rootfilename);
+        perf  << perf.str()    << "_s" << i << "_perf.txt";
+
+        std::ifstream fromperf( perf.str().c_str() );             
+        if ( !fromperf )
+        {
+           std::cout << "Can't open file [" << perf.str() << "]" << std::endl;
+           exit(0);
+        }
+        std::cout << "Open file [" << perf.str() << "] : OK" << std::endl;
+
+      if (X2)
+         LoadImageX2(fromperf, &image[NX*NY*i]);
+      else
+         LoadImage(fromperf, &image[NX*NY*i] );
+       
+      fromperf.close();  
+   } // end : for (int i=0; i<numberOfSlices
+   
+     dcmImageName = deb + "_perf.dcm";
+     MakeDicomImage(image, NX, NY, dcmImageName, patientName, numberOfSlices, strStudyUID, strSerieUID, serieDescr, numberOfSlices, multiframe ); 
+ }
+
+
+// === WashoutTc ===
+
+
+   strSerieUID =  GDCM_NAME_SPACE::Util::CreateUniqueUID();
+   
+   if (multiframe) {    
+     for (int i=0; i<numberOfSlices; i++)
+     {     
+        WashoutTc.str(rootfilename);
+        WashoutTc <<  WashoutTc.str() << "_s" << i << "_WashoutTc.txt";
+
+        std::ifstream fromWashoutTc( WashoutTc.str().c_str() );             
+        if ( !fromWashoutTc )
+        {
+           std::cout << "Can't open file [" << WashoutTc.str() << "]" << std::endl;
+           exit(0);
+        }
+        std::cout << "Open file [" << WashoutTc.str() << "] : OK" << std::endl;
+
+        if (X2)      
+          LoadImageX2(fromWashoutTc,  &image[NX*NY*i]);
+        else
+          LoadImage(fromWashoutTc, &image[NX*NY*i] );
+        fromWashoutTc.close();  
+
+     } // end : for (int i=0; i<numberOfSlices
+          
+     dcmImageName = deb + "_WashoutTc.dcm";
+     MakeDicomImage(image, NX, NY, dcmImageName, patientName, numberOfSlices, strStudyUID, strSerieUID, serieDescr, numberOfSlices, multiframe );      
+ } 
+
+
+   if (!multiframe) {
+    
+   for (int i1=0; i1<numberOfSlices; i1++)
+   {     
+      WashoutTc.str(rootfilename);
+      WashoutTc <<  WashoutTc.str() << "_s" << i1 << "_WashoutTc.txt";
+      std::ifstream fromWashoutTc( WashoutTc.str().c_str() );             
+      if ( !fromWashoutTc )
+      {
+         std::cout << "Can't open file [" << WashoutTc.str() << "]" << std::endl;
+         exit(0);
+      }
+
+      std::cout << "Open file [" << WashoutTc.str() << "] : OK" << std::endl;
+      if (X2)      
+         LoadImageX2(fromWashoutTc,image );
+       else
+         LoadImage(fromWashoutTc,image );
+      fromWashoutTc.close();
+       
+      dcmImageName = Ecc.str() + ".dcm";
+      MakeDicomImage(image, NX, NY, dcmImageName, patientName, 1, strStudyUID, strSerieUID, serieDescr, i1, multiframe ); 
+    } // end : for (int i=0; i<numberOfSlices
+
+  }
+
+   delete []image;      
+   return 1;            
+}
+
+// =====================================================================================================================
+
+void LoadImage(std::ifstream &from,  unsigned short int *image)
+{
+// in any file ".txt" :
+
+/*
+XY Dimensions           47          50
+     0.000000     0.000000     0.000000     0.000000     0.000000     0.000000
+     ...
+*/  
+
+   if (!from)
+      return;
+
+   std::string str1;
+
+    from >> str1;
+    from >> str1;
+    
+    int NX, NY;
+    from >> NX;
+    from >> NY;
+    std::cout << "NX, NY : " << NX << ", " << NY << std::endl; 
+
+    float pixelValue;
+     
+     int i, j;
+     for( i=0;i<NY;i++)
+        for(j=0;j<NX;j++) {
+           from >> pixelValue;
+           image[i*NX+j] = (unsigned short int)(pixelValue * 1000.)
+        }
+}
+
+
+// =====================================================================================================================
+
+void LoadImageX2(std::ifstream &from,  unsigned short int *image )
+{
+// in any file ".txt" :
+
+/*
+XY Dimensions           47          50
+     0.000000     0.000000     0.000000     0.000000     0.000000     0.000000
+     ...
+*/  
+
+   if (!from)
+      return;
+
+   std::string str1;
+
+    from >> str1;
+    from >> str1;
+    
+    int NX, NY;
+    from >> NX;
+    from >> NY;
+    std::cout << "NX, NY : " << NX << ", " << NY << std::endl; 
+
+    float pixelValue;
+     
+     int i, j;
+     for( i=0;i<NY;i++) {
+           for(j=0;j<NX;j++) {
+              from >> pixelValue;
+              pixelValue*=1000.;
+              image[i*4*NX + j*2] = image[i*4*NX + j*2+1] =  image[(i*4+2)*NX + j*2] =  image[(i*4+2)*NX + j*2+1] = (unsigned short int)(pixelValue);  
+   }
+        }
+
+}
+// =====================================================================================================================================
+
+
+void MakeDicomImage(unsigned short int *tabVal, int X, int Y, std::string dcmImageName, const char * patientName, int nbFrames, std::string studyUID, std::string serieUID, std::string SerieDescr, int imgNum, bool m)
+{
+
+ // GDCM_NAME_SPACE::Debug::DebugOn();
+  
+   std::ostringstream str;
+
+   GDCM_NAME_SPACE::File *file;
+   file = GDCM_NAME_SPACE::File::New();       
+      
+  // Set the image size
+   str.str(""); 
+   str << X;
+   file->InsertEntryString(str.str(),0x0028,0x0011,"US"); // Columns
+   str.str("");
+   str << Y;
+   file->InsertEntryString(str.str(),0x0028,0x0010,"US"); // Rows
+
+  // Set the pixel type
+  //      16; //8, 16, 32
+   file->InsertEntryString("16",0x0028,0x0100,"US"); // Bits Allocated
+   
+   str.str("");
+   str << 16; // may be 12 or 16 if componentSize =16
+   file->InsertEntryString("16",0x0028,0x0101,"US"); // Bits Stored
+   file->InsertEntryString("15",0x0028,0x0102,"US"); // High Bit
+
+  // Set the pixel representation // 0/1 , 0=unsigned
+   file->InsertEntryString("1",0x0028,0x0103, "US"); // Pixel Representation
+   
+  // Set the samples per pixel // 1:Grey level, 3:RGB
+   file->InsertEntryString("1",0x0028,0x0002, "US"); // Samples per Pixel
+
+
+   if (nbFrames != 1)
+   {
+      str.str("");
+      str << nbFrames;
+      file->InsertEntryString(str.str(),0x0028,0x0008,"IS"); // Number of Frames  
+   }
+  
+   if (strlen(patientName) != 0)
+      file->InsertEntryString(patientName,0x0010,0x0010, "PN"); // Patient's Name
+
+   file->InsertEntryString(studyUID, 0x0020, 0x000d, "UI");
+   file->InsertEntryString(serieUID, 0x0020, 0x000e, "UI");
+   file->InsertEntryString(SerieDescr,0x0008,0x103e, "LO");  // Series Description 
+
+// 0020 0037 DS 6 Image Orientation (Patient)   
+   file->InsertEntryString("1.0\\0.0\\0.0\\0.0\\1.0\\0.0",0x0020,0x0037, "DS"); //[1\0\0\0\1\0] : Axial   (Tant pis!)
+   
+// 0020 0032 DS 3 Image Position (Patient)   
+   char charImagePosition[256];
+   sprintf(charImagePosition,"0.0\\0.0\\%f",(float)imgNum);
+   file->InsertEntryString(charImagePosition,0x0020,0x0032, "DS");  //0020 0032 DS 3 Image Position (Patient)        
+
+// 0020 0x1041 DS 1 Slice Location 
+        sprintf(charImagePosition,"%f",float(imgNum));
+        file->InsertEntryString(charImagePosition,0x0020,0x1041, "DS");   
+/*
+  // Set Rescale Intercept
+        str.str("");
+        str << div;  
+        file->InsertEntryString(str.str(),0x0028,0x1052,"DS");
+
+  // Set Rescale Slope
+        str.str("");
+        str << mini;  
+        file->InsertEntryString(str.str(),0x0028,0x1053,"DS");
+*/
+
+   GDCM_NAME_SPACE::FileHelper *fileH;
+   fileH = GDCM_NAME_SPACE::FileHelper::New(file);
+   // cast is just to avoid warnings (*no* conversion is performed)
+   //fileH->SetImageData((uint8_t *)img,int(maxX*maxY)*sizeof(uint16_t)); // troubles when maxX, mayY are *actually* float!
+   
+   fileH->SetImageData((uint8_t *)tabVal,X*Y*nbFrames*sizeof(uint16_t));
+   fileH->SetWriteModeToRaw(); 
+   fileH->SetWriteTypeToDcmExplVR();
+        
+   if( !fileH->Write(dcmImageName))
+      std::cout << "Failed for [" << dcmImageName << "]\n"
+                << "           File is unwrittable" << std::endl;
+
+  // file->Print();
+           
+  // delete img;
+   file->Delete();
+   fileH->Delete();  
+}
+
+
+
+// =====================================================================================================================
+