00001
00002
00003 #include "gdcmHeaderHelper.h"
00004 #include "gdcmDirList.h"
00005
00006 #include "gdcmUtil.h"
00007 #include <math.h>
00008 #include <algorithm>
00009
00010
00011
00012
00013
00018 gdcmHeaderHelper::gdcmHeaderHelper() : gdcmHeader( ) {
00019
00020 }
00021
00033 gdcmHeaderHelper::gdcmHeaderHelper(const char *InFilename,
00034 bool exception_on_error,
00035 bool enable_sequences,
00036 bool ignore_shadow)
00037 : gdcmHeader( InFilename,
00038 exception_on_error,
00039 enable_sequences,
00040 ignore_shadow)
00041 {
00042 }
00043
00044
00045
00046
00047
00048
00055 int gdcmHeaderHelper::GetPixelSize() {
00056
00057
00058
00059 if (gdcmHeader::GetEntryByNumber(0x0028,0x0100) == "24")
00060 return 3;
00061
00062 std::string PixelType = GetPixelType();
00063 if (PixelType == "8U" || PixelType == "8S")
00064 return 1;
00065 if (PixelType == "16U" || PixelType == "16S")
00066 return 2;
00067 if (PixelType == "32U" || PixelType == "32S")
00068 return 4;
00069 if (PixelType == "FD")
00070 return 8;
00071 dbg.Verbose(0, "gdcmHeader::GetPixelSize: Unknown pixel type");
00072 return 0;
00073 }
00074
00093 std::string gdcmHeaderHelper::GetPixelType() {
00094 std::string BitsAlloc;
00095 BitsAlloc = GetEntryByNumber(0x0028, 0x0100);
00096 if (BitsAlloc == GDCM_UNFOUND) {
00097 dbg.Verbose(0, "gdcmHeader::GetPixelType: unfound Bits Allocated");
00098 BitsAlloc = std::string("16");
00099 }
00100 if (BitsAlloc == "12")
00101 BitsAlloc = std::string("16");
00102 else if (BitsAlloc == "24")
00103 BitsAlloc = std::string("8");
00104
00105 std::string Signed;
00106 Signed = GetEntryByNumber(0x0028, 0x0103);
00107 if (Signed == GDCM_UNFOUND) {
00108 dbg.Verbose(0, "gdcmHeader::GetPixelType: unfound Pixel Representation");
00109 BitsAlloc = std::string("0");
00110 }
00111 if (BitsAlloc == "64")
00112 return("FD");
00113
00114 if (Signed == "0")
00115 Signed = std::string("U");
00116 else
00117 Signed = std::string("S");
00118
00119 return( BitsAlloc + Signed);
00120 }
00121
00128 float gdcmHeaderHelper::GetXSpacing() {
00129 float xspacing, yspacing;
00130 std::string StrSpacing = GetEntryByNumber(0x0028,0x0030);
00131
00132 if (StrSpacing == GDCM_UNFOUND) {
00133 dbg.Verbose(0, "gdcmHeader::GetXSpacing: unfound Pixel Spacing (0028,0030)");
00134 return 1.;
00135 }
00136 if( sscanf( StrSpacing.c_str(), "%f\\%f", &yspacing, &xspacing) != 2)
00137 return 0.;
00138 if (xspacing == 0.) {
00139 dbg.Verbose(0, "gdcmHeader::GetYSpacing: gdcmData/CT-MONO2-8-abdo.dcm problem");
00140
00141 sscanf( StrSpacing.c_str(), "%f\\0\\%f", &yspacing, &xspacing);
00142 }
00143 return xspacing;
00144 }
00145
00152 float gdcmHeaderHelper::GetYSpacing() {
00153 float xspacing, yspacing;
00154 std::string StrSpacing = GetEntryByNumber(0x0028,0x0030);
00155
00156 if (StrSpacing == GDCM_UNFOUND) {
00157 dbg.Verbose(0, "gdcmHeader::GetYSpacing: unfound Pixel Spacing (0028,0030)");
00158 return 1.;
00159 }
00160 if( sscanf( StrSpacing.c_str(), "%f\\%f", &yspacing, &xspacing) != 2)
00161 return 0.;
00162 if (xspacing == 0.) {
00163 dbg.Verbose(0, "gdcmHeader::GetYSpacing: gdcmData/CT-MONO2-8-abdo.dcm problem");
00164
00165 sscanf( StrSpacing.c_str(), "%f\\0\\%f", &yspacing, &xspacing);
00166 }
00167 return yspacing;
00168 }
00169
00177 float gdcmHeaderHelper::GetZSpacing() {
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188 std::string StrSpacingBSlices = GetEntryByNumber(0x0018,0x0088);
00189
00190 if (StrSpacingBSlices == GDCM_UNFOUND) {
00191 dbg.Verbose(0, "gdcmHeader::GetZSpacing: unfound StrSpacingBSlices");
00192 std::string StrSliceThickness = GetEntryByNumber(0x0018,0x0050);
00193 if (StrSliceThickness == GDCM_UNFOUND)
00194 return 1.;
00195 else
00196
00197
00198
00199
00200 return atof(StrSliceThickness.c_str());
00201 } else {
00202 return atof(StrSpacingBSlices.c_str());
00203 }
00204 }
00205
00211 float gdcmHeaderHelper::GetRescaleIntercept() {
00212 float resInter = 0.;
00213 std::string StrRescInter = GetEntryByNumber(0x0028,0x1052);
00214 if (StrRescInter != GDCM_UNFOUND) {
00215 if( sscanf( StrRescInter.c_str(), "%f", &resInter) != 1) {
00216 dbg.Verbose(0, "gdcmHeader::GetRescaleIntercept: Rescale Slope is empty");
00217
00218 }
00219 }
00220 return resInter;
00221 }
00222
00228 float gdcmHeaderHelper::GetRescaleSlope() {
00229 float resSlope = 1.;
00230 std::string StrRescSlope = GetEntryByNumber(0x0028,0x1053);
00231 if (StrRescSlope != GDCM_UNFOUND) {
00232 if( sscanf( StrRescSlope.c_str(), "%f", &resSlope) != 1) {
00233 dbg.Verbose(0, "gdcmHeader::GetRescaleSlope: Rescale Slope is empty");
00234
00235 }
00236 }
00237 return resSlope;
00238 }
00239
00248 int gdcmHeaderHelper::GetNumberOfScalarComponents() {
00249 if (GetSamplesPerPixel() ==3)
00250 return 3;
00251
00252
00253
00254 if (gdcmHeader::GetEntryByNumber(0x0028,0x0100) == "24")
00255 return 3;
00256
00257 std::string PhotometricInterpretation =
00258 gdcmHeader::GetEntryByNumber(0x0028,0x0004);
00259
00260 if ( ( PhotometricInterpretation == "PALETTE COLOR ") ) {
00261 if (HasLUT())
00262 return 3;
00263 else
00264 return 1;
00265 }
00266
00267
00268 if (PhotometricInterpretation.find(GDCM_UNFOUND) <
00269 PhotometricInterpretation.length() ||
00270 PhotometricInterpretation.find("MONOCHROME1") <
00271 PhotometricInterpretation.length() ||
00272 PhotometricInterpretation.find("MONOCHROME2") <
00273 PhotometricInterpretation.length() )
00274 return 1;
00275 else
00276
00277 return 3;
00278 }
00279
00288 int gdcmHeaderHelper::GetNumberOfScalarComponentsRaw() {
00289
00290
00291
00292 if (gdcmHeader::GetEntryByNumber(0x0028,0x0100) == "24")
00293 return 3;
00294
00295
00296 return GetSamplesPerPixel();
00297 }
00298
00305 std::string gdcmHeaderHelper::GetStudyUID(){
00306 return GetEntryByNumber(0x0020,0x000d);
00307 }
00308
00315 std::string gdcmHeaderHelper::GetSeriesUID(){
00316 return GetEntryByNumber(0x0020,0x000e);
00317 }
00318
00325 std::string gdcmHeaderHelper::GetClassUID(){
00326 return GetEntryByNumber(0x0008,0x0016);
00327 }
00328
00335 std::string gdcmHeaderHelper::GetInstanceUID(){
00336 return GetEntryByNumber(0x0008,0x0018);
00337 }
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00362 float gdcmHeaderHelper::GetXOrigin() {
00363 float xImPos, yImPos, zImPos;
00364 std::string StrImPos = GetEntryByNumber(0x0020,0x0032);
00365
00366 if (StrImPos == GDCM_UNFOUND) {
00367 dbg.Verbose(0, "gdcmHeader::GetXImagePosition: unfound Image Position Patient (0020,0032)");
00368 StrImPos = GetEntryByNumber(0x0020,0x0030);
00369 if (StrImPos == GDCM_UNFOUND) {
00370 dbg.Verbose(0, "gdcmHeader::GetXImagePosition: unfound Image Position (RET) (0020,0030)");
00371
00372 return 0.;
00373 }
00374 }
00375 if( sscanf( StrImPos.c_str(), "%f\\%f\\%f", &xImPos, &yImPos, &zImPos) != 3)
00376 return 0.;
00377 return xImPos;
00378 }
00379
00387 float gdcmHeaderHelper::GetYOrigin() {
00388 float xImPos, yImPos, zImPos;
00389 std::string StrImPos = GetEntryByNumber(0x0020,0x0032);
00390
00391 if (StrImPos == GDCM_UNFOUND) {
00392 dbg.Verbose(0, "gdcmHeader::GetYImagePosition: unfound Image Position Patient (0020,0032)");
00393 StrImPos = GetEntryByNumber(0x0020,0x0030);
00394 if (StrImPos == GDCM_UNFOUND) {
00395 dbg.Verbose(0, "gdcmHeader::GetYImagePosition: unfound Image Position (RET) (0020,0030)");
00396
00397 return 0.;
00398 }
00399 }
00400 if( sscanf( StrImPos.c_str(), "%f\\%f\\%f", &xImPos, &yImPos, &zImPos) != 3)
00401 return 0.;
00402 return yImPos;
00403 }
00404
00414 float gdcmHeaderHelper::GetZOrigin() {
00415 float xImPos, yImPos, zImPos;
00416 std::string StrImPos = GetEntryByNumber(0x0020,0x0032);
00417 if (StrImPos != GDCM_UNFOUND) {
00418 if( sscanf( StrImPos.c_str(), "%f\\%f\\%f", &xImPos, &yImPos, &zImPos) != 3) {
00419 dbg.Verbose(0, "gdcmHeader::GetZImagePosition: wrong Image Position Patient (0020,0032)");
00420 return 0.;
00421 } else {
00422 return zImPos;
00423 }
00424 }
00425 StrImPos = GetEntryByNumber(0x0020,0x0030);
00426 if (StrImPos != GDCM_UNFOUND) {
00427 if( sscanf( StrImPos.c_str(), "%f\\%f\\%f", &xImPos, &yImPos, &zImPos) != 3) {
00428 dbg.Verbose(0, "gdcmHeader::GetZImagePosition: wrong Image Position (RET) (0020,0030)");
00429 return 0.;
00430 } else {
00431 return zImPos;
00432 }
00433 }
00434 std::string StrSliceLocation = GetEntryByNumber(0x0020,0x1041);
00435 if (StrSliceLocation != GDCM_UNFOUND) {
00436 if( sscanf( StrSliceLocation.c_str(), "%f", &zImPos) !=1) {
00437 dbg.Verbose(0, "gdcmHeader::GetZImagePosition: wrong Slice Location (0020,1041)");
00438 return 0.;
00439 } else {
00440 return zImPos;
00441 }
00442 }
00443 dbg.Verbose(0, "gdcmHeader::GetZImagePosition: unfound Slice Location (0020,1041)");
00444 std::string StrLocation = GetEntryByNumber(0x0020,0x0050);
00445 if (StrLocation != GDCM_UNFOUND) {
00446 if( sscanf( StrLocation.c_str(), "%f", &zImPos) !=1) {
00447 dbg.Verbose(0, "gdcmHeader::GetZImagePosition: wrong Location (0020,0050)");
00448 return 0.;
00449 } else {
00450 return zImPos;
00451 }
00452 }
00453 dbg.Verbose(0, "gdcmHeader::GetYImagePosition: unfound Location (0020,0050)");
00454 return 0.;
00455 }
00456
00463 int gdcmHeaderHelper::GetImageNumber() {
00464
00465
00466
00467
00468
00469 std::string StrImNumber = GetEntryByNumber(0x0020,0x0013);
00470 if (StrImNumber != GDCM_UNFOUND) {
00471 return atoi( StrImNumber.c_str() );
00472 }
00473 return 0;
00474 }
00475
00481 ModalityType gdcmHeaderHelper::GetModality(void) {
00482 std::string StrModality = GetEntryByNumber(0x0008,0x0060);
00483 if (StrModality != GDCM_UNFOUND) {
00484 if ( StrModality.find("AU") < StrModality.length()) return AU;
00485 else if ( StrModality.find("AS") < StrModality.length()) return AS;
00486 else if ( StrModality.find("BI") < StrModality.length()) return BI;
00487 else if ( StrModality.find("CF") < StrModality.length()) return CF;
00488 else if ( StrModality.find("CP") < StrModality.length()) return CP;
00489 else if ( StrModality.find("CR") < StrModality.length()) return CR;
00490 else if ( StrModality.find("CT") < StrModality.length()) return CT;
00491 else if ( StrModality.find("CS") < StrModality.length()) return CS;
00492 else if ( StrModality.find("DD") < StrModality.length()) return DD;
00493 else if ( StrModality.find("DF") < StrModality.length()) return DF;
00494 else if ( StrModality.find("DG") < StrModality.length()) return DG;
00495 else if ( StrModality.find("DM") < StrModality.length()) return DM;
00496 else if ( StrModality.find("DS") < StrModality.length()) return DS;
00497 else if ( StrModality.find("DX") < StrModality.length()) return DX;
00498 else if ( StrModality.find("ECG") < StrModality.length()) return ECG;
00499 else if ( StrModality.find("EPS") < StrModality.length()) return EPS;
00500 else if ( StrModality.find("FA") < StrModality.length()) return FA;
00501 else if ( StrModality.find("FS") < StrModality.length()) return FS;
00502 else if ( StrModality.find("HC") < StrModality.length()) return HC;
00503 else if ( StrModality.find("HD") < StrModality.length()) return HD;
00504 else if ( StrModality.find("LP") < StrModality.length()) return LP;
00505 else if ( StrModality.find("LS") < StrModality.length()) return LS;
00506 else if ( StrModality.find("MA") < StrModality.length()) return MA;
00507 else if ( StrModality.find("MR") < StrModality.length()) return MR;
00508 else if ( StrModality.find("NM") < StrModality.length()) return NM;
00509 else if ( StrModality.find("OT") < StrModality.length()) return OT;
00510 else if ( StrModality.find("PT") < StrModality.length()) return PT;
00511 else if ( StrModality.find("RF") < StrModality.length()) return RF;
00512 else if ( StrModality.find("RG") < StrModality.length()) return RG;
00513 else if ( StrModality.find("RTDOSE") < StrModality.length()) return RTDOSE;
00514 else if ( StrModality.find("RTIMAGE") < StrModality.length()) return RTIMAGE;
00515 else if ( StrModality.find("RTPLAN") < StrModality.length()) return RTPLAN;
00516 else if ( StrModality.find("RTSTRUCT")< StrModality.length()) return RTSTRUCT;
00517 else if ( StrModality.find("SM") < StrModality.length()) return SM;
00518 else if ( StrModality.find("ST") < StrModality.length()) return ST;
00519 else if ( StrModality.find("TG") < StrModality.length()) return TG;
00520 else if ( StrModality.find("US") < StrModality.length()) return US;
00521 else if ( StrModality.find("VF") < StrModality.length()) return VF;
00522 else if ( StrModality.find("XA") < StrModality.length()) return XA;
00523 else if ( StrModality.find("XC") < StrModality.length()) return XC;
00524
00525 else
00526 {
00527
00528
00529 return Unknow;
00530 }
00531 }
00532 return Unknow;
00533 }
00534
00541 void gdcmHeaderHelper::GetImageOrientationPatient( float* iop ) {
00542
00543
00544 iop[0] = iop[1] = iop[2] = iop[3] = iop[4] = iop[5] = 0;
00545
00546 std::string StrImOriPat = GetEntryByNumber(0x0020,0x0037);
00547 if (StrImOriPat != GDCM_UNFOUND) {
00548 if( sscanf( StrImOriPat.c_str(), "%f\\%f\\%f\\%f\\%f\\%f",
00549 &iop[0], &iop[1], &iop[2], &iop[3], &iop[4], &iop[5]) != 6) {
00550 dbg.Verbose(0, "gdcmHeader::GetImageOrientationPatient: wrong Image Orientation Patient (0020,0037)");
00551 return ;
00552 }
00553 else
00554 return ;
00555 }
00556
00557
00558 StrImOriPat = GetEntryByNumber(0x0020,0x0035);
00559 if (StrImOriPat != GDCM_UNFOUND) {
00560 if( sscanf( StrImOriPat.c_str(), "%f\\%f\\%f\\%f\\%f\\%f",
00561 &iop[0], &iop[1], &iop[2], &iop[3], &iop[4], &iop[5]) != 6) {
00562 dbg.Verbose(0, "gdcmHeader::GetImageOrientationPatient: wrong Image Orientation Patient (0020,0035)");
00563 return ;
00564 }
00565 else
00566 return ;
00567 }
00568 }
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584 gdcmSerieHeaderHelper::~gdcmSerieHeaderHelper(){
00586 for (std::list<gdcmHeaderHelper*>::iterator it = CoherentGdcmFileList.begin();
00587 it != CoherentGdcmFileList.end(); it++)
00588 {
00589 delete *it;
00590 }
00591 CoherentGdcmFileList.clear();
00592 }
00593
00594
00595
00596
00597
00598
00604 void gdcmSerieHeaderHelper::AddFileName(std::string filename) {
00605 gdcmHeaderHelper *GdcmFile = new gdcmHeaderHelper( filename.c_str() );
00606 this->CoherentGdcmFileList.push_back( GdcmFile );
00607 }
00608
00614 void gdcmSerieHeaderHelper::AddGdcmFile(gdcmHeaderHelper *file){
00615 this->CoherentGdcmFileList.push_back( file );
00616 }
00617
00623 void gdcmSerieHeaderHelper::SetDirectory(std::string dir){
00624 gdcmDirList filenames_list(dir);
00625
00626 for(gdcmDirList::iterator it = filenames_list.begin();
00627 it !=filenames_list.end(); it++)
00628 {
00629 gdcmHeaderHelper *file = new gdcmHeaderHelper( it->c_str() );
00630 this->CoherentGdcmFileList.push_back( file );
00631 }
00632 }
00633
00641 void gdcmSerieHeaderHelper::OrderGdcmFileList(){
00642 if( ImagePositionPatientOrdering() ) {
00643 return ;
00644 }
00645 else if( ImageNumberOrdering() ) {
00646 return ;
00647 } else {
00648 FileNameOrdering();
00649 }
00650 }
00651
00657 std::list<gdcmHeaderHelper*> &gdcmSerieHeaderHelper::GetGdcmFileList() {
00658 return CoherentGdcmFileList;
00659 }
00660
00661
00662
00663
00664
00665
00675 bool gdcmSerieHeaderHelper::ImagePositionPatientOrdering()
00676
00677 {
00678
00679 float *cosines = new float[6];
00680 float normal[3];
00681 float ipp[3];
00682 float dist;
00683 float min, max;
00684 bool first = true;
00685 int n=0;
00686 std::vector<float> distlist;
00687
00689 for (std::list<gdcmHeaderHelper*>::iterator it = CoherentGdcmFileList.begin();
00690 it != CoherentGdcmFileList.end(); it++)
00691 {
00692 if(first) {
00693 (*it)->GetImageOrientationPatient(cosines);
00694
00695
00696
00697
00698 normal[0] = cosines[1]*cosines[5] - cosines[2]*cosines[4];
00699 normal[1] = cosines[2]*cosines[3] - cosines[0]*cosines[5];
00700 normal[2] = cosines[0]*cosines[4] - cosines[1]*cosines[3];
00701
00702 ipp[0] = (*it)->GetXOrigin();
00703 ipp[1] = (*it)->GetYOrigin();
00704 ipp[2] = (*it)->GetZOrigin();
00705
00706 dist = 0;
00707 for (int i = 0; i < 3; ++i)
00708 dist += normal[i]*ipp[i];
00709
00710 if( dist == 0 )
00711 {
00712 delete[] cosines;
00713 return false;
00714 }
00715
00716 distlist.push_back( dist );
00717
00718 max = min = dist;
00719 first = false;
00720 }
00721 else {
00722 ipp[0] = (*it)->GetXOrigin();
00723 ipp[1] = (*it)->GetYOrigin();
00724 ipp[2] = (*it)->GetZOrigin();
00725
00726 dist = 0;
00727 for (int i = 0; i < 3; ++i)
00728 dist += normal[i]*ipp[i];
00729
00730 if( dist == 0 )
00731 {
00732 delete[] cosines;
00733 return false;
00734 }
00735
00736 distlist.push_back( dist );
00737
00738 min = (min < dist) ? min : dist;
00739 max = (max > dist) ? max : dist;
00740 }
00741 n++;
00742 }
00743
00744
00745
00746
00747 std::vector<gdcmHeaderHelper*> CoherentGdcmFileVector(n);
00748
00749 CoherentGdcmFileVector.resize( n );
00750
00751
00752 float step = (max - min)/(n - 1);
00753 int pos;
00754 n = 0;
00755
00756
00757 for (std::list<gdcmHeaderHelper*>::iterator it2 = CoherentGdcmFileList.begin();
00758 it2 != CoherentGdcmFileList.end(); it2++, n++)
00759 {
00760
00761
00762 pos = (int)( fabs( (distlist[n]-min)/step) + .5 );
00763
00764 CoherentGdcmFileVector[pos] = *it2;
00765 }
00766
00767 CoherentGdcmFileList.clear();
00768
00769
00770 for (std::vector<gdcmHeaderHelper*>::iterator it3 = CoherentGdcmFileVector.begin();
00771 it3 != CoherentGdcmFileVector.end(); it3++)
00772 {
00773 CoherentGdcmFileList.push_back( *it3 );
00774 }
00775
00776 distlist.clear();
00777 CoherentGdcmFileVector.clear();
00778 delete[] cosines;
00779
00780 return true;
00781 }
00782
00789 bool gdcmSerieHeaderHelper::ImageNumberOrdering() {
00790 int min, max, pos;
00791 int n = 0;
00792 unsigned char *partition;
00793
00794 std::list<gdcmHeaderHelper*>::iterator it = CoherentGdcmFileList.begin();
00795 min = max = (*it)->GetImageNumber();
00796
00797 for (; it != CoherentGdcmFileList.end(); it++, n++)
00798 {
00799 pos = (*it)->GetImageNumber();
00800
00801
00802 min = (min < pos) ? min : pos;
00803 }
00804
00805
00806 partition = new unsigned char[n];
00807 memset(partition, 0, n);
00808
00809 std::vector<gdcmHeaderHelper*> CoherentGdcmFileVector(n);
00810
00811
00812 for (std::list<gdcmHeaderHelper*>::iterator it2 = CoherentGdcmFileList.begin();
00813 it2 != CoherentGdcmFileList.end(); it2++)
00814 {
00815 pos = (*it2)->GetImageNumber();
00816 CoherentGdcmFileVector[pos - min] = *it2;
00817 partition[pos - min]++;
00818 }
00819
00820 unsigned char mult = 1;
00821 for(int i=0; i<n ; i++)
00822 {
00823 mult *= partition[i];
00824 }
00825
00826
00827 CoherentGdcmFileList.clear();
00828 for (std::vector<gdcmHeaderHelper*>::iterator it3 = CoherentGdcmFileVector.begin();
00829 it3 != CoherentGdcmFileVector.end(); it3++)
00830 {
00831 CoherentGdcmFileList.push_back( *it3 );
00832 }
00833 CoherentGdcmFileVector.clear();
00834
00835 delete[] partition;
00836 return (mult!=0);
00837 }
00838
00839
00845 bool gdcmSerieHeaderHelper::FileNameOrdering() {
00846
00847
00848 return true;
00849 }
00850
00851