/*========================================================================= Program: GDCM (Grassroots DICOM). A DICOM library Copyright (c) 2006-2011 Mathieu Malaterre All rights reserved. See Copyright.txt or http://gdcm.sourceforge.net/Copyright.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 notice for more information. =========================================================================*/ /* */ #include "gdcmSorter.h" #include "gdcmScanner.h" #include "gdcmDataSet.h" #include "gdcmAttribute.h" bool mysort(gdcm::DataSet const & ds1, gdcm::DataSet const & ds2 ) { //gdcm::Attribute<0x0020,0x0013> at1; // Instance Number gdcm::Attribute<0x0018,0x1060> at1; // Trigger Time gdcm::Attribute<0x0020,0x0032> at11; // Image Position (Patient) at1.Set( ds1 ); at11.Set( ds1 ); //gdcm::Attribute<0x0020,0x0013> at2; gdcm::Attribute<0x0018,0x1060> at2; gdcm::Attribute<0x0020,0x0032> at22; at2.Set( ds2 ); at22.Set( ds2 ); if( at11 == at22 ) { return at1 < at2; } return at11 < at22; } bool mysort_part1(gdcm::DataSet const & ds1, gdcm::DataSet const & ds2 ) { gdcm::Attribute<0x0018,0x1060> at1; at1.Set( ds1 ); gdcm::Attribute<0x0018,0x1060> at2; at2.Set( ds2 ); return at1 < at2; } bool mysort_part2(gdcm::DataSet const & ds1, gdcm::DataSet const & ds2 ) { gdcm::Attribute<0x0020,0x0032> at1; at1.Set( ds1 ); gdcm::Attribute<0x0020,0x0032> at2; at2.Set( ds2 ); return at1 < at2; } // technically all files are in the same Frame of Reference, so this function // should be a no-op bool mysort_dummy(gdcm::DataSet const & ds1, gdcm::DataSet const & ds2 ) { gdcm::Attribute<0x0020,0x0052> at1; // FrameOfReferenceUID at1.Set( ds1 ); gdcm::Attribute<0x0020,0x0052> at2; at2.Set( ds2 ); return at1 < at2; } int main(int argc, char *argv[]) { if (argc < 2 ) return 1; const char *dirname = argv[1]; gdcm::Directory dir; unsigned int nfiles = dir.Load( dirname ); dir.Print( std::cout ); gdcm::Sorter sorter; sorter.SetSortFunction( mysort ); sorter.Sort( dir.GetFilenames() ); std::cout << "Sorter:" << std::endl; sorter.Print( std::cout ); gdcm::Sorter sorter2; sorter2.SetSortFunction( mysort_part1 ); sorter2.StableSort( dir.GetFilenames() ); sorter2.SetSortFunction( mysort_part2 ); sorter2.StableSort( sorter2.GetFilenames() ); // IMPORTANT sorter2.SetSortFunction( mysort_dummy ); sorter2.StableSort( sorter2.GetFilenames() ); // IMPORTANT std::cout << "Sorter2:" << std::endl; sorter2.Print( std::cout ); gdcm::Scanner s; s.AddTag( gdcm::Tag(0x20,0x32) ); // Image Position (Patient) //s.AddTag( gdcm::Tag(0x20,0x37) ); // Image Orientation (Patient) s.Scan( dir.GetFilenames() ); //s.Print( std::cout ); // Count how many different IPP there are: const gdcm::Scanner::ValuesType &values = s.GetValues(); size_t nvalues = values.size(); std::cout << "There are " << nvalues << " different type of values" << std::endl; //std::cout << "nfiles=" << nfiles << std::endl; if( nfiles % nvalues != 0 ) { std::cerr << "Impossible: this is a not a proper series" << std::endl; return 1; } std::cout << "Series is composed of " << (nfiles/nvalues) << " different 3D volumes" << std::endl; return 0; }