From 2a411bd641bb5979b3d8ecd3785a844aeffbb56f Mon Sep 17 00:00:00 2001 From: Romulo Pinho Date: Thu, 31 Jan 2013 16:26:19 +0100 Subject: [PATCH] support different series in a single dicom folder in Dicom2Image --- tools/clitkDicom2Image.cxx | 210 ++++++++++++++++++++++--------------- tools/clitkDicom2Image.ggo | 1 + 2 files changed, 127 insertions(+), 84 deletions(-) diff --git a/tools/clitkDicom2Image.cxx b/tools/clitkDicom2Image.cxx index 07a8565..2819fde 100644 --- a/tools/clitkDicom2Image.cxx +++ b/tools/clitkDicom2Image.cxx @@ -30,6 +30,8 @@ #include #endif +#include + //==================================================================== int main(int argc, char * argv[]) { @@ -52,8 +54,11 @@ int main(int argc, char * argv[]) //=========================================== /// Get slices locations ... - std::vector theorigin(3); - std::vector sliceLocations; + int series_number = -1; + std::set series_numbers; + std::map< int, std::vector > theorigin; + std::map< int, std::vector > sliceLocations; + std::map< int, std::vector > seriesFiles; for(unsigned int i=0; i pixel_size; gdcm::DataSet& ds = hreader.GetFile().GetDataSet(); + + if (args_info.extract_series_flag) { + gdcm::Attribute<0x20,0x11> series_number_att; + series_number_att.SetFromDataSet(hreader.GetFile().GetDataSet()); + series_number = series_number_att.GetValue(); + } + + series_numbers.insert(series_number); + theorigin[series_number] = gdcm::ImageHelper::GetOriginValue(hreader.GetFile()); + std::cout << "theorigin[series_number][0] " << theorigin[series_number][0] << std::endl; + std::cout << "theorigin[series_number][1] " << theorigin[series_number][1] << std::endl; + std::cout << "theorigin[series_number][2] " << theorigin[series_number][2] << std::endl; + sliceLocations[series_number].push_back(theorigin[series_number][2]); + seriesFiles[series_number].push_back(input_files[i]); + + gdcm::Attribute<0x28, 0x100> pixel_size; pixel_size.SetFromDataSet(ds); if (pixel_size.GetValue() != 16) { @@ -80,10 +98,18 @@ int main(int argc, char * argv[]) header->SetFileName(input_files[i]); header->SetMaxSizeLoadEntry(16384); // required ? header->Load(); - theorigin[0] = header->GetXOrigin(); - theorigin[1] = header->GetYOrigin(); - theorigin[2] = header->GetZOrigin(); - sliceLocations.push_back(theorigin[2]); + + if (args_info.extract_series_flag) { + series_number = atoi(header->GetEntryValue(0x20,0x11).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]); if (header->GetPixelSize() != 2) { std::cerr << "Pixel type 2 bytes ! " << std::endl; std::cerr << "In file " << input_files[i] << std::endl; @@ -94,87 +120,103 @@ int main(int argc, char * argv[]) //=========================================== // Sort slices locations ... - std::vector sliceIndex; - clitk::GetSortedIndex(sliceLocations, sliceIndex); - if (args_info.verboseSliceLocation_flag) { - std::cout << sliceLocations[sliceIndex[0]] << " -> " - << sliceIndex[0] << " / " << 0 << " => " - << "0 mm " - << input_files[sliceIndex[0]] - << std::endl; - for(unsigned int i=1; i " - << sliceIndex[i] << " / " << i << " => " - << sliceLocations[sliceIndex[i]] - sliceLocations[sliceIndex[i-1]] - << "mm " - << input_files[sliceIndex[i]] + std::set::iterator sn = series_numbers.begin(); + while ( sn != series_numbers.end() ) { + std::vector locs = sliceLocations[*sn]; + std::vector origin = theorigin[*sn]; + std::vector files = seriesFiles[*sn]; + std::vector sliceIndex; + clitk::GetSortedIndex(locs, sliceIndex); + if (args_info.verboseSliceLocation_flag) { + std::cout << locs[sliceIndex[0]] << " -> " + << sliceIndex[0] << " / " << 0 << " => " + << "0 mm " + << files[sliceIndex[0]] << std::endl; - } - } - - //=========================================== - // Analyze slices locations ... - double currentDist; - double dist=0; - double tolerance = args_info.tolerance_arg; - double previous = sliceLocations[sliceIndex[0]]; - for(unsigned int i=1; i tolerance) { - std::cout << "ERROR : " << std::endl - << "Current slice pos is = " << sliceLocations[sliceIndex[i]] << std::endl - << "Previous slice pos is = " << previous << std::endl - << "Current file is = " << input_files[sliceIndex[i]] << std::endl - << "Current index is = " << i << std::endl - << "Current sortindex is = " << sliceIndex[i] << std::endl - << "Current slice diff = " << dist << std::endl - << "Current error = " << fabs(dist-currentDist) << std::endl; - exit(1); + for(unsigned int i=1; i " + << sliceIndex[i] << " / " << i << " => " + << locs[sliceIndex[i]] - locs[sliceIndex[i-1]] + << "mm " + << files[sliceIndex[i]] + << std::endl; } - } else dist = currentDist; - previous = sliceLocations[sliceIndex[i]]; - } + } - //=========================================== - // Create ordered vector of filenames - std::vector sorted_files; - sorted_files.resize(sliceIndex.size()); - for(unsigned int i=0; i tolerance) { + std::cout << "ERROR : " << std::endl + << "Current slice pos is = " << locs[sliceIndex[i]] << std::endl + << "Previous slice pos is = " << previous << std::endl + << "Current file is = " << files[sliceIndex[i]] << std::endl + << "Current index is = " << i << std::endl + << "Current sortindex is = " << sliceIndex[i] << std::endl + << "Current slice diff = " << dist << std::endl + << "Current error = " << fabs(dist-currentDist) << std::endl; + exit(1); + } + } else dist = currentDist; + previous = locs[sliceIndex[i]]; + } - //=========================================== - // Read write serie - vvImageReader::Pointer reader = vvImageReader::New(); - reader->SetInputFilenames(sorted_files); - reader->Update(vvImageReader::DICOM); - if (reader->GetLastError().size() != 0) { - std::cerr << reader->GetLastError() << std::endl; - return 1; - } - - vvImage::Pointer image = reader->GetOutput(); - vtkImageData* vtk_image = image->GetFirstVTKImageData(); - vtkImageChangeInformation* modifier = vtkImageChangeInformation::New(); - if (args_info.focal_origin_given) { - std::vector spacing = image->GetSpacing(); - std::vector size = image->GetSize(); - theorigin[0] = -spacing[0]*size[0]/2.0; - theorigin[1] = -spacing[1]*size[1]/2.0; - modifier->SetInput(vtk_image); - modifier->SetOutputOrigin(theorigin[0], theorigin[1], sliceLocations[sliceIndex[0]]); - modifier->Update(); - vvImage::Pointer focal_image = vvImage::New(); - focal_image->AddVtkImage(modifier->GetOutput()); - image = focal_image; - } + //=========================================== + // Create ordered vector of filenames + std::vector sorted_files; + sorted_files.resize(sliceIndex.size()); + for(unsigned int i=0; iSetInput(image); - writer->SetOutputFileName(args_info.output_arg); - writer->Update(); + //=========================================== + // Read write serie + vvImageReader::Pointer reader = vvImageReader::New(); + reader->SetInputFilenames(sorted_files); + reader->Update(vvImageReader::DICOM); + if (reader->GetLastError().size() != 0) { + std::cerr << reader->GetLastError() << std::endl; + return 1; + } + + vvImage::Pointer image = reader->GetOutput(); + vtkImageData* vtk_image = image->GetFirstVTKImageData(); + vtkImageChangeInformation* modifier = vtkImageChangeInformation::New(); + if (args_info.focal_origin_given) { + std::vector spacing = image->GetSpacing(); + std::vector size = image->GetSize(); + origin[0] = -spacing[0]*size[0]/2.0; + origin[1] = -spacing[1]*size[1]/2.0; + modifier->SetInput(vtk_image); + modifier->SetOutputOrigin(origin[0], origin[1], locs[sliceIndex[0]]); + modifier->Update(); + vvImage::Pointer focal_image = vvImage::New(); + focal_image->AddVtkImage(modifier->GetOutput()); + image = focal_image; + } - modifier->Delete(); + std::string outfile; + if (series_numbers.size() == 1) + outfile = args_info.output_arg; + else { + std::ostringstream name; + name << *sn << "_" << args_info.output_arg; + outfile = name.str(); + } + vvImageWriter::Pointer writer = vvImageWriter::New(); + writer->SetInput(image); + writer->SetOutputFileName(outfile); + writer->Update(); + modifier->Delete(); + + sn++; + } + return 0; } diff --git a/tools/clitkDicom2Image.ggo b/tools/clitkDicom2Image.ggo index fb51135..a2d3a89 100644 --- a/tools/clitkDicom2Image.ggo +++ b/tools/clitkDicom2Image.ggo @@ -10,3 +10,4 @@ option "tolerance" t "Tolerance for slice position" double default="0" no option "output" o "Output image filename" string yes option "std_input" - "Take the like of input file from stdin, to support huge lists of filenames" flag off option "focal_origin" - "Output files with FOCAL-like origin, instead of the origin present in the dicom files" flag off +option "extract_series" s "Identify different series in the file list and create the MHDs accordinly" flag off -- 2.47.1