1 /*=========================================================================
4 Module: $RCSfile: PcpdenseToDicom.cxx,v $
6 Date: $Date: 2010/08/26 12:46:12 $
7 Version: $Revision: 1.5 $
9 Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
10 l'Image). All rights reserved. See Doc/License.txt or
11 http://www.creatis.insa-lyon.fr/Public/Gdcm/License.html for details.
13 This software is distributed WITHOUT ANY WARRANTY; without even
14 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 PURPOSE. See the above copyright notices for more information.
17 =========================================================================*/
23 #if defined(__BORLANDC__)
28 #include "gdcmFileHelper.h"
29 #include "gdcmDebug.h"
30 #include "gdcmDirList.h"
32 #include "gdcmArgMgr.h"
36 * Converts the "pcpdense" ".txt" (2008 version) files into 16 bits Dicom Files,
37 * Hope they don't change soon!
40 void MakeDicomImage(unsigned short int *tabVal, int X, int Y, std::string dcmImageName, const char * patientName, int nbFrames,
41 std::string studyUID, std::string serieUID, std::string SerieDescr, int imgNum, bool m );
43 void LoadImage(std::ifstream &from, unsigned short int * );
45 void LoadImageX2(std::ifstream &from, unsigned short int * );
48 int main(int argc, char *argv[])
51 " \n pcpdenseToDicom :\n ",
52 " Converts the '.txt' files into 16 bits Dicom Files, ",
54 " pcpdenseToDicom rootfilename=... ",
55 " (e.g.. : meas_MID380_DENSE_stacked_slices_aif_FID81637)",
56 " numberOfSlices = (default : 3) ",
57 " X2 : multiply x 2 image size ",
58 " m :create multiframe files instead of image stacks ",
59 " [patientname = Patient's name] ",
60 " [verbose] [debug] ",
62 " verbose : user wants to run the program in 'verbose mode' ",
63 " debug : *developer* wants to run the program in 'debug mode' ",
66 // ----- Initialize Arguments Manager ------
68 GDCM_NAME_SPACE::ArgMgr *am = new GDCM_NAME_SPACE::ArgMgr(argc, argv);
70 if (argc == 1 || am->ArgMgrDefined("usage"))
72 am->ArgMgrUsage(usage); // Display 'usage'
76 // Seems that ArgMgrWantString doesn't work on MacOS
77 if(!am->ArgMgrDefined("rootfilename"))
79 std::cout << "'rootfilename' is mandatory" << std::endl;
83 const char *rootfilename = am->ArgMgrWantString("rootfilename",usage);
84 int numberOfSlices = am->ArgMgrGetInt("numberOfSlices",3);
85 const char *patientName = am->ArgMgrGetString("patientname", "Patient^Name");
87 if (am->ArgMgrDefined("debug"))
88 GDCM_NAME_SPACE::Debug::DebugOn();
90 verbose = ( 0 != am->ArgMgrDefined("verbose") );
91 bool X2 = ( 0 != am->ArgMgrDefined("X2") );
92 bool multiframe = ( 0 != am->ArgMgrDefined("m") );
94 // if unused Param we give up
95 if ( am->ArgMgrPrintUnusedLabels() )
97 am->ArgMgrUsage(usage);
101 delete am; // we don't need Argument Manager any longer
103 // ----- Begin Processing -----
105 std::ostringstream Ecc;
106 std::ostringstream perf;
107 std::ostringstream WashoutTc;
109 std::string strSerieUID;
110 std::string strStudyUID = GDCM_NAME_SPACE::Util::CreateUniqueUID();
111 std::string dcmImageName, textFileName, patientname,/* studyUID, serieUID, */ serieDescr ;
112 std::string deb(rootfilename);
114 unsigned short int *image;
122 Ecc.str(rootfilename);
123 Ecc << Ecc.str() << "_s0" << "_Ecc.txt";
125 std::ifstream fromEcc( Ecc.str().c_str() );
128 std::cout << "Can't open file [" << Ecc.str() << "]" << std::endl;
138 std::cout << "NX, NY : " << NX << ", " << NY << std::endl;
148 image = new unsigned short int[NX*NY*mult*numberOfSlices];
150 image = new unsigned short int[NX*NY*mult];
156 strSerieUID = GDCM_NAME_SPACE::Util::CreateUniqueUID();
162 for (int i=0; i<numberOfSlices; i++)
164 Ecc.str(rootfilename);
165 Ecc << Ecc.str() << "_s" << i << "_Ecc.txt";
167 std::ifstream fromEcc( Ecc.str().c_str() );
170 std::cout << "Can't open file [" << Ecc.str() << "]" << std::endl;
173 std::cout << "Open file [" << Ecc.str() << "] : OK" << std::endl;
176 LoadImageX2(fromEcc, image);
178 LoadImage(fromEcc, image);
181 dcmImageName = Ecc.str() + ".dcm";
183 MakeDicomImage(image, NX, NY, dcmImageName, patientName, 1, strStudyUID, strSerieUID, serieDescr, i, multiframe );
184 } // end : for (int i=0; i<numberOfSlices
191 for (int i=0; i<numberOfSlices; i++)
193 Ecc.str(rootfilename);
194 Ecc << Ecc.str() << "_s" << i << "_Ecc.txt";
196 std::ifstream fromEcc( Ecc.str().c_str() );
199 std::cout << "Can't open file [" << Ecc.str() << "]" << std::endl;
203 std::cout << "Open file [" << Ecc.str() << "] : OK" << std::endl;
205 LoadImageX2(fromEcc ,&image[NX*NY*i] );
207 LoadImage(fromEcc, &image[NX*NY*i] );
210 } // end : for (int i=0; i<numberOfSlices
212 dcmImageName = deb + "_Ecc.dcm";
213 MakeDicomImage(image, NX, NY, dcmImageName, patientName, numberOfSlices, strStudyUID, strSerieUID, serieDescr, 0, multiframe );
215 } // end : if (multiframe)
221 strSerieUID = GDCM_NAME_SPACE::Util::CreateUniqueUID();
226 for (int i=0; i<numberOfSlices; i++)
228 perf.str(rootfilename);
229 perf << perf.str() << "_s" << i << "_perf.txt";
231 std::ifstream fromperf( perf.str().c_str() );
234 std::cout << "Can't open file [" << perf.str() << "]" << std::endl;
237 std::cout << "Open file [" << perf.str() << "] : OK" << std::endl;
240 LoadImageX2(fromperf ,image );
242 LoadImage(fromperf, image );
246 dcmImageName = Ecc.str() + ".dcm";
247 MakeDicomImage(image, NX, NY, dcmImageName, patientName, 1, strStudyUID, strSerieUID, serieDescr, i, multiframe );
249 } // end : for (int i=0; i<numberOfSlices
254 for (int i=0; i<numberOfSlices; i++)
256 perf.str(rootfilename);
257 perf << perf.str() << "_s" << i << "_perf.txt";
259 std::ifstream fromperf( perf.str().c_str() );
262 std::cout << "Can't open file [" << perf.str() << "]" << std::endl;
265 std::cout << "Open file [" << perf.str() << "] : OK" << std::endl;
268 LoadImageX2(fromperf, &image[NX*NY*i]);
270 LoadImage(fromperf, &image[NX*NY*i] );
273 } // end : for (int i=0; i<numberOfSlices
275 dcmImageName = deb + "_perf.dcm";
276 MakeDicomImage(image, NX, NY, dcmImageName, patientName, numberOfSlices, strStudyUID, strSerieUID, serieDescr, numberOfSlices, multiframe );
284 strSerieUID = GDCM_NAME_SPACE::Util::CreateUniqueUID();
286 serieDescr = "WashoutTc";
289 for (int i=0; i<numberOfSlices; i++)
291 WashoutTc.str(rootfilename);
292 WashoutTc << WashoutTc.str() << "_s" << i << "_WashoutTc.txt";
294 std::ifstream fromWashoutTc( WashoutTc.str().c_str() );
295 if ( !fromWashoutTc )
297 std::cout << "Can't open file [" << WashoutTc.str() << "]" << std::endl;
300 std::cout << "Open file [" << WashoutTc.str() << "] : OK" << std::endl;
303 LoadImageX2(fromWashoutTc, &image[NX*NY*i]);
305 LoadImage(fromWashoutTc, &image[NX*NY*i] );
306 fromWashoutTc.close();
308 } // end : for (int i=0; i<numberOfSlices
310 dcmImageName = deb + "_WashoutTc.dcm";
311 MakeDicomImage(image, NX, NY, dcmImageName, patientName, numberOfSlices, strStudyUID, strSerieUID, serieDescr, numberOfSlices, multiframe );
317 for (int i1=0; i1<numberOfSlices; i1++)
319 WashoutTc.str(rootfilename);
320 WashoutTc << WashoutTc.str() << "_s" << i1 << "_WashoutTc.txt";
322 std::ifstream fromWashoutTc( WashoutTc.str().c_str() );
323 if ( !fromWashoutTc )
325 std::cout << "Can't open file [" << WashoutTc.str() << "]" << std::endl;
329 std::cout << "Open file [" << WashoutTc.str() << "] : OK" << std::endl;
331 LoadImageX2(fromWashoutTc,image );
333 LoadImage(fromWashoutTc,image );
334 fromWashoutTc.close();
336 dcmImageName = Ecc.str() + ".dcm";
337 MakeDicomImage(image, NX, NY, dcmImageName, patientName, 1, strStudyUID, strSerieUID, serieDescr, i1, multiframe );
338 } // end : for (int i=0; i<numberOfSlices
346 // =====================================================================================================================
348 void LoadImage(std::ifstream &from, unsigned short int *image)
350 // in any file ".txt" :
354 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
369 std::cout << "NX, NY : " << NX << ", " << NY << std::endl;
377 image[i*NX+j] = (unsigned short int)(pixelValue * 1000.); // Why do we multiply by 1000? // JPR
382 // =====================================================================================================================
384 void LoadImageX2(std::ifstream &from, unsigned short int *image )
386 // in any file ".txt" :
390 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
405 std::cout << "NX, NY : " << NX << ", " << NY << std::endl;
413 pixelValue*=1000.; // Why do we multiply by 1000? // JPR
414 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);
419 // =====================================================================================================================================
422 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)
425 // GDCM_NAME_SPACE::Debug::DebugOn();
427 std::ostringstream str;
429 GDCM_NAME_SPACE::File *file;
430 file = GDCM_NAME_SPACE::File::New();
432 // Set the image size
435 file->InsertEntryString(str.str(),0x0028,0x0011,"US"); // Columns
438 file->InsertEntryString(str.str(),0x0028,0x0010,"US"); // Rows
440 // Set the pixel type
442 file->InsertEntryString("16",0x0028,0x0100,"US"); // Bits Allocated
445 str << 16; // may be 12 or 16 if componentSize =16
446 file->InsertEntryString("16",0x0028,0x0101,"US"); // Bits Stored
447 file->InsertEntryString("15",0x0028,0x0102,"US"); // High Bit
449 // Set the pixel representation // 0/1 , 0=unsigned
450 file->InsertEntryString("1",0x0028,0x0103, "US"); // Pixel Representation
452 // Set the samples per pixel // 1:Grey level, 3:RGB
453 file->InsertEntryString("1",0x0028,0x0002, "US"); // Samples per Pixel
460 file->InsertEntryString(str.str(),0x0028,0x0008,"IS"); // Number of Frames
463 if (strlen(patientName) != 0)
464 file->InsertEntryString(patientName,0x0010,0x0010, "PN"); // Patient's Name
466 file->InsertEntryString(studyUID, 0x0020, 0x000d, "UI");
467 file->InsertEntryString(serieUID, 0x0020, 0x000e, "UI");
469 file->InsertEntryString(SerieDescr,0x0008,0x103e, "LO"); // Series Description
471 // 0020 0037 DS 6 Image Orientation (Patient)
472 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!)
474 // 0020 0032 DS 3 Image Position (Patient)
475 char charImagePosition[256];
476 sprintf(charImagePosition,"0.0\\0.0\\%f",(float)imgNum);
477 file->InsertEntryString(charImagePosition,0x0020,0x0032, "DS"); //0020 0032 DS 3 Image Position (Patient)
479 // 0020 0x1041 DS 1 Slice Location
480 sprintf(charImagePosition,"%f",float(imgNum));
481 file->InsertEntryString(charImagePosition,0x0020,0x1041, "DS");
483 // Set Rescale Intercept
486 file->InsertEntryString(str.str(),0x0028,0x1052,"DS");
491 file->InsertEntryString(str.str(),0x0028,0x1053,"DS");
494 GDCM_NAME_SPACE::FileHelper *fileH;
495 fileH = GDCM_NAME_SPACE::FileHelper::New(file);
496 // cast is just to avoid warnings (*no* conversion is performed)
497 //fileH->SetImageData((uint8_t *)img,int(maxX*maxY)*sizeof(uint16_t)); // troubles when maxX, mayY are *actually* float!
499 fileH->SetImageData((uint8_t *)tabVal,X*Y*nbFrames*sizeof(uint16_t));
500 fileH->SetWriteModeToRaw();
501 fileH->SetWriteTypeToDcmExplVR();
503 if( !fileH->Write(dcmImageName))
504 std::cout << "Failed for [" << dcmImageName << "]\n"
505 << " File is unwrittable" << std::endl;
516 // =====================================================================================================================