]> Creatis software - clitk.git/commitdiff
From Benoit P, use clitkDicomRTStruct2Image with image with direction cosine rtStruct
authortbaudier <thomas.baudier@creatis.insa-lyon.fr>
Thu, 10 Oct 2019 07:21:31 +0000 (09:21 +0200)
committertbaudier <thomas.baudier@creatis.insa-lyon.fr>
Thu, 10 Oct 2019 07:21:31 +0000 (09:21 +0200)
15 files changed:
common/clitkDicomRTStruct2ImageFilter.cxx
common/clitkDicomRTStruct2ImageFilter.h
common/clitkDicomRT_Contour.cxx
common/clitkDicomRT_Contour.h
common/clitkDicomRT_ROI.cxx
common/clitkDicomRT_ROI.h
common/clitkDicomRT_StructureSet.cxx
common/clitkDicomRT_StructureSet.h
common/vvImage.cxx
common/vvImage.h
tools/clitkDicom2Image.cxx
tools/clitkDicomRTStruct2Image.cxx
tools/clitkDicomRTStruct2Image.ggo
vv/vvToolROIManager.cxx
vv/vvToolROIManager.h

index 2e11fdc42a6ccd2a3243d8f6598b74c52cddd534..81c478e736c0c03677b1e472b555bed80effba31 100644 (file)
@@ -23,6 +23,7 @@
 // clitk
 #include "clitkDicomRTStruct2ImageFilter.h"
 #include "clitkImageCommon.h"
+#include "vvImageWriter.h"
 
 // vtk
 #include <vtkVersion.h>
@@ -32,6 +33,7 @@
 #include <vtkLinearExtrusionFilter.h>
 #include <vtkMetaImageWriter.h>
 #include <vtkXMLPolyDataWriter.h>
+#include <vtkTransformPolyDataFilter.h>
 
 
 //--------------------------------------------------------------------
@@ -107,13 +109,19 @@ void clitk::DicomRTStruct2ImageFilter::SetImage(vvImage::Pointer image)
 {
   if (image->GetNumberOfDimensions() != 3) {
     std::cerr << "Error. Please provide a 3D image." << std::endl;
-    exit(0);
+    exit(EXIT_FAILURE);
   }
   mSpacing.resize(3);
   mOrigin.resize(3);
   mSize.resize(3);
   mDirection.resize(3);
-  mTransformMatrix = image->GetTransform()[0]->GetMatrix();
+  //mTransformMatrix = image->GetTransform()[0]->GetMatrix();
+  mTransformMatrix = vtkSmartPointer<vtkMatrix4x4>::New();
+  for(unsigned int i=0;i<4;i++) {
+      for(unsigned int j=0;j<4;j++) {
+          mTransformMatrix->SetElement(i,j,image->GetTransform()[0]->GetMatrix()->GetElement(i,j));
+      }
+  }
   for(unsigned int i=0; i<3; i++) {
     mSpacing[i] = image->GetSpacing()[i];
     mOrigin[i] = image->GetOrigin()[i];
@@ -132,7 +140,7 @@ void clitk::DicomRTStruct2ImageFilter::SetImageFilename(std::string f)
   itk::ImageIOBase::Pointer header = clitk::readImageHeader(f);
   if (header->GetNumberOfDimensions() < 3) {
     std::cerr << "Error. Please provide a 3D image instead of " << f << std::endl;
-    exit(0);
+    exit(EXIT_FAILURE);
   }
   if (header->GetNumberOfDimensions() > 3) {
     std::cerr << "Warning dimension > 3 are ignored" << std::endl;
@@ -149,6 +157,18 @@ void clitk::DicomRTStruct2ImageFilter::SetImageFilename(std::string f)
     for(unsigned int j=0; j<3; j++)
       mDirection[i][j] = header->GetDirection(i)[j];
   }
+  //cf. AddItkImage function in vvImage.txx
+  mTransformMatrix = vtkSmartPointer<vtkMatrix4x4>::New();
+  mTransformMatrix->Identity();
+  for(unsigned int i=0; i<3; i++) {
+      double tmp = 0;
+      for(unsigned int j=0; j<3; j++) {
+          mTransformMatrix->SetElement(i,j,mDirection[i][j]);
+          tmp -= mDirection[i][j] * mOrigin[j];
+      }
+      tmp += mOrigin[i];
+      mTransformMatrix->SetElement(i,3,tmp);
+  }
 }
 //--------------------------------------------------------------------
 
@@ -182,11 +202,11 @@ void clitk::DicomRTStruct2ImageFilter::Update()
 {
   if (!mROI) {
     std::cerr << "Error. No ROI set, please use SetROI." << std::endl;
-    exit(0);
+    exit(EXIT_FAILURE);
   }
   if (!ImageInfoIsSet()) {
     std::cerr << "Error. Please provide image info (spacing/origin) with SetImageFilename" << std::endl;
-    exit(0);
+    exit(EXIT_FAILURE);
   }
 
   // Get Mesh
@@ -206,7 +226,7 @@ void clitk::DicomRTStruct2ImageFilter::Update()
 
   // Get bounds
   double *bounds=mesh->GetBounds();
-
+  /*
   //Change mOrigin, mSize and mSpacing with respect to the directions
   // Spacing is influenced by input direction
   std::vector<double> tempSpacing;
@@ -238,7 +258,7 @@ void clitk::DicomRTStruct2ImageFilter::Update()
     }
     mSize[i] = lrint(tempSize[i]);
   }
-
+  */
   // Compute origin
   std::vector<double> origin;
   origin.resize(3);
@@ -259,7 +279,18 @@ void clitk::DicomRTStruct2ImageFilter::Update()
       extend[i] = mSize[i]-1;
     }
   }
-
+  //Apply the transform to the mesh
+  vtkSmartPointer<vtkTransform> outputLabelmapGeometryTransform = vtkSmartPointer<vtkTransform>::New();
+  outputLabelmapGeometryTransform->SetMatrix(mTransformMatrix);
+  // Apparently the inverse is wrong...
+  //outputLabelmapGeometryTransform->Inverse();
+  vtkSmartPointer<vtkTransformPolyDataFilter> transformPolyDataFilter = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
+#if VTK_MAJOR_VERSION <= 5
+  transformPolyDataFilter->SetInput(mesh);
+#else
+  transformPolyDataFilter->SetInputData(mesh);
+#endif
+  transformPolyDataFilter->SetTransform(outputLabelmapGeometryTransform);
   // Create new output image
   mBinaryImage = vtkSmartPointer<vtkImageData>::New();
 #if VTK_MAJOR_VERSION <= 5
@@ -281,11 +312,7 @@ void clitk::DicomRTStruct2ImageFilter::Update()
 
   // Extrude
   vtkSmartPointer<vtkLinearExtrusionFilter> extrude=vtkSmartPointer<vtkLinearExtrusionFilter>::New();
-#if VTK_MAJOR_VERSION <= 5
-  extrude->SetInput(mesh);
-#else
-  extrude->SetInputData(mesh);
-#endif
+  extrude->SetInputConnection(transformPolyDataFilter->GetOutputPort());
   ///We extrude in the -slice_spacing direction to respect the FOCAL convention (NEEDED !)
   extrude->SetVector(0, 0, -mSpacing[2]);
 
@@ -295,11 +322,7 @@ void clitk::DicomRTStruct2ImageFilter::Update()
   //http://www.nabble.com/Bug-in-vtkPolyDataToImageStencil--td23368312.html#a23370933
   sts->SetTolerance(0);
   sts->SetInformationInput(mBinaryImage);
-#if VTK_MAJOR_VERSION <= 5
-  sts->SetInput(extrude->GetOutput());
-#else
   sts->SetInputConnection(extrude->GetOutputPort(0));
-#endif
   //sts->SetInput(mesh);
 
   vtkSmartPointer<vtkImageStencil> stencil=vtkSmartPointer<vtkImageStencil>::New();
@@ -316,22 +339,26 @@ void clitk::DicomRTStruct2ImageFilter::Update()
   stencil->ReverseStencilOn();
   stencil->Update();
 
-  /*
-  vtkSmartPointer<vtkMetaImageWriter> w = vtkSmartPointer<vtkMetaImageWriter>::New();
-  w->SetInput(stencil->GetOutput());
-  w->SetFileName("binary2.mhd");
-  w->Write();
-  */
-
   mBinaryImage->ShallowCopy(stencil->GetOutput());
 
+  vvImage::Pointer vvBinaryImage = vvImage::New();
+  vtkSmartPointer<vtkTransform> vvBinaryImageT = vtkSmartPointer<vtkTransform>::New();
+  vvBinaryImageT->SetMatrix(mTransformMatrix);
+  vvBinaryImage->AddVtkImage(mBinaryImage, vvBinaryImageT);
+
   if (mWriteOutput) {
-    typedef itk::Image<unsigned char, 3> ImageType;
-    typedef itk::VTKImageToImageFilter<ImageType> ConnectorType;
-    ConnectorType::Pointer connector = ConnectorType::New();
-    connector->SetInput(GetOutput());
-    connector->Update();
-    clitk::writeImage<ImageType>(connector->GetOutput(), mOutputFilename);
+    //typedef itk::Image<unsigned char, 3> ImageType;
+    //typedef itk::VTKImageToImageFilter<ImageType> ConnectorType;
+    //ConnectorType::Pointer connector = ConnectorType::New();
+    //connector->SetInput(GetOutput());
+    //connector->Update();
+    //clitk::writeImage<ImageType>(connector->GetOutput(), mOutputFilename);
+    vvImageWriter::Pointer writer = vvImageWriter::New();
+    writer->SetInput(vvBinaryImage);
+    if (!vvBinaryImage->GetTransform().empty())
+        writer->SetSaveTransform(true);
+    writer->SetOutputFileName(mOutputFilename);
+    writer->Update();
   }
 }
 //--------------------------------------------------------------------
index f93cbb2969ca833f70682d1307b7f4993eed4cb0..9ba08453b303546e601d2841e9756095ad6d40bb 100644 (file)
@@ -72,17 +72,17 @@ namespace clitk {
 
 //--------------------------------------------------------------------
 
-template <int Dimension> 
-typename itk::Image<unsigned char,Dimension>::ConstPointer clitk::DicomRTStruct2ImageFilter::GetITKOutput()
-{
-  assert(mBinaryImage);
-  typedef itk::Image<unsigned char,Dimension> ConnectorImageType;
-  typedef itk::VTKImageToImageFilter <ConnectorImageType> ConnectorType;
-  typename ConnectorType::Pointer connector = ConnectorType::New();
-  connector->SetInput(mBinaryImage);
-  connector->Update();
-  return connector->GetOutput();
-}
+//template <int Dimension>
+//typename itk::Image<unsigned char,Dimension>::ConstPointer clitk::DicomRTStruct2ImageFilter::GetITKOutput()
+//{
+//  assert(mBinaryImage);
+//  typedef itk::Image<unsigned char,Dimension> ConnectorImageType;
+//  typedef itk::VTKImageToImageFilter <ConnectorImageType> ConnectorType;
+//  typename ConnectorType::Pointer connector = ConnectorType::New();
+//  connector->SetInput(mBinaryImage);
+//  connector->Update();
+//  return connector->GetOutput();
+//}
 //--------------------------------------------------------------------
 #endif // CLITKDICOMRT_TRUCT2IMAGEFILTER_H
 
index 9a5042befdef6b7b14f63a86d8e23aa42e290704..6bc6332e05fff2d53be9784e2960f48b148870a5 100644 (file)
@@ -82,11 +82,7 @@ void clitk::DicomRT_Contour::UpdateDicomItem()
     double * p = mData->GetPoint(i);
     points[i*3] = p[0];
     points[i*3+1] = p[1];
-#if VTK_MAJOR_VERSION <= 5
-    points[i*3+1] = p[2];
-#else
     points[i*3+1] = p[2]-0.5;
-#endif
   }
 
   // Get attribute
@@ -96,7 +92,7 @@ void clitk::DicomRT_Contour::UpdateDicomItem()
   at.SetFromDataElement( contourdata );
 
   // Set attribute
-  at.SetValues(&points[0], points.size(), false);
+  at.SetValues(&points[0], points.size());
   DD(at.GetValues()[0]);
   
   DD("replace");
@@ -161,14 +157,10 @@ bool clitk::DicomRT_Contour::Read(gdcm::Item * item)
     double p[3];
     p[0] = points[i*3];
     p[1] = points[i*3+1];
-#if VTK_MAJOR_VERSION <= 5
-    p[2] = points[i*3+2];
-#else
     p[2] = points[i*3+2]+0.5;
-#endif
     mData->SetPoint(i, p);
     if (mZ == -1) mZ = p[2];
-    if (p[2] != mZ) {
+    if (std::fabs(p[2] - mZ) > mTolerance) {
       DD(i);
       DD(p[2]);
       DD(mZ);
@@ -212,14 +204,10 @@ bool clitk::DicomRT_Contour::Read(gdcm::SQItem * item)
     double p[3];
     p[0] = points[i*3];
     p[1] = points[i*3+1];
-#if VTK_MAJOR_VERSION <= 5
-    p[2] = points[i*3+2];
-#else
     p[2] = points[i*3+2]+0.5;
-#endif
     mData->SetPoint(i, p);
     if (mZ == -1) mZ = p[2];
-    if (p[2] != mZ) {
+    if (std::fabs(p[2] - mZ) > mTolerance) {
       DD(i);
       DD(p[2]);
       DD(mZ);
@@ -259,8 +247,17 @@ void clitk::DicomRT_Contour::SetTransformMatrix(vtkMatrix4x4* matrix)
   mTransformMatrix = matrix;
 }
 //--------------------------------------------------------------------
-
-
+//--------------------------------------------------------------------
+double clitk::DicomRT_Contour::GetTolerance()
+{
+  return mTolerance;
+}
+//--------------------------------------------------------------------
+void clitk::DicomRT_Contour::SetTolerance(double tol)
+{
+  mTolerance = tol;
+}
+//--------------------------------------------------------------------
 //--------------------------------------------------------------------
 void clitk::DicomRT_Contour::ComputeMeshFromDataPoints()
 {
@@ -271,10 +268,10 @@ void clitk::DicomRT_Contour::ComputeMeshFromDataPoints()
   mMesh->SetPoints(mPoints);
   vtkIdType ids[2];
   for (unsigned int idx=0 ; idx<mNbOfPoints ; idx++) {
-    double pointIn[4];
-    for (unsigned int j=0 ; j<3; ++j)
-      pointIn[j] = mData->GetPoint(idx)[j];
-    pointIn[3] = 1.0;
+    //double pointIn[4];
+    //for (unsigned int j=0 ; j<3; ++j)
+    //  pointIn[j] = mData->GetPoint(idx)[j];
+    //pointIn[3] = 1.0;
     /*double pointOut[4];
     mTransformMatrix->MultiplyPoint(pointIn, pointOut);
     std::cout << pointOut[0] << " " << pointOut[1] << " " << pointOut[2] << " " << pointOut[3] << std::endl;
index ab6db0d27d37565f99dc4dacb6db80e3b04a9948..389bbdd8dcb800812d6a0b391d9f6ce713b1a317 100644 (file)
@@ -56,6 +56,8 @@ public:
   vtkPoints * GetPoints() {return mData;}
   double GetZ() const {return mZ;}
   void SetTransformMatrix(vtkMatrix4x4* matrix);
+  double GetTolerance();
+  void SetTolerance(double tol);
   
   
 protected:
@@ -70,6 +72,7 @@ protected:
   bool mMeshIsUpToDate;
   ///Z location of the contour
   double mZ;
+  double mTolerance;
   
 #if GDCM_MAJOR_VERSION >= 2
   gdcm::Item * mItem;
index d8af8c313e10cbd64a5ae92d649f4001ea9f6ce9..7a2d4fcb83888d2a50e65c67b29ebaa2a31a0e5a 100644 (file)
@@ -149,7 +149,7 @@ double clitk::DicomRT_ROI::GetForegroundValueLabelImage() const
 
 //--------------------------------------------------------------------
 #if GDCM_MAJOR_VERSION >= 2
-bool clitk::DicomRT_ROI::Read(gdcm::Item * itemInfo, gdcm::Item * itemContour)
+bool clitk::DicomRT_ROI::Read(gdcm::Item * itemInfo, gdcm::Item * itemContour, double tol)
 {
   //FATAL("Error : compile vv with itk4 + external gdcm");
   // Keep dicom item
@@ -211,6 +211,7 @@ bool clitk::DicomRT_ROI::Read(gdcm::Item * itemInfo, gdcm::Item * itemContour)
     {
       gdcm::Item & j = sqi2->GetItem(i+1); // Item start at #1
       DicomRT_Contour::Pointer c = DicomRT_Contour::New();
+      c->SetTolerance(tol);
       c->SetTransformMatrix(mTransformMatrix);
       bool b = c->Read(&j);
       if (b) {
@@ -221,7 +222,7 @@ bool clitk::DicomRT_ROI::Read(gdcm::Item * itemInfo, gdcm::Item * itemContour)
   return true;
 }
 #else
-void clitk::DicomRT_ROI::Read(std::map<int, std::string> & rois, gdcm::SQItem * item)
+void clitk::DicomRT_ROI::Read(std::map<int, std::string> & rois, gdcm::SQItem * item, double tol)
 {
   // ROI number [Referenced ROI Number]
   mNumber = atoi(item->GetEntryValue(0x3006,0x0084).c_str());
@@ -238,6 +239,7 @@ void clitk::DicomRT_ROI::Read(std::map<int, std::string> & rois, gdcm::SQItem *
     int i=0;
     for(gdcm::SQItem* j=contours->GetFirstSQItem(); j!=0; j=contours->GetNextSQItem()) {
       DicomRT_Contour::Pointer c = DicomRT_Contour::New();
+      c->SetTolerance(tol);
       c->SetTransformMatrix(mTransformMatrix);
       bool b = c->Read(j);
       if (b) {
@@ -505,7 +507,7 @@ void clitk::DicomRT_ROI::ComputeContoursFromImage()
 
 //--------------------------------------------------------------------
 #if CLITK_USE_SYSTEM_GDCM == 1
-void clitk::DicomRT_ROI::Read(vtkSmartPointer<vtkGDCMPolyDataReader> & reader, int roiindex)
+void clitk::DicomRT_ROI::Read(vtkSmartPointer<vtkGDCMPolyDataReader> & reader, int roiindex, double tol)
 {
   vtkRTStructSetProperties * p = reader->GetRTStructSetProperties();
   
@@ -528,6 +530,7 @@ void clitk::DicomRT_ROI::Read(vtkSmartPointer<vtkGDCMPolyDataReader> & reader, i
   // Get the contour
   mMesh =  reader->GetOutput(roiindex);  
   DicomRT_Contour::Pointer c = DicomRT_Contour::New();
+  c->SetTolerance(tol);
   c->SetTransformMatrix(mTransformMatrix);
   c->SetMesh(mMesh); // FIXME no GetZ, not GetPoints  
   mMeshIsUpToDate = true;
index b41793323bb67b1795da94f21050f75e3ab04b68..d7c5a9817085016cdfa5cd9ff19de3c172a132f2 100644 (file)
@@ -80,14 +80,14 @@ public:
 
   // Read from DICOM RT STRUCT
 #if GDCM_MAJOR_VERSION >= 2
-  bool Read(gdcm::Item * itemInfo, gdcm::Item * itemContour);
+  bool Read(gdcm::Item * itemInfo, gdcm::Item * itemContour, double tol);
   void UpdateDicomItem();
 #else
-  void Read(std::map<int, std::string> & rois, gdcm::SQItem * item);
+  void Read(std::map<int, std::string> & rois, gdcm::SQItem * item, double tol);
 #endif
 
 #if CLITK_USE_SYSTEM_GDCM == 1
-  void Read(vtkSmartPointer<vtkGDCMPolyDataReader> & reader, int roiindex);
+  void Read(vtkSmartPointer<vtkGDCMPolyDataReader> & reader, int roiindex, double tol);
 #endif
 
 protected:
index a845ef55b97cc6a789a7c63b72bb9ce2a805a091..4b8f6f40974af634f8458e5133890c81b95ad670 100644 (file)
@@ -317,7 +317,7 @@ void clitk::DicomRT_StructureSet::Write(const std::string & filename)
 
 
 //--------------------------------------------------------------------
-void clitk::DicomRT_StructureSet::Read(const std::string & filename)
+void clitk::DicomRT_StructureSet::Read(const std::string & filename, double tol)
 {
 
 //Try to avoid to use extern GDCM library
@@ -448,7 +448,7 @@ void clitk::DicomRT_StructureSet::Read(const std::string & filename)
     // Create the roi
     mROIs[nb] = DicomRT_ROI::New();
     mROIs[nb]->SetTransformMatrix(mTransformMatrix);
-    mROIs[nb]->Read(mMapOfROIInfo[nb], mMapOfROIContours[nb]);
+    mROIs[nb]->Read(mMapOfROIInfo[nb], mMapOfROIContours[nb], tol);
   }
     
   return;
index dff4d75276aa3196dca59941661007f7da497733..16018c96be48103cf1e58299b5b5ceed79c1dbfb 100644 (file)
@@ -60,7 +60,7 @@ public:
   typedef ROIMapContainer::const_iterator ROIConstIteratorType;
 
   void Print(std::ostream & os = std::cout) const;
-  void Read(const std::string & filename);
+  void Read(const std::string & filename, double tol);
   void SetTransformMatrix(vtkMatrix4x4* matrix);
   bool IsDicomRTStruct(const std::string & filename);
   void Write(const std::string & filename);
index f75d3212267441b0ee75e2a0ffe221d00ad9066a..3fe5df2d29b7bca7685dd20159a9af0d0c1c5e68 100644 (file)
@@ -70,7 +70,7 @@ void vvImage::Reset()
 //--------------------------------------------------------------------
 
 //--------------------------------------------------------------------
-void vvImage::AddVtkImage(vtkImageData* input)
+void vvImage::AddVtkImage(vtkImageData* input, vtkSmartPointer<vtkTransform> transform)
 {
   // RP: 20/12/2011
   // Note that we're simply adding a new image to the vector.
@@ -90,6 +90,7 @@ void vvImage::AddVtkImage(vtkImageData* input)
     mImageDimension = 1;
   
   mVtkImages.push_back(input);
+  mTransform.push_back(transform);
 }
 
 //--------------------------------------------------------------------
index cbb0284ce0e925f706032825c7e8888da7744987..81c2219b3a7c23cbf74184f6d297ab1edd6f0b94 100644 (file)
@@ -47,7 +47,7 @@ public :
   void Init();
   void Reset();
   template<class TItkImageType> void AddItkImage(TItkImageType *input);
-  void AddVtkImage(vtkImageData* input);
+  void AddVtkImage(vtkImageData* input, vtkSmartPointer<vtkTransform> transform);
   const std::vector<vtkImageData*>& GetVTKImages();
   vtkImageData* GetFirstVTKImageData();
   int GetNumberOfDimensions() const;
index 614c5d96b458c4905316142bd791d34df76632ca..c2253d779546ce18c836f2da8685e91ab15c7e1f 100644 (file)
@@ -62,7 +62,11 @@ int main(int argc, char * argv[])
   NamesGeneratorType::Pointer nameGenerator = NamesGeneratorType::New();
   nameGenerator->SetUseSeriesDetails(false);
   std::string folderName=".";
+#ifdef _WIN32
+  const size_t last_slash_idx = input_files[0].rfind('\\');
+#else
   const size_t last_slash_idx = input_files[0].rfind('/');
+#endif
   if (std::string::npos != last_slash_idx)
     folderName = input_files[0].substr(0, last_slash_idx);
   nameGenerator->SetInputDirectory(folderName);
@@ -87,7 +91,7 @@ int main(int argc, char * argv[])
 #endif
   for(unsigned int i=0; i<args_info.inputs_num; i++) {
     if (args_info.verbose_flag)
-        std::cout << "Reading <" << input_files[i] << std::endl;
+        std::cout << "Reading < " << input_files[i] << std::endl;
 #if GDCM_MAJOR_VERSION >= 2
     gdcm::Reader hreader;
     hreader.SetFileName(input_files[i].c_str());
@@ -161,6 +165,16 @@ int main(int argc, char * argv[])
     std::vector<double> origin = theorigin[*sn];
     std::vector<double> instanceNumberSerie = instanceNumber[*sn];
     std::vector<std::string> files = seriesFiles[*sn];
+    //Let's process the filenames -- it is mandatory for the line "if (tempFilename == files[i])"
+    for(unsigned int i=0; i<files.size(); i++) {
+#ifdef _WIN32
+        const size_t first_slash_idx_fn = files[i].find('\\');
+#else
+        const size_t first_slash_idx_fn = files[i].find('/');
+#endif
+        if (std::string::npos != first_slash_idx_fn && first_slash_idx_fn == 1 && files[i][0] == '.')
+          files[i] = files[i].substr(first_slash_idx_fn+1);
+    }
     std::vector<int> sliceIndex(files.size());
     //clitk::GetSortedIndex(locs, sliceIndex);
     //Look for files into GDCMSeriesFileNames, because it sorts files correctly and take the order
@@ -169,10 +183,18 @@ int main(int argc, char * argv[])
       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);
+#ifdef _WIN32
+        // There is a bug on Windows, the last \ is a /...
+        // Let's substitute it
+        const size_t last_slash_idx_win = tempFilename.rfind('/');
+        tempFilename[last_slash_idx_win] = '\\';
+        const size_t first_slash_idx = tempFilename.find('\\');
+#else
+        const size_t first_slash_idx = tempFilename.find('/');
+#endif
+        if (std::string::npos != first_slash_idx && first_slash_idx == 1 && tempFilename[0] == '.')
+          tempFilename = tempFilename.substr(first_slash_idx+1);
         if (tempFilename == files[i]) {
           sliceIndex[j] = i;
           found = true;
@@ -278,7 +300,7 @@ int main(int argc, char * argv[])
       modifier->SetOutputOrigin(origin[0], origin[1], locs[sliceIndex[0]]);
       modifier->Update();
       vvImage::Pointer focal_image = vvImage::New();
-      focal_image->AddVtkImage(modifier->GetOutput());
+      focal_image->AddVtkImage(modifier->GetOutput(), image->GetTransform()[0]);
       image = focal_image;
     }
 
@@ -289,7 +311,11 @@ int main(int argc, char * argv[])
       std::ostringstream name;
       std::vector<std::string> directory = clitk::SplitFilename(args_info.output_arg);
       if (directory.size() == 2)
+#ifdef _WIN32
+        name << directory[0] << "\\" << *sn << "_" << directory[1];
+#else
         name << directory[0] << "/" << *sn << "_" << directory[1];
+#endif
       else
         name << *sn << "_" << args_info.output_arg;
       outfile = name.str();
index 3790ab7b3100e335da027148e0d797d2ba20f59a..a62cee06ce8ec4827bb921d257082f5a81b4f300 100644 (file)
 #include "clitkDicomRTStruct2Image_ggo.h"
 #include "clitkIO.h"
 
+//--------------------------------------------------------------------
+std::string outputFileName(clitk::DicomRT_ROI::Pointer roi, const args_info_clitkDicomRTStruct2Image& args_info)
+{
+  std::string name = roi->GetName();
+  int num = roi->GetROINumber();
+  name.erase(remove_if(name.begin(), name.end(), isspace), name.end());
+  std::string n;
+  n = std::string(args_info.output_arg).append(clitk::toString(num)).append("_").append(name);
+  if (args_info.mha_flag) {
+    n=n.append(".mha");
+  }
+  else if (args_info.nii_flag) {
+    n=n.append(".nii");
+  }
+  else if (args_info.niigz_flag) {
+    n=n.append(".nii.gz");
+  }
+  else {
+    n=n.append(".mhd");
+  }
+  if (args_info.verbose_flag) {
+    std::cout << num << " " << roi->GetName() << " num=" << num << " : " << n << std::endl;
+  }
+  return n;
+}
 //--------------------------------------------------------------------
 int main(int argc, char * argv[]) {
 
@@ -31,27 +56,33 @@ int main(int argc, char * argv[]) {
 
   // Read and display information
   clitk::DicomRT_StructureSet::Pointer s = clitk::DicomRT_StructureSet::New();
-  s->Read(args_info.input_arg);
+  s->Read(args_info.input_arg, args_info.tolerance_arg);
   if (args_info.verboseFile_flag) {
     s->Print(std::cout);
   }
-  
-  // New filter to convert to binary image
-  clitk::DicomRTStruct2ImageFilter filter;
-  filter.SetCropMaskEnabled(args_info.crop_flag);
-  filter.SetImageFilename(args_info.image_arg);  // Used to get spacing + origin
-  if (args_info.vtk_flag) {
-    filter.SetWriteMesh(true);
-  }
-  if (args_info.roiName_given) {
-    filter.SetROI(s->GetROIFromROIName(args_info.roiName_arg)); 
-    filter.SetOutputImageFilename(args_info.output_arg);
-    filter.Update();  
-  }
-  else if (args_info.roi_given && args_info.roi_arg != -1) {
-    filter.SetROI(s->GetROIFromROINumber(args_info.roi_arg)); 
-    filter.SetOutputImageFilename(args_info.output_arg);
-    filter.Update();  
+  if (args_info.roiName_given || (args_info.roi_given && args_info.roi_arg != -1)) {
+    clitk::DicomRT_ROI::Pointer roi;
+    if (args_info.roiName_given) {
+      roi = s->GetROIFromROIName(args_info.roiName_arg);
+    }
+    else if (args_info.roi_given && args_info.roi_arg != -1) {
+        roi = s->GetROIFromROINumber(args_info.roi_arg);
+    }
+    if (roi) {
+      // New filter to convert to binary image
+      clitk::DicomRTStruct2ImageFilter filter;
+      filter.SetCropMaskEnabled(args_info.crop_flag);
+      filter.SetImageFilename(args_info.image_arg);  // Used to get spacing + origin
+      if (args_info.vtk_flag) {
+        filter.SetWriteMesh(true);
+      }
+      filter.SetROI(roi);
+      filter.SetOutputImageFilename(outputFileName(roi, args_info));
+      filter.Update();
+      } else {
+        std::cerr<<"No ROI with this name/id"<<std::endl;
+          return EXIT_FAILURE;
+      }
   }
   else {
     clitk::DicomRT_StructureSet::ROIMapContainer* rois;
@@ -65,36 +96,18 @@ int main(int argc, char * argv[]) {
       for(iter = rois->begin(); iter != rois->end(); iter++) {
         clitk::DicomRT_ROI::Pointer roi = iter->second;
         clitk::DicomRTStruct2ImageFilter filter;
-        std::string name = roi->GetName();
-        int num = roi->GetROINumber();
-        filter.SetROI(roi); 
         filter.SetCropMaskEnabled(args_info.crop_flag);
         filter.SetImageFilename(args_info.image_arg);  // Used to get spacing + origin
         if (args_info.vtk_flag) {
           filter.SetWriteMesh(true);
         }
-        name.erase(remove_if(name.begin(), name.end(), isspace), name.end());
-        std::string n;
-        if (args_info.mha_flag) {
-          n = std::string(args_info.output_arg).append
-            (clitk::toString(num)).append
-            ("_").append
-            (name).append
-            (".mha");
-        }
-        else {
-          n = std::string(args_info.output_arg).append
-            (clitk::toString(num)).append
-            ("_").append
-            (name).append
-            (".mhd");
-        }
-        if (args_info.verbose_flag) {
-          std::cout << num << " " << roi->GetName() << " num=" << num << " : " << n << std::endl;
-        }
-        filter.SetOutputImageFilename(n);
-        filter.Update();  
+        filter.SetROI(roi);
+        filter.SetOutputImageFilename(outputFileName(roi, args_info));
+        filter.Update();
       }
+    } else {
+        std::cerr<<"No ROIs with this substring of ROI name"<<std::endl;
+        return EXIT_FAILURE;
     }
   }
 //   else {
@@ -144,5 +157,5 @@ int main(int argc, char * argv[]) {
   //}
 
   // This is the end my friend 
-  return 0;
+  return EXIT_SUCCESS;
 }
index 8e6159a16ff837ef4148d14193d27017db2abe4a..861f31346b257bebf51d005a8871ca62ab2b5d70 100644 (file)
@@ -9,13 +9,16 @@ option "verboseFile"  - "Verbose file content"
 option "input"        i "Input Dicom file"                                                      string  yes
 option "image"        j "Used to read image info (spacing, origin)"                             string  yes
 option "output"       o "Output image base filename (roi number and extension will be append)"  string  yes
+option "tolerance"    t "Tolerance for slice position"                                          double  no  default="0"
 
-defgroup "ROIoption" groupdesc="an option of this group is required" 
-groupoption "roi"           r "ROI to binarize (if -1 = all roi)"                                                             int     no default="-1" group="ROIoption"
-groupoption "roiName"       n "ROI name to binarize (be wary of spaces in ROI names; if blank, use given 'roi' value)"        string  no default=""   group="ROIoption"
-groupoption "roiNameSubstr" s "Substring of ROI name to binarize (reuturns all matches; if blank, use given 'roiName' value)" string  no default=""   group="ROIoption"
-
+text "\nOutput options - the default output format is mhd"
 option "crop"         c "Crop binary mask"                                                      flag off
 option "mha"          - "Write the RTStruct as a mha image to avoid special character problems" flag off
+option "nii"          - "Write the RTStruct as a nii image"                                     flag off
+option "niigz"        - "Write the RTStruct as a gzipped nii image"                             flag off
 option "vtk"          - "Write the vtk Mesh as a vtk file"                                      flag off
 
+defgroup "ROI option" groupdesc="an option of this group is required"
+groupoption "roi"           r "ROI number to binarize (if -1 = all roi)"                                                      int     no default="-1" group="ROI option"
+groupoption "roiName"       n "ROI name to binarize (be wary of spaces in ROI names; if blank, use given 'roi' value)"        string  no default=""   group="ROI option"
+groupoption "roiNameSubstr" s "Substring of ROI name to binarize (returns all matches; if blank, use given 'roiName' value)"  string  no default=""   group="ROI option"
index 00eff1df1472e45fef50c19338c488d03c4eacc2..1eb7d4813e6abd28a53a47b28386ee6b7b43d989 100644 (file)
@@ -330,7 +330,7 @@ void vvToolROIManager::SelectedImageHasChanged(vvSlicerManager * m)
 void vvToolROIManager::Open()
 {
   // Open images
-  QString Extensions = "Images or Dicom-Struct files ( *.mha *.mhd *.hdr *.his *.dcm RS*)";
+  QString Extensions = "Images or Dicom-Struct files (*.nii *.nii.gz *.mha *.mhd *.hdr *.his *.dcm RS*)";
   Extensions += ";;All Files (*)";
   QStringList filename =
     QFileDialog::getOpenFileNames(this,tr("Open binary image or DICOM RT Struct"),
@@ -392,7 +392,7 @@ void vvToolROIManager::OpenBinaryImage(QStringList & filename)
 
 
 //------------------------------------------------------------------------------
-void vvToolROIManager::OpenDicomImage(std::string filename)
+void vvToolROIManager::OpenDicomImage(std::string filename, double tol)
 {
   // GUI selector of roi
   vvMeshReader reader;
@@ -412,7 +412,7 @@ void vvToolROIManager::OpenDicomImage(std::string filename)
     vtkSmartPointer<vtkMatrix4x4> transformMatrix = vtkSmartPointer<vtkMatrix4x4>::New();
     transformMatrix = mCurrentImage->GetTransform()[0]->GetMatrix();
     s->SetTransformMatrix(transformMatrix);
-    s->Read(filename);
+    s->Read(filename, tol);
 
     // Loop on selected struct
     std::vector<int> list = selector.getSelectedItems();
@@ -428,7 +428,7 @@ void vvToolROIManager::OpenDicomImage(std::string filename)
 
       // Get image
       vvImage::Pointer binaryImage = vvImage::New();
-      binaryImage->AddVtkImage(filter.GetOutput());
+      binaryImage->AddVtkImage(filter.GetOutput(), mCurrentImage->GetTransform()[0]);
 
       // Add to gui
       AddImage(binaryImage, s->GetROIFromROINumber(list[i])->GetName(), "", 0, true); // "" = no filename
index db630c641b059c4838a376d7bdfdf380a70d4fd5..6ca20e9ad10bcbeb87e9e1fb0498411175fac478 100644 (file)
@@ -63,7 +63,7 @@ class vvToolROIManager:
   void SelectedImageHasChanged(vvSlicerManager *);
   void Open();
   void OpenBinaryImage(QStringList & filenames);
-  void OpenDicomImage(std::string filaneme);
+  void OpenDicomImage(std::string filaneme, double tol=0);
   void SelectedItemChangedInTree();
   void VisibleROIToggled(bool b);
   void VisibleContourROIToggled(bool b);