#include "clitkImageCommon.h"
#include "vvImageReader.h"
#include "vvImageWriter.h"
+#include <itkGDCMImageIO.h>
+#include <itkGDCMSeriesFileNames.h>
#include <gdcmFile.h>
#include <vtkVersion.h>
#include <vtkImageChangeInformation.h>
-#if GDCM_MAJOR_VERSION == 2
+#if GDCM_MAJOR_VERSION >= 2
#include <gdcmImageHelper.h>
#include <gdcmAttribute.h>
#include <gdcmReader.h>
} else for (unsigned int i=0; i<args_info.inputs_num; i++)
input_files.push_back(args_info.inputs[i]);
+ //Get GDCMSeriesFileNames order to sort filenames
+ typedef itk::GDCMSeriesFileNames NamesGeneratorType;
+ NamesGeneratorType::Pointer nameGenerator = NamesGeneratorType::New();
+ nameGenerator->SetUseSeriesDetails(false);
+ std::string folderName=".";
+ const size_t last_slash_idx = input_files[0].rfind('/');
+ if (std::string::npos != last_slash_idx)
+ folderName = input_files[0].substr(0, last_slash_idx);
+ nameGenerator->SetInputDirectory(folderName);
//===========================================
/// Get slices locations ...
- int series_number = -1;
- std::set<int> series_numbers;
- std::map< int, std::vector<double> > theorigin;
- std::map< int, std::vector<double> > theorientation;
- std::map< int, std::vector<double> > sliceLocations;
- std::map< int, std::vector<std::string> > seriesFiles;
-#if GDCM_MAJOR_VERSION == 2
+ std::string series_UID = "";
+ std::set<std::string> series_UIDs;
+ std::map< std::string, std::vector<double> > theorigin;
+ std::map< std::string, std::vector<double> > theorientation;
+ std::map< std::string, std::vector<double> > sliceLocations;
+ std::map< std::string, std::vector<std::string> > seriesFiles;
+#if GDCM_MAJOR_VERSION >= 2
if (args_info.verbose_flag)
std::cout << "Using GDCM-2.x" << std::endl;
#else
for(unsigned int i=0; i<args_info.inputs_num; i++) {
if (args_info.verbose_flag)
std::cout << "Reading <" << input_files[i] << std::endl;
-#if GDCM_MAJOR_VERSION == 2
+#if GDCM_MAJOR_VERSION >= 2
gdcm::Reader hreader;
hreader.SetFileName(input_files[i].c_str());
hreader.Read();
gdcm::DataSet& ds = hreader.GetFile().GetDataSet();
- if (args_info.extract_series_flag) {
- gdcm::Attribute<0x20,0x11> series_number_att;
- series_number_att.SetFromDataSet(ds);
- series_number = series_number_att.GetValue();
- }
+ gdcm::Attribute<0x20,0x000e> series_UID_att;
+ series_UID_att.SetFromDataSet(ds);
+ series_UID = series_UID_att.GetValue().c_str();
- series_numbers.insert(series_number);
- theorigin[series_number] = gdcm::ImageHelper::GetOriginValue(hreader.GetFile());
- theorientation[series_number] = gdcm::ImageHelper::GetDirectionCosinesValue(hreader.GetFile());
- double n1 = theorientation[series_number][1]*theorientation[series_number][5]-
- theorientation[series_number][2]*theorientation[series_number][4];
- double n2 = theorientation[series_number][3]*theorientation[series_number][2]-
- theorientation[series_number][5]*theorientation[series_number][0];
- double n3 = theorientation[series_number][0]*theorientation[series_number][4]-
- theorientation[series_number][1]*theorientation[series_number][3];
- double sloc = theorigin[series_number][0]*n1+
- theorigin[series_number][1]*n2+
- theorigin[series_number][2]*n3;
- sliceLocations[series_number].push_back(sloc);
- seriesFiles[series_number].push_back(input_files[i]);
+ series_UIDs.insert(series_UID);
+ theorigin[series_UID] = gdcm::ImageHelper::GetOriginValue(hreader.GetFile());
+ theorientation[series_UID] = gdcm::ImageHelper::GetDirectionCosinesValue(hreader.GetFile());
+ if (args_info.patientSystem_flag) {
+ double n1 = theorientation[series_UID][1]*theorientation[series_UID][5]-
+ theorientation[series_UID][2]*theorientation[series_UID][4];
+ double n2 = theorientation[series_UID][3]*theorientation[series_UID][2]-
+ theorientation[series_UID][5]*theorientation[series_UID][0];
+ double n3 = theorientation[series_UID][0]*theorientation[series_UID][4]-
+ theorientation[series_UID][1]*theorientation[series_UID][3];
+ double sloc = theorigin[series_UID][0]*n1+
+ theorigin[series_UID][1]*n2+
+ theorigin[series_UID][2]*n3;
+ sliceLocations[series_UID].push_back(sloc);
+ } else
+ sliceLocations[series_UID].push_back(theorigin[series_UID][2]);
+ seriesFiles[series_UID].push_back(input_files[i]);
gdcm::Attribute<0x28, 0x100> pixel_size;
pixel_size.SetFromDataSet(ds);
header->SetMaxSizeLoadEntry(16384); // required ?
header->Load();
- if (args_info.extract_series_flag) {
- series_number = atoi(header->GetEntryValue(0x20,0x11).c_str());
- }
+ series_UID = header->GetEntryValue(0x20,0x000e).c_str();
- series_numbers.insert(series_number);
- theorigin[series_number].resize(3);
- theorigin[series_number][0] = header->GetXOrigin();
- theorigin[series_number][1] = header->GetYOrigin();
- theorigin[series_number][2] = header->GetZOrigin();
- sliceLocations[series_number].push_back(theorigin[series_number][2]);
- seriesFiles[series_number].push_back(input_files[i]);
+ series_UIDs.insert(series_UID);
+ theorigin[series_UID].resize(3);
+ theorigin[series_UID][0] = header->GetXOrigin();
+ theorigin[series_UID][1] = header->GetYOrigin();
+ theorigin[series_UID][2] = header->GetZOrigin();
+ sliceLocations[series_UID].push_back(theorigin[series_UID][2]);
+ seriesFiles[series_UID].push_back(input_files[i]);
/*if (header->GetPixelSize() != 2) {
std::cerr << "Pixel type 2 bytes ! " << std::endl;
std::cerr << "In file " << input_files[i] << std::endl;
//===========================================
// Sort slices locations ...
- std::set<int>::iterator sn = series_numbers.begin();
- while ( sn != series_numbers.end() ) {
+ std::set<std::string>::iterator sn = series_UIDs.begin();
+ while ( sn != series_UIDs.end() ) {
std::vector<double> locs = sliceLocations[*sn];
std::vector<double> origin = theorigin[*sn];
std::vector<std::string> files = seriesFiles[*sn];
- std::vector<int> sliceIndex;
- clitk::GetSortedIndex(locs, sliceIndex);
+ std::vector<int> sliceIndex(files.size());
+ //clitk::GetSortedIndex(locs, sliceIndex);
+ //Look for files into GDCMSeriesFileNames, because it sorts files correctly and take the order
+ const std::vector<std::string> & temp = nameGenerator->GetFileNames(*sn);
+ for(unsigned int i=0; i<files.size(); i++) {
+ int j(0);
+ bool found(false);
+ while (!found && j<temp.size()) {
+ const size_t last_slash_idx2 = temp[j].rfind('/');
+ std::string tempFilename(temp[j]);
+ if (temp[j][0] == '.' && temp[j][1] == '/')
+ tempFilename = temp[j].substr(2, temp[j].size()-1);
+ if (tempFilename == files[i]) {
+ sliceIndex[j] = i;
+ found = true;
+ }
+ ++j;
+ }
+ }
+ if (sliceIndex.size() == 0) { //ie. sn is not a serie present in files
+ sn++;
+ continue;
+ }
+
if (args_info.verbose_flag) {
std::cout << locs[sliceIndex[0]] << " -> "
<< sliceIndex[0] << " / " << 0 << " => "
// Read write serie
vvImageReader::Pointer reader = vvImageReader::New();
reader->SetInputFilenames(sorted_files);
+ reader->SetPatientCoordinateSystem(args_info.patientSystem_flag);
reader->Update(vvImageReader::DICOM);
if (reader->GetLastError().size() != 0) {
std::cerr << reader->GetLastError() << std::endl;
}
std::string outfile;
- if (series_numbers.size() == 1)
+ if (series_UIDs.size() == 1)
outfile = args_info.output_arg;
else {
std::ostringstream name;
name << *sn << "_" << args_info.output_arg;
outfile = name.str();
}
- //Check on transform
- bool bId = true;
- for(unsigned int i=0; i<4; i++) {
- for(unsigned int j=0; j<4; j++) {
- double elt = image->GetTransform()[0]->GetMatrix()->GetElement(i,j);
- if(i==j && elt!=1.) {
- bId = false;
- }
- if(i!=j && elt!=0.) {
- bId = false;
- }
- }
- }
vvImageWriter::Pointer writer = vvImageWriter::New();
writer->SetInput(image);
- if(!bId) {
- writer->SetSaveTransform(true);
- }
+ if (args_info.patientSystem_flag && !image->GetTransform().empty())
+ writer->SetSaveTransform(true);
writer->SetOutputFileName(outfile);
writer->Update();