X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=Example%2FDenseMultiFramesToDicom.cxx;h=18109cac808234b39b190eba5f272bdca531e48b;hb=5f2a9e86acc7c14559f0c692af86f4e92ccf8a87;hp=3e43a357f0cf3615d51023c6e53802742a7c1314;hpb=6c5535595741be007d3605d715c3a2aa5fcae721;p=gdcm.git diff --git a/Example/DenseMultiFramesToDicom.cxx b/Example/DenseMultiFramesToDicom.cxx index 3e43a357..18109cac 100755 --- a/Example/DenseMultiFramesToDicom.cxx +++ b/Example/DenseMultiFramesToDicom.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: DenseMultiFramesToDicom.cxx,v $ Language: C++ - Date: $Date: 2006/07/20 17:15:28 $ - Version: $Revision: 1.1 $ + Date: $Date: 2007/10/29 17:13:59 $ + Version: $Revision: 1.10 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -20,6 +20,10 @@ #include //#include +#if defined(__BORLANDC__) +#include +#endif + #include "gdcmFile.h" #include "gdcmFileHelper.h" #include "gdcmDebug.h" @@ -36,9 +40,8 @@ * WARNING : directory must contain ONLY .txt files */ - void Load(std::ifstream &from, std::string imageName, std::string patName, - std::string strStudyUID, int serieNumber); + std::string strStudyUID, std::string strSerieUID, int serieNumber, int verbose); //std::ifstream& eatwhite(std::ifstream& is); @@ -93,17 +96,17 @@ The terms brightness and contrast are not used in radiology imaging int main(int argc, char *argv[]) { START_USAGE(usage) - " \n DenseMultiframeToDicom :\n ", + " \n DenseMultiFramesToDicom : \n", " - explores recursively the given (single Patient, single Study) directory", " - examines the '.txt' files ", " - Converts the files into 16 bits Dicom files, ", " WARNING : directory must contain ONLY .txt files ", " usage: ", - " DenseMultiframeToDicom dirin=rootDirectoryName ", + " DenseMultiFramesToDicom dirin=rootDirectoryName ", " [studyUID = ] [patName = ] ", " [listonly] [verbose] [debug] ", " ", - "studyUID : *aware* user wants to add the serie ", + " studyUID : *aware* user wants to add the serie ", " to an already existing study ", " verbose : user wants to run the program in 'verbose mode' ", " debug : *developer* wants to run the program in 'debug mode' ", @@ -111,7 +114,7 @@ int main(int argc, char *argv[]) // ----- 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")) { @@ -124,20 +127,25 @@ int main(int argc, char *argv[]) dirNamein = am->ArgMgrGetString("dirin","."); if (am->ArgMgrDefined("debug")) - gdcm::Debug::DebugOn(); + GDCM_NAME_SPACE::Debug::DebugOn(); int verbose = am->ArgMgrDefined("verbose"); int listonly = am->ArgMgrDefined("listonly"); - std::string patName = am->ArgMgrGetString("patname", "g^PatientName"); + std::string patName = am->ArgMgrGetString("patname", dirNamein); + + bool userDefinedStudy = ( 0 != am->ArgMgrDefined("studyUID") ); - bool userDefinedStudy = am->ArgMgrDefined("studyUID"); - const char *studyUID = am->ArgMgrGetString("studyUID"); + const char *studyUID; + if (userDefinedStudy) + studyUID = am->ArgMgrGetString("studyUID"); + + // not described *on purpose* in the Usage ! + bool userDefinedSerie = ( 0 != am->ArgMgrDefined("serieUID") ); + + const char *serieUID; + if(userDefinedSerie) + serieUID = am->ArgMgrGetString("serieUID"); -// not described *on purpose* in the Usage ! - bool userDefinedSerie = am->ArgMgrDefined("serieUID"); - const char *serieUID = am->ArgMgrGetString("serieUID"); - - // if unused Param we give up if ( am->ArgMgrPrintUnusedLabels() ) { @@ -149,7 +157,7 @@ int main(int argc, char *argv[]) // ----- Begin Processing ----- - if ( ! gdcm::DirList::IsDirectory(dirNamein) ) + if ( ! GDCM_NAME_SPACE::DirList::IsDirectory(dirNamein) ) { std::cout << "KO : [" << dirNamein << "] is not a Directory." << std::endl; @@ -157,11 +165,12 @@ int main(int argc, char *argv[]) } else { - std::cout << "OK : [" << dirNamein << "] is a Directory." << std::endl; + if (verbose) + std::cout << "OK : [" << dirNamein << "] is a Directory." << std::endl; } std::string strDirNamein(dirNamein); - gdcm::DirList dirList(strDirNamein, true); // (recursively) the list of files + GDCM_NAME_SPACE::DirList dirList(strDirNamein, true); // (recursively) the list of files if (listonly) { @@ -174,16 +183,37 @@ int main(int argc, char *argv[]) std::string filenameout; std::string strStudyUID; - strStudyUID = gdcm::Util::CreateUniqueUID(); + std::string strSerieUID; + + if (userDefinedStudy) + strSerieUID = studyUID; + else + strStudyUID = GDCM_NAME_SPACE::Util::CreateUniqueUID(); + + if (userDefinedStudy) + strSerieUID = serieUID; + else + strStudyUID = GDCM_NAME_SPACE::Util::CreateUniqueUID(); + + int serieNumber =0; - gdcm::DirListType fileNames; + GDCM_NAME_SPACE::DirListType fileNames; fileNames = dirList.GetFilenames(); - for (gdcm::DirListType::iterator it = fileNames.begin(); + for (GDCM_NAME_SPACE::DirListType::iterator it = fileNames.begin(); it != fileNames.end(); ++it) - { - - + { + if ( GDCM_NAME_SPACE::Util::GetName((*it)).c_str()[0] == '.' ) + { + // skip hidden files + continue; + } + int sz = (*it).size(); + if ( (*it).c_str()[sz-1] != 't') + { + // skip non .txt files + continue; + } std::ifstream from( (*it).c_str() ); if ( !from ) { @@ -192,21 +222,26 @@ int main(int argc, char *argv[]) } else { - std::cout << "Success in open file" << *it << std::endl; - Load(from, *it, patName, strStudyUID, serieNumber); - serieNumber++; + if (verbose) + std::cout << "Success in open file" << *it << std::endl; + Load(from, *it, patName, strStudyUID, strSerieUID, serieNumber, verbose); + serieNumber+=2; //return 0; } } + return 1; } void Load(std::ifstream &from, std::string imageName, std::string patName, - std::string strStudyUID, int serieNumber) + std::string strStudyUID, std::string strSerieUID, int serieNumber, int verbose) { + if (verbose) + std::cout << " ========= Deal with file [" << imageName << "]" << std::endl; if (!from) return; - + if (verbose) + std::cout << " ========= Create Parametric images" << std::endl; /* was OK for single frames eg : --------------------------- @@ -259,66 +294,119 @@ All pixels with zero strain values are outside the masks. from >> str1; from >> str1; // 52x59x14 - std::cout << "[" << str1 << "]" << std::endl; + if(verbose) + std::cout << "[" << str1 << "]" << std::endl; sscanf( str1.c_str(),"%dx%dx%d", &nx,&ny,&nf); std::cout << nx << " " << ny << " " << nf << std::endl; - // Skip 4 lines. - for (int k=0; k<4; k++) - { + std::getline(from, str1); + + from >> str1; // Temporal + from >> str1; // Resolution + from >> str1; // = + + from >> str1; + + float temporalResolution; + sscanf( str1.c_str(),"%f",&temporalResolution); + if(verbose) + std::cout << "temporal Resolution = " << temporalResolution << std::endl; + std::getline(from, str1); + + from >> str1; // First + from >> str1; // frame + from >> str1; // starts + from >> str1; // at + + from >> str1; + float timeStart; + sscanf( str1.c_str(),"%f",&timeStart); + std::cout << "time Start = " << timeStart << std::endl; + std::getline(from, str1); + + // Skip 3 lines. + for (int k=0; k<2; k++) // + { std::getline(from, str1); std::cout << str1 << std::endl; } - //float *f = new float(nx*ny); + //float *f = new float(nx*ny); + // -->float *f = new float[nx*ny]; // Would be better ! float *f = (float *) malloc(nx*ny*nf*sizeof(float)); // float mini = FLT_MAX, maxi = FLT_MIN; float val; - - - std::string strSerieUID; - strSerieUID = gdcm::Util::CreateUniqueUID(); - - for (int l=0; l> str1; + } //end eatwhite(from); + + // trouble : when space is missing "-0.0990263-8.8778" + // is not interpreted as TWO values :-( + // from >> str1; + + int first = 1; + char previous = 'z'; + for(;;) + { + from.get(c); + if ( c == ' ') + break; + if ( first != 1 && c == '-' && previous != 'e') + { + from.putback(c); + //std::cout << " One more gauffre in frame:" << std::dec << l + // << ", line : " << j << " element " << i << std::endl; + break; + } + + first=0; + previous = c; + str1=str1+c; + } + val = (float)atof(str1.c_str()); - // std::cout << " " << val; + //std::cout << " " << val; *(f+ /*l*nx*ny + */j*nx+i) = val; if(from.eof()) { - std::cout << "Missing values at [" << j <<"," << i << "]" + std::cout << "Missing values at [" << std::dec << j <<"," << i << "]" << std::endl; break; } - l++; } - std::cout << std::endl; + //std::cout << std::endl; //std::cout << std::endl << " line nb : " << j // << " line length : " << l << std::endl; - } - // std::cout << "mini : "<< mini << " maxi : " << maxi << std::endl; /* @@ -336,26 +424,26 @@ All pixels with zero strain values are outside the masks. ptr++; } */ - uint16_t *img = new uint16_t[ny*nx]; - uint16_t *ptr = img; + int16_t *img = new int16_t[ny*nx]; + int16_t *ptr = img; float *tmp = f /* + l*ny*nx */ ; // start on image nb l. for( int k=0; k 1.0) // artefacted pixel *ptr = 0; else /// \todo FIXME : what about max threshold ? *ptr = (int16_t)(*tmp *100); - //std::cout << std::dec << "[" << *tmp <<" : " << *ptr << "] "; + // std::cout << std::dec << "[" << *tmp <<" : " << *ptr << "] "; tmp ++; ptr++; } - // gdcm::Debug::DebugOn(); + // GDCM_NAME_SPACE::Debug::DebugOn(); std::ostringstream str; - gdcm::File *file; - file = gdcm::File::New(); + GDCM_NAME_SPACE::File *file; + file = GDCM_NAME_SPACE::File::New(); // Set the image size str.str(""); @@ -375,7 +463,7 @@ All pixels with zero strain values are outside the masks. file->InsertEntryString("15",0x0028,0x0102,"US"); // High Bit // Set the pixel representation // 0/1 1 : signed - file->InsertEntryString("0",0x0028,0x0103, "US"); // Pixel Representation + 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 @@ -397,10 +485,10 @@ All pixels with zero strain values are outside the masks. // 0020 0032 DS 3 Image Position (Patient) char charImagePosition[256]; - sprintf(charImagePosition,"0.0\\0.0\\%f",float(l%nf)); + sprintf(charImagePosition,"0.0\\0.0\\%f",float(l1%nf)); // 0020 0x1041 DS 1 Slice Location - sprintf(charImagePosition,"%f",float(l%nf)); + sprintf(charImagePosition,"%f",float(l1%nf)); file->InsertEntryString(charImagePosition,0x0020,0x1041, "DS"); //0008 103e LO 1 Series Description @@ -413,11 +501,19 @@ All pixels with zero strain values are outside the masks. //0020 0011 "IS" Series Number sprintf(charImagePosition,"%04d",serieNumber); file->InsertEntryString(charImagePosition,0x0020,0x0011, "IS"); - + +//0020 0011 "IS" Instance Number + sprintf(charImagePosition,"%04d",imageNumber); + file->InsertEntryString(charImagePosition,0x0020,0x0013, "IS"); + +//0018 1060 "DS" Time Trigger + sprintf(charImagePosition,"%f",currentTime); + file->InsertEntryString(charImagePosition,0x0018,0x1060, "DS"); + // file->Print(); - gdcm::FileHelper *fh; - fh = gdcm::FileHelper::New(file); + GDCM_NAME_SPACE::FileHelper *fh; + fh = GDCM_NAME_SPACE::FileHelper::New(file); // cast is just to avoid warnings (*no* conversion) fh->SetImageData((uint8_t *)img,nx*ny*sizeof(uint16_t)); fh->SetWriteModeToRaw(); @@ -425,18 +521,167 @@ All pixels with zero strain values are outside the masks. fh->SetWriteTypeToDcmExplVR(); - char numero[10]; - sprintf(numero, "%02d", l); + sprintf(numero, "%02d", l1); std::string fileName = imageName + "." + numero + ".dcm"; - std::cout << "fileName " << fileName << std::endl; + if(verbose) + std::cout << "fileName " << fileName << std::endl; if( !fh->Write(fileName)) std::cout << "Failed for [" << fileName << "]\n" << " File is unwrittable" << std::endl; - delete img; + delete img; + currentTime += temporalResolution; + imageNumber ++; + } // end loop on frames + + // Anatomical Images. + std::cout << " ========= Create Anatomical images" << std::endl; + + strSerieUID = GDCM_NAME_SPACE::Util::CreateUniqueUID(); + imageNumber = 0; + currentTime = timeStart; + + for (int fr=0; fr> str1; + val = (float)atof(str1.c_str()); + // std::cout << " " << val; + *(f+ /*l*nx*ny + */j*nx+i) = val; + + if(from.eof()) + { + std::cout << "Missing values at [" << std::dec << j <<"," << i << "]" + << std::endl; + break; + } + l++; + } + } + + uint16_t *img = new uint16_t[ny*nx]; + uint16_t *ptr = img; + float *tmp = f /* + l*ny*nx */ ; // start on image nb l. + for( int k=0; kInsertEntryString(str.str(),0x0028,0x0011,"US"); // Columns + str.str(""); + str << ny; + 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 1 : signed + file->InsertEntryString("0",0x0028,0x0103, "US"); // Pixel Representation + + // Set the samples per pixel // 1:Grey level, 3:RGB + file->InsertEntryString("1",0x0028,0x0002, "US"); // Samples per Pixel + +/* + // 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"); +*/ + +// 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 + +// 0020 0032 DS 3 Image Position (Patient) + char charImagePosition[256]; + sprintf(charImagePosition,"0.0\\0.0\\%f",float(l1%nf)); + +// 0020 0x1041 DS 1 Slice Location + sprintf(charImagePosition,"%f",float(l1%nf)); + file->InsertEntryString(charImagePosition,0x0020,0x1041, "DS"); + +//0008 103e LO 1 Series Description + file->InsertEntryString(imageName,0x0008,0x103e, "LO"); + + file->InsertEntryString(strStudyUID,0x0020,0x000d,"UI"); + file->InsertEntryString(strSerieUID,0x0020,0x000e,"UI"); + file->InsertEntryString(patName,0x0010,0x0010, "PN"); // Patient's Name + +//0020 0011 "IS" Series Number + sprintf(charImagePosition,"%04d",serieNumber+1); + file->InsertEntryString(charImagePosition,0x0020,0x0011, "IS"); + +//0020 0011 "IS" Instance Number + sprintf(charImagePosition,"%04d",imageNumber); + file->InsertEntryString(charImagePosition,0x0020,0x0013, "IS"); + +//0018 1060 "DS" Time Trigger + sprintf(charImagePosition,"%f",currentTime); + file->InsertEntryString(charImagePosition,0x0018,0x1060, "DS"); + // file->Print(); + + GDCM_NAME_SPACE::FileHelper *fh; + fh = GDCM_NAME_SPACE::FileHelper::New(file); + // cast is just to avoid warnings (*no* conversion) + fh->SetImageData((uint8_t *)img,nx*ny*sizeof(uint16_t)); + fh->SetWriteModeToRaw(); + fh->SetWriteTypeToDcmExplVR(); + + fh->SetWriteTypeToDcmExplVR(); + + char numero[10]; + sprintf(numero, "%02d", l1); + std::string fileName = imageName + ".Anatomical." + numero + ".dcm"; + std::cout << "fileName " << fileName << std::endl; + + if( !fh->Write(fileName)) + std::cout << "Failed for [" << fileName << "]\n" + << " File is unwrittable" << std::endl; + + delete img; + currentTime += temporalResolution; + imageNumber ++; + + } // end loop on frames + from.close(); -} +} // end void Load(