From 083e0fff724f0a36b6850fa335f80829c0f1c770 Mon Sep 17 00:00:00 2001 From: jpr Date: Thu, 4 Sep 2008 14:10:44 +0000 Subject: [PATCH] Transform 'pcpdense' format files into Dicomfile (single or multiframes, depending on users's choice) --- Example/PcpdenseToDicom.cxx | 511 ++++++++++++++++++++++++++++++++++++ 1 file changed, 511 insertions(+) create mode 100644 Example/PcpdenseToDicom.cxx diff --git a/Example/PcpdenseToDicom.cxx b/Example/PcpdenseToDicom.cxx new file mode 100644 index 00000000..359ad62e --- /dev/null +++ b/Example/PcpdenseToDicom.cxx @@ -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 +#include +//#include + +#if defined(__BORLANDC__) +#include +#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> 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> 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> 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(); +} + + + +// ===================================================================================================================== + -- 2.45.0