]> Creatis software - clitk.git/commitdiff
Merge branch 'master' of git://git.creatis.insa-lyon.fr/clitk
authorBenoît Presles <benoit.presles@netcourrier.com>
Fri, 1 Jun 2012 07:39:23 +0000 (09:39 +0200)
committerBenoît Presles <benoit.presles@netcourrier.com>
Fri, 1 Jun 2012 07:39:23 +0000 (09:39 +0200)
28 files changed:
common/clitkGateAsciiImageIO.cxx
common/clitkGateAsciiImageIO.h
common/clitkImageToImageGenericFilterBase.cxx
common/clitkMemoryUsage.cxx
common/clitkXdrImageIOWriter.cxx
itk/clitkBackProjectImageFilter.h
itk/clitkBackProjectImageFilter.txx
itk/clitkExtractImageFilter.h
itk/clitkExtractImageFilter.txx
registration/clitkExtractImageFilter.h [deleted file]
registration/clitkExtractImageFilter.txx [deleted file]
scripts/CMakeLists.txt
scripts/calculate_contour_stats.sh
scripts/calculate_motion_amplitude.sh
scripts/compress_mhd.sh [new file with mode: 0755]
scripts/create_mhd_4D.sh
scripts/create_midP_masks-2.0.sh
scripts/midp_common.sh
segmentation/clitkMotionMask.ggo
segmentation/clitkMotionMaskGenericFilter.h
segmentation/clitkMotionMaskGenericFilter.txx
tools/clitkBackProjectImage.ggo
tools/clitkBackProjectImageGenericFilter.txx
tools/clitkImageConvertGenericFilter.cxx
tools/clitkImageConvertGenericFilter.h
vv/vvSlicer.cxx
vv/vvSlicer.h
vv/vvSlicerManager.cxx

index 589c30cfb783b0a9d0ae7d43a1a3609e1a7d8a8b..99520ee4241268c4a089712881fbfde4508e809e 100644 (file)
@@ -252,9 +252,49 @@ void clitk::GateAsciiImageIO::Write(const void* abstract_buffer)
   stream << "# nbVal      = " << nb_value << endl;
   stream << "######################" << endl;
 
-  const double* buffer = static_cast<const double*>(abstract_buffer);
-  for (unsigned long kk=0; kk<nb_value; kk++) {
-    stream << buffer[kk] << endl;
+  if(this->GetComponentType()==itk::ImageIOBase::UCHAR) {
+    const unsigned char* buffer = static_cast<const unsigned char*>(abstract_buffer);
+    for (unsigned long kk=0; kk<nb_value; kk++)
+      stream << buffer[kk] << endl;
+  } else if(this->GetComponentType()==itk::ImageIOBase::CHAR) {
+    const char* buffer = static_cast<const char*>(abstract_buffer);
+    for (unsigned long kk=0; kk<nb_value; kk++)
+      stream << buffer[kk] << endl;
+  } else if(this->GetComponentType()==itk::ImageIOBase::USHORT) {
+    const unsigned short* buffer = static_cast<const unsigned short*>(abstract_buffer);
+    for (unsigned long kk=0; kk<nb_value; kk++)
+      stream << buffer[kk] << endl;
+  } else if(this->GetComponentType()==itk::ImageIOBase::SHORT) {
+    const short* buffer = static_cast<const short*>(abstract_buffer);
+    for (unsigned long kk=0; kk<nb_value; kk++)
+      stream << buffer[kk] << endl;
+  } else if(this->GetComponentType()==itk::ImageIOBase::UINT) {
+    const unsigned int* buffer = static_cast<const unsigned int*>(abstract_buffer);
+    for (unsigned long kk=0; kk<nb_value; kk++)
+      stream << buffer[kk] << endl;
+  } else if(this->GetComponentType()==itk::ImageIOBase::INT) {
+    const int* buffer = static_cast<const int*>(abstract_buffer);
+    for (unsigned long kk=0; kk<nb_value; kk++)
+      stream << buffer[kk] << endl;
+  } else if(this->GetComponentType()==itk::ImageIOBase::ULONG) {
+    const unsigned long* buffer = static_cast<const unsigned long*>(abstract_buffer);
+    for (unsigned long kk=0; kk<nb_value; kk++)
+      stream << buffer[kk] << endl;
+  } else if(this->GetComponentType()==itk::ImageIOBase::LONG) {
+    const long* buffer = static_cast<const long*>(abstract_buffer);
+    for (unsigned long kk=0; kk<nb_value; kk++)
+      stream << buffer[kk] << endl;
+  } else if(this->GetComponentType()==itk::ImageIOBase::FLOAT) {
+    const float* buffer = static_cast<const float*>(abstract_buffer);
+    for (unsigned long kk=0; kk<nb_value; kk++)
+      stream << buffer[kk] << endl;
+  } else if(this->GetComponentType()==itk::ImageIOBase::DOUBLE) {
+    const double* buffer = static_cast<const double*>(abstract_buffer);
+    for (unsigned long kk=0; kk<nb_value; kk++)
+      stream << buffer[kk] << endl;
+  } else {
+    itkGenericExceptionMacro(<< "Unhandled pixel type: " << this->GetComponentTypeAsString(this->GetComponentType()));
+    return;
   }
 
   FILE* handle = fopen(m_FileName.c_str(),"w");
@@ -264,6 +304,5 @@ void clitk::GateAsciiImageIO::Write(const void* abstract_buffer)
   }
 
   fwrite(stream.str().c_str(),1,stream.str().size(),handle);
-
   fclose(handle);
 }
index 7d174f82ed01e164ef3d9d241af455b046f00428..7d134de7030ac61afdea880fde62abb2d74dd92a 100644 (file)
@@ -42,7 +42,6 @@ public:
   typedef GateAsciiImageIO        Self;
   typedef itk::ImageIOBase        Superclass;
   typedef itk::SmartPointer<Self> Pointer;
-  typedef signed short int        PixelType;
 
   struct GateAsciiHeader {
     double matrix_size[3];
index 8a713d2b8d0190cece7b01752a145335eb81978d..9db15b0902513c78b26992e788f43ac4cae18381 100644 (file)
@@ -306,6 +306,58 @@ DEF_SetNextOutput_And_GetInput(int, 3);
 DEF_SetNextOutput_And_GetInput(float, 3);
 DEF_SetNextOutput_And_GetInput(double, 3);
 
+/*
+DEF_SetNextOutput_And_GetInput_WithCompo(unsigned char, 2, 2);
+DEF_SetNextOutput_And_GetInput_WithCompo(unsigned char, 2, 3);
+DEF_SetNextOutput_And_GetInput_WithCompo(unsigned char, 2, 4);
+DEF_SetNextOutput_And_GetInput_WithCompo(unsigned char, 3, 2);
+DEF_SetNextOutput_And_GetInput_WithCompo(unsigned char, 3, 3);
+DEF_SetNextOutput_And_GetInput_WithCompo(unsigned char, 3, 4);
+DEF_SetNextOutput_And_GetInput_WithCompo(unsigned char, 4, 2);
+DEF_SetNextOutput_And_GetInput_WithCompo(unsigned char, 4, 3);
+DEF_SetNextOutput_And_GetInput_WithCompo(unsigned char, 4, 4);
+
+DEF_SetNextOutput_And_GetInput_WithCompo(char, 2, 2);
+DEF_SetNextOutput_And_GetInput_WithCompo(char, 2, 3);
+DEF_SetNextOutput_And_GetInput_WithCompo(char, 2, 4);
+DEF_SetNextOutput_And_GetInput_WithCompo(char, 3, 2);
+DEF_SetNextOutput_And_GetInput_WithCompo(char, 3, 3);
+DEF_SetNextOutput_And_GetInput_WithCompo(char, 3, 4);
+DEF_SetNextOutput_And_GetInput_WithCompo(char, 4, 2);
+DEF_SetNextOutput_And_GetInput_WithCompo(char, 4, 3);
+DEF_SetNextOutput_And_GetInput_WithCompo(char, 4, 4);
+
+DEF_SetNextOutput_And_GetInput_WithCompo(unsigned short, 2, 2);
+DEF_SetNextOutput_And_GetInput_WithCompo(unsigned short, 2, 3);
+DEF_SetNextOutput_And_GetInput_WithCompo(unsigned short, 2, 4);
+DEF_SetNextOutput_And_GetInput_WithCompo(unsigned short, 3, 2);
+DEF_SetNextOutput_And_GetInput_WithCompo(unsigned short, 3, 3);
+DEF_SetNextOutput_And_GetInput_WithCompo(unsigned short, 3, 4);
+DEF_SetNextOutput_And_GetInput_WithCompo(unsigned short, 4, 2);
+DEF_SetNextOutput_And_GetInput_WithCompo(unsigned short, 4, 3);
+DEF_SetNextOutput_And_GetInput_WithCompo(unsigned short, 4, 4);
+
+DEF_SetNextOutput_And_GetInput_WithCompo(short, 2, 2);
+DEF_SetNextOutput_And_GetInput_WithCompo(short, 2, 3);
+DEF_SetNextOutput_And_GetInput_WithCompo(short, 2, 4);
+DEF_SetNextOutput_And_GetInput_WithCompo(short, 3, 2);
+DEF_SetNextOutput_And_GetInput_WithCompo(short, 3, 3);
+DEF_SetNextOutput_And_GetInput_WithCompo(short, 3, 4);
+DEF_SetNextOutput_And_GetInput_WithCompo(short, 4, 2);
+DEF_SetNextOutput_And_GetInput_WithCompo(short, 4, 3);
+DEF_SetNextOutput_And_GetInput_WithCompo(short, 4, 4);
+
+DEF_SetNextOutput_And_GetInput_WithCompo(int, 2, 2);
+DEF_SetNextOutput_And_GetInput_WithCompo(int, 2, 3);
+DEF_SetNextOutput_And_GetInput_WithCompo(int, 2, 4);
+DEF_SetNextOutput_And_GetInput_WithCompo(int, 3, 2);
+DEF_SetNextOutput_And_GetInput_WithCompo(int, 3, 3);
+DEF_SetNextOutput_And_GetInput_WithCompo(int, 3, 4);
+DEF_SetNextOutput_And_GetInput_WithCompo(int, 4, 2);
+DEF_SetNextOutput_And_GetInput_WithCompo(int, 4, 3);
+DEF_SetNextOutput_And_GetInput_WithCompo(int, 4, 4);
+*/
+
 DEF_SetNextOutput_And_GetInput_WithCompo(float, 2, 2);
 DEF_SetNextOutput_And_GetInput_WithCompo(float, 2, 3);
 DEF_SetNextOutput_And_GetInput_WithCompo(float, 2, 4);
index c0b78ce4ddee203a40a0e216a1ffca69d80d0af9..e2a095dab5e080dae4e058b2517be8233c450a45 100644 (file)
@@ -19,7 +19,9 @@
 // clitk include
 #include "clitkCommon.h"
 #include "clitkMemoryUsage.h"
-#include <unistd.h>
+#ifndef _WIN32
+#  include <unistd.h>
+#endif
 
 void clitk::PrintMemory(bool verbose, std::string s) 
 {
index 1e826db7d6ab07b49142085d84d2ce6180069fba..af50b0ea0dfe3399c3eec82424f810c1dc2f9e5f 100644 (file)
@@ -97,7 +97,9 @@ void clitk::XdrImageIO::Write(const void* buffer)
 #include <math.h>
 #include <stdlib.h>
 #include <limits.h>
-#include <unistd.h>
+#ifndef _WIN32
+#  include <unistd.h>
+#endif
 #if !defined(unix) && !defined(__APPLE__)
 #include <io.h>
 #endif
index 7de71a116111326f2bed06060af31bc165a6ecb5..689e67852d0bf3fd5bd93d32ff0493dbc6d42ab7 100644 (file)
@@ -242,7 +242,11 @@ namespace clitk
     void BeforeThreadedGenerateData(void );
   
     // Threaded Generate Data
+#if ITK_VERSION_MAJOR >= 4
+    void ThreadedGenerateData(const OutputImageRegionType & outputRegionForThread, itk::ThreadIdType threadId );
+#else
     void ThreadedGenerateData(const OutputImageRegionType & outputRegionForThread, int threadId );
+#endif
 
  
     //------------------------------------------------
index c07033602c188e1075bd931bf69991727f25083b..b1f84e260426db6becc2a0261be699742ee759da 100644 (file)
@@ -303,7 +303,11 @@ namespace clitk
   template <class InputImageType, class OutputImageType>
   void 
   BackProjectImageFilter<InputImageType, OutputImageType>
+#if ITK_VERSION_MAJOR >= 4
+  ::ThreadedGenerateData( const OutputImageRegionType & outputRegionForThread,  itk::ThreadIdType threadId )
+#else
   ::ThreadedGenerateData( const OutputImageRegionType & outputRegionForThread,  int threadId )
+#endif
   {
     //Projection pointer
     InputImageConstPointer inputPtr=this->GetInput();
index 7ea101adc2edbaba0f74e4f9becaa6be367b9b13..ce31fd9c915ebdb12f552f8e58809b312ba26463 100644 (file)
@@ -94,8 +94,12 @@ protected:
                                                  const OutputImageRegionType &srcRegion);
 
 
-  void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread,
-                            int threadId );
+#if ITK_VERSION_MAJOR >= 4
+  void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, itk::ThreadIdType threadId );
+#else
+  void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, int threadId );
+#endif
+
   InputImageRegionType m_ExtractionRegion;
   OutputImageRegionType m_OutputImageRegion;
 
index 236a7cb0c1d3178eaa29eb999a264f79f99d3190..90fee3bbd49f312a120373da966ae0bbc845b5cf 100644 (file)
@@ -236,8 +236,11 @@ ExtractImageFilter<TInputImage,TOutputImage>
 template <class TInputImage, class TOutputImage>
 void 
 ExtractImageFilter<TInputImage,TOutputImage>
-::ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread,
-                       int threadId)
+#if ITK_VERSION_MAJOR >= 4
+::ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, itk::ThreadIdType threadId)
+#else
+::ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, int threadId)
+#endif
 {
   itkDebugMacro(<<"Actually executing");
 
diff --git a/registration/clitkExtractImageFilter.h b/registration/clitkExtractImageFilter.h
deleted file mode 100644 (file)
index 1e797bc..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-/*=========================================================================
-  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
-
-  Authors belong to: 
-  - University of LYON              http://www.universite-lyon.fr/
-  - Léon Bérard cancer center       http://www.centreleonberard.fr
-  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
-
-  This software is distributed WITHOUT ANY WARRANTY; without even
-  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-  PURPOSE.  See the copyright notices for more information.
-
-  It is distributed under dual licence
-
-  - BSD        See included LICENSE.txt file
-  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
-===========================================================================**/
-#ifndef __clitkExtractImageFilter_h
-#define __clitkExtractImageFilter_h
-#include "itkImageToImageFilter.h"
-#include "itkSmartPointer.h"
-#include "itkExtractImageFilterRegionCopier.h"
-
-namespace clitk
-{
-
-template <class TInputImage, class TOutputImage>
-class ITK_EXPORT ExtractImageFilter:
-    public itk::ImageToImageFilter<TInputImage,TOutputImage>
-{
-public:
-  /** Standard class typedefs. */
-  typedef ExtractImageFilter         Self;
-  typedef itk::ImageToImageFilter<TInputImage,TOutputImage>  Superclass;
-  typedef itk::SmartPointer<Self>  Pointer;
-  typedef itk::SmartPointer<const Self>  ConstPointer;
-
-  /** Method for creation through the object factory. */
-  itkNewMacro(Self);  
-
-  /** Run-time type information (and related methods). */
-  itkTypeMacro(ExtractImageFilter, ImageToImageFilter);
-
-  /** Image type information. */
-  typedef TInputImage  InputImageType;
-  typedef TOutputImage OutputImageType;
-
-  /** Typedef to describe the output and input image region types. */
-  typedef typename TOutputImage::RegionType OutputImageRegionType;
-  typedef typename TInputImage::RegionType InputImageRegionType;
-
-  /** Typedef to describe the type of pixel. */
-  typedef typename TOutputImage::PixelType OutputImagePixelType;
-  typedef typename TInputImage::PixelType InputImagePixelType;
-
-  /** Typedef to describe the output and input image index and size types. */
-  typedef typename TOutputImage::IndexType OutputImageIndexType;
-  typedef typename TInputImage::IndexType InputImageIndexType;
-  typedef typename TOutputImage::SizeType OutputImageSizeType;
-  typedef typename TInputImage::SizeType InputImageSizeType;
-
-  /** ImageDimension enumeration */
-  itkStaticConstMacro(InputImageDimension, unsigned int,
-                      TInputImage::ImageDimension);
-  itkStaticConstMacro(OutputImageDimension, unsigned int,
-                      TOutputImage::ImageDimension);
-
-  typedef itk::ImageToImageFilterDetail::ExtractImageFilterRegionCopier<
-    itkGetStaticConstMacro(InputImageDimension), 
-    itkGetStaticConstMacro(OutputImageDimension)> ExtractImageFilterRegionCopierType;
-
-  void SetExtractionRegion(InputImageRegionType extractRegion);
-  itkGetMacro(ExtractionRegion, InputImageRegionType);
-
-#ifdef ITK_USE_CONCEPT_CHECKING
-  /** Begin concept checking */
-  itkConceptMacro(InputCovertibleToOutputCheck,
-                 (itk::Concept::Convertible<InputImagePixelType, OutputImagePixelType>));
-  /** End concept checking */
-#endif
-
-protected:
-  ExtractImageFilter();
-  ~ExtractImageFilter() {};
-  void PrintSelf(std::ostream& os, itk::Indent indent) const;
-
-
-  virtual void GenerateOutputInformation();
-
-
-  virtual void CallCopyOutputRegionToInputRegion(InputImageRegionType &destRegion,
-                                                 const OutputImageRegionType &srcRegion);
-
-
-  void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread,
-                            int threadId );
-  InputImageRegionType m_ExtractionRegion;
-  OutputImageRegionType m_OutputImageRegion;
-
-private:
-  ExtractImageFilter(const Self&); //purposely not implemented
-  void operator=(const Self&); //purposely not implemented
-  
-};
-
-  
-} // end namespace itk
-  
-#ifndef ITK_MANUAL_INSTANTIATION
-#include "clitkExtractImageFilter.txx"
-#endif
-  
-#endif
diff --git a/registration/clitkExtractImageFilter.txx b/registration/clitkExtractImageFilter.txx
deleted file mode 100644 (file)
index d321f9e..0000000
+++ /dev/null
@@ -1,274 +0,0 @@
-/*=========================================================================
-  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
-
-  Authors belong to: 
-  - University of LYON              http://www.universite-lyon.fr/
-  - Léon Bérard cancer center       http://www.centreleonberard.fr
-  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
-
-  This software is distributed WITHOUT ANY WARRANTY; without even
-  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-  PURPOSE.  See the copyright notices for more information.
-
-  It is distributed under dual licence
-
-  - BSD        See included LICENSE.txt file
-  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
-===========================================================================**/
-#ifndef _clitkExtractImageFilter_txx
-#define _clitkExtractImageFilter_txx
-#include "clitkExtractImageFilter.h"
-#include "itkImageRegionIterator.h"
-#include "itkImageRegionConstIterator.h"
-#include "itkObjectFactory.h"
-#include "itkExtractImageFilterRegionCopier.h"
-#include "itkProgressReporter.h"
-
-
-namespace clitk
-{
-
-/**
- *
- */
-template <class TInputImage, class TOutputImage>
-ExtractImageFilter<TInputImage,TOutputImage>
-::ExtractImageFilter() 
-{
-}
-
-
-/**
- *
- */
-template <class TInputImage, class TOutputImage>
-void 
-ExtractImageFilter<TInputImage,TOutputImage>
-::PrintSelf(std::ostream& os, itk::Indent indent) const
-{
-  Superclass::PrintSelf(os,indent);
-
-  os << indent << "ExtractionRegion: " << m_ExtractionRegion << std::endl;
-  os << indent << "OutputImageRegion: " << m_OutputImageRegion << std::endl;
-}
-
-
-template<class TInputImage, class TOutputImage>
-void 
-ExtractImageFilter<TInputImage,TOutputImage>
-::CallCopyOutputRegionToInputRegion(InputImageRegionType &destRegion,
-                                    const OutputImageRegionType &srcRegion)
-{
-  ExtractImageFilterRegionCopierType extractImageRegionCopier;
-  extractImageRegionCopier(destRegion, srcRegion, m_ExtractionRegion);
-}
-
-
-template <class TInputImage, class TOutputImage>
-void 
-ExtractImageFilter<TInputImage,TOutputImage>
-::SetExtractionRegion(InputImageRegionType extractRegion)
-{
-  m_ExtractionRegion = extractRegion;
-
-  unsigned int nonzeroSizeCount = 0;
-  InputImageSizeType inputSize = extractRegion.GetSize();
-  OutputImageSizeType outputSize;
-  OutputImageIndexType outputIndex;
-
-  /**
-   * check to see if the number of non-zero entries in the extraction region
-   * matches the number of dimensions in the output image.  
-   **/
-  for (unsigned int i = 0; i < InputImageDimension; ++i)
-    {
-    if (inputSize[i])
-      { 
-      outputSize[nonzeroSizeCount] = inputSize[i];    
-      outputIndex[nonzeroSizeCount] = extractRegion.GetIndex()[i];
-      nonzeroSizeCount++;
-      }
-    }
-    
-  if (nonzeroSizeCount != OutputImageDimension)
-    {
-    itkExceptionMacro("Extraction Region not consistent with output image");
-    }
-
-  m_OutputImageRegion.SetSize(outputSize);
-  m_OutputImageRegion.SetIndex(outputIndex);
-  this->Modified();
-}
-
-
-
-/** 
- * ExtractImageFilter can produce an image which is a different resolution
- * than its input image.  As such, ExtractImageFilter needs to provide an
- * implementation for GenerateOutputInformation() in order to inform
- * the pipeline execution model.  The original documentation of this
- * method is below.
- *
- * \sa ProcessObject::GenerateOutputInformaton() 
- */
-template <class TInputImage, class TOutputImage>
-void 
-ExtractImageFilter<TInputImage,TOutputImage>
-::GenerateOutputInformation()
-{
-  // do not call the superclass' implementation of this method since
-  // this filter allows the input and the output to be of different dimensions
-  // get pointers to the input and output
-  typename Superclass::OutputImagePointer      outputPtr = this->GetOutput();
-  typename Superclass::InputImageConstPointer  inputPtr  = this->GetInput();
-
-  if ( !outputPtr || !inputPtr)
-    {
-    return;
-    }
-
-  // Set the output image size to the same value as the extraction region.
-  outputPtr->SetLargestPossibleRegion( m_OutputImageRegion );
-
-  // Set the output spacing and origin
-  const itk::ImageBase<InputImageDimension> *phyData;
-
-  phyData
-    = dynamic_cast<const itk::ImageBase<InputImageDimension>*>(this->GetInput());
-
-  if (phyData)
-    {
-    // Copy what we can from the image from spacing and origin of the input
-    // This logic needs to be augmented with logic that select which
-    // dimensions to copy
-
-    unsigned int i;
-    const typename InputImageType::SpacingType& 
-      inputSpacing = inputPtr->GetSpacing();
-    const typename InputImageType::DirectionType&
-      inputDirection = inputPtr->GetDirection();
-    const typename InputImageType::PointType&
-      inputOrigin = inputPtr->GetOrigin();
-
-    typename OutputImageType::SpacingType outputSpacing;
-    typename OutputImageType::DirectionType outputDirection;
-    typename OutputImageType::PointType outputOrigin;
-
-    if ( static_cast<unsigned int>(OutputImageDimension) > 
-         static_cast<unsigned int>(InputImageDimension )    )
-      {
-      // copy the input to the output and fill the rest of the
-      // output with zeros.
-      for (i=0; i < InputImageDimension; ++i)
-        {
-        outputSpacing[i] = inputSpacing[i];
-        outputOrigin[i] = inputOrigin[i];
-        for (unsigned int dim = 0; dim < InputImageDimension; ++dim)
-          {
-          outputDirection[i][dim] = inputDirection[i][dim];
-          }
-        }
-      for (; i < OutputImageDimension; ++i)
-        {
-        outputSpacing[i] = 1.0;
-        outputOrigin[i] = 0.0;
-        for (unsigned int dim = 0; dim < InputImageDimension; ++dim)
-          {
-          outputDirection[i][dim] = 0.0;
-          }
-        outputDirection[i][i] = 1.0;
-        }
-      }
-    else
-      {
-      // copy the non-collapsed part of the input spacing and origing to the output
-      int nonZeroCount = 0;
-      for (i=0; i < InputImageDimension; ++i)
-        {
-        if (m_ExtractionRegion.GetSize()[i])
-          {
-          outputSpacing[nonZeroCount] = inputSpacing[i];
-          outputOrigin[nonZeroCount] = inputOrigin[i];
-          int nonZeroCount2 = 0;
-          for (unsigned int dim = 0; dim < InputImageDimension; ++dim)
-            {
-            if (m_ExtractionRegion.GetSize()[dim])
-              {
-              outputDirection[nonZeroCount][nonZeroCount2] =
-                inputDirection[i][dim];
-              ++nonZeroCount2;
-              }
-            }
-          nonZeroCount++;
-          }
-        }
-      }
-
-    // set the spacing and origin
-    outputPtr->SetSpacing( outputSpacing );
-    outputPtr->SetDirection( outputDirection );
-    outputPtr->SetOrigin( outputOrigin );
-    outputPtr->SetNumberOfComponentsPerPixel(inputPtr->GetNumberOfComponentsPerPixel() );
-    }
-  else
-    {
-    // pointer could not be cast back down
-    itkExceptionMacro(<< "itk::ExtractImageFilter::GenerateOutputInformation "
-                      << "cannot cast input to "
-                      << typeid(itk::ImageBase<InputImageDimension>*).name() );
-    }
-}
-
-/** 
-   * ExtractImageFilter can be implemented as a multithreaded filter.
-   * Therefore, this implementation provides a ThreadedGenerateData()
-   * routine which is called for each processing thread. The output
-   * image data is allocated automatically by the superclass prior to
-   * calling ThreadedGenerateData().  ThreadedGenerateData can only
-   * write to the portion of the output image specified by the
-   * parameter "outputRegionForThread"
-   *
-   * \sa ImageToImageFilter::ThreadedGenerateData(),
-   *     ImageToImageFilter::GenerateData() 
-   */
-template <class TInputImage, class TOutputImage>
-void 
-ExtractImageFilter<TInputImage,TOutputImage>
-::ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread,
-                       int threadId)
-{
-  itkDebugMacro(<<"Actually executing");
-
-  // Get the input and output pointers
-  typename Superclass::InputImageConstPointer  inputPtr = this->GetInput();
-  typename Superclass::OutputImagePointer outputPtr = this->GetOutput();
-
-  // support progress methods/callbacks
- itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());
-  
-  // Define the portion of the input to walk for this thread
-  InputImageRegionType inputRegionForThread;
-  this->CallCopyOutputRegionToInputRegion(inputRegionForThread, outputRegionForThread);
-  
-  // Define the iterators.
-  typedef itk::ImageRegionIterator<TOutputImage> OutputIterator;
-  typedef itk::ImageRegionConstIterator<TInputImage> InputIterator;
-
-  OutputIterator outIt(outputPtr, outputRegionForThread);
-  InputIterator inIt(inputPtr, inputRegionForThread);
-
-  // walk the output region, and sample the input image
-  while( !outIt.IsAtEnd() )
-    {
-    // copy the input pixel to the output
-    outIt.Set( static_cast<OutputImagePixelType>(inIt.Get()));
-    ++outIt; 
-    ++inIt; 
-    progress.CompletedPixel();
-    }
-}
-
-} // end namespace clitk
-
-#endif
index 41ace96169479bccee3194a87a0bd1c6633d45b8..6c444dc0864fe86381cc459fc919dcb8c5b98770 100644 (file)
@@ -5,6 +5,7 @@ SET(SCRIPTS
   ${CLITK_SOURCE_DIR}/scripts/calculate_contour_stats.sh
   ${CLITK_SOURCE_DIR}/scripts/midp_common.sh
   ${CLITK_SOURCE_DIR}/scripts/registration.sh
+  ${CLITK_SOURCE_DIR}/scripts/compress_mhd.sh
   ${CLITK_SOURCE_DIR}/scripts/create_midP.sh
   ${CLITK_SOURCE_DIR}/scripts/create_midP-2.0.sh        
   ${CLITK_SOURCE_DIR}/scripts/create_mhd_4D.sh          
index b15caa8011d673ebef63b756b70538a1b45edecd..be10e9dfc96d7e1c22495070bdbeeb14bf4fa1aa 100755 (executable)
@@ -1,94 +1,51 @@
 #! /bin/bash +x 
 
-select_contour_gui()
-{
-  local roi_list=$@
-  roi=`zenity --list --title="Available Contours" --column="Please choose a contour:" $roi_list`
-  case $? in
-    0)
-    if [ -z $roi ]
-    then
-      zenity --warning --text="You must choose one contour."
-      select_contour $roi_list
-    else
-      rtstruct_roi_name=$roi
-    fi;;
-    1)
-    if zenity --question --text="Do you really wish to quit?"
-    then
-      exit
-    else
-      select_contour $roi_list
-    fi;;
-    -1)
-      zenity --error --text="Unexpected error. Please relaunch the application."
-      exit;;
-  esac
-}
+source `dirname $0`/midp_common.sh
 
-select_contour()
-{
-  local roi_list=$@
-  echo "Available Contours:" 
-  for r in $roi_list; do
-    echo $r
-  done
-
-  echo "Please choose a contour number:"
-  read rtstruct_roi_number
-}
-
-select_roi()
-{
-  rtstruct_roi_name_list=( `clitkDicomInfo ${rtstruct_file} | grep "3006|0026" | cut -d '[' -f 4 | sed 's/| V 3006|0026[LO] [ROI Name] \|]//'` )
-  rtstruct_roi_number_list=( `clitkDicomInfo ${rtstruct_file} | grep "3006|0022" | cut -d '[' -f 4 | sed 's/| V 3006|0026[LO] [ROI Number] \|]//'` )
-  rtstruct_roi_list=( )
-  for i in $(seq 0 1 $(( ${#rtstruct_roi_name_list[@]} - 1 ))); do
-    rtstruct_roi_list[$i]=${rtstruct_roi_number_list[$i]}:${rtstruct_roi_name_list[$i]}
-  done
-
-  if [ $gui_mode = 1 ]; then
-    select_contour_gui ${rtstruct_roi_list[@]}
-    rtstruct_roi=`echo ${rtstruct_roi_name} | cut -d ':' -f 1`
-    rtstruct_roi_name=`echo ${rtstruct_roi_name} | cut -d ':' -f 2`
-  else
-    select_contour ${rtstruct_roi_list[@]}
-    rtstruct_roi=$rtstruct_roi_number
-    rtstruct_roi_name=${rtstruct_roi_name_list[$(( $rtstruct_roi_number - 1))]}
-  fi
-}
 
 ############# main 
 
 if echo $* | grep "\-h"; then
-  echo Usage: calculate_motion_amplitude.sh { RTSTRUCT_FILE REFERENCE_IMAGE | --gui }
-
+  echo Usage: calculate_motion_amplitude.sh { REFERENCE_IMAGE RTSTRUCT_FILE [ RTSTRUCT_ROI | --gui ] } | --gui 
+  echo "  RTSTRUCT_REF_IMAGE: mhd of the reference image used in the contour delineation"
+  echo "  RTSTRUCT_FILE: dicom with contours"
+  echo "  RTSTRUCT_ROI: number of the contour whose motion to analyze"
+  echo "  --gui: use GUI to select files"
   exit 0
 fi
 
 
-rtstruct_roi=0
+rtstruct_roi=
 
 if echo $* | grep "\-\-gui" > /dev/null 2>&1; then
-  if [ $# != 1 ]; then
+  gui_mode=1
+  if [ $# = 1 ]; then
+    rtstruct_ref_image=`zenity --file-selection --title="Select Reference Image."`
+    rtstruct_file=`zenity --file-selection --title="Select RT Struct file."`
+    select_roi
+  elif [ $# = 3 ]; then
+    rtstruct_ref_image=$1
+    rtstruct_file=$2
+    select_roi
+  else
     echo Invalid arguments. Type \'`basename $0` -h\' for help
     exit -1
   fi
 
-  gui_mode=1
-  rtstruct_file=`zenity --file-selection --title="Select RT Struct file."`
-  select_roi
-  rtstruct_ref_image=`zenity --file-selection --title="Select Reference Image."`
 else
-  if [ $# != 2 ]; then
+  gui_mode=0
+  rtstruct_ref_image=$1
+  rtstruct_file=$2
+  if [ $# = 2 ]; then
+    select_roi
+  elif [ $# = 3 ]; then
+    rtstruct_roi=$3
+    rtstruct_roi_name=$rtstruct_roi
+  else
     echo Invalid arguments. Type \'`basename $0` -h\' for help
     exit -1
   fi
 
-  gui_mode=0
-  rtstruct_file=$1
-  rtstruct_ref_image=$2
-  select_roi
 fi
 
 
index b40c766997115c960a4ce7a21aab0f8c91b2cbd1..c1128b0ebdec75f3896fd5298bfe6efedf4db8df 100755 (executable)
@@ -1,27 +1,76 @@
 #! /bin/bash +x 
 
+source `dirname $0`/midp_common.sh
+
+
+calculate_motion()
+{
+  # calculate motion amplitudes along the 3 image axes
+  rm /tmp/result.txt 2> /dev/null
+  dir=( "\"left-right\"" "\"anterior-posterior\"" "\"cranio-caudal\"" )
+  pct=( 0 33 67 )
+  for i in 0 1 2; do
+    if [ $gui_mode = 1 ]; then
+      echo "${pct[$i]}"; echo "# Calculating motion along ${dir[$i]} direction.."
+    else
+      echo "Calculating motion along ${dir[$i]} direction.."
+    fi
+
+    echo "Motion along ${dir[$i]} direction" >> /tmp/result.txt
+    clitkImageStatistics -i ${vector_file} -m ${roi_mask2} -c $i --verbose 2> /dev/null | tail -n 8 | head -n 6 >> /tmp/result.txt
+    min=`tail -n 2 /tmp/result.txt | head -n 1 | cut -f 2 -d ':'`
+    max=`tail -n 1 /tmp/result.txt | cut -f 2 -d ':'`
+    amp=`echo $max-$min | bc`
+
+    echo "Amplitude: $amp" >> /tmp/result.txt
+    echo "" >> /tmp/result.txt
+  done
+}
+
 ############# main 
 
 if echo $* | grep "\-h"; then
-  echo Usage: calculate_motion_amplitude.sh VECTOR_FILE RTSTRUCT_FILE RTSTRUCT_ROI_NUMBER RTSTRUCT_REF_IMAGE
+  echo "Usage: calculate_motion_amplitude.sh { VECTOR_FILE RTSTRUCT_REF_IMAGE RTSTRUCT_FILE [ RTSTRUCT_ROI_NUMBER | --gui ] } | --gui "
   echo "  VECTOR_FILE: mhd of the vector field from where to extract motion information (may also be 4D)"
+  echo "  RTSTRUCT_REF_IMAGE: mhd of the reference image used in the contour delineation"
   echo "  RTSTRUCT_FILE: dicom with contours"
   echo "  RTSTRUCT_ROI: number of the contour whose motion to analyze"
-  echo "  RTSTRUCT_REF_IMAGE: mhd of the reference image used in the contour delineation"
-
+  echo "  --gui: use GUI to select files"
   exit 0
 fi
 
-if [ $# != 4 ]; then
-  echo Invalid arguments. Type \'`basename $0` -h\' for help
-  exit -1
+if echo $* | grep "\-\-gui" > /dev/null 2>&1; then
+  gui_mode=1
+  if [ $# = 1 ]; then
+    vector_file=`zenity --file-selection --title="Select 4D Vector Field file."`
+    rtstruct_ref_image=`zenity --file-selection --title="Select Reference Image."`
+    rtstruct_file=`zenity --file-selection --title="Select RT Struct file."`
+    select_roi
+  elif [ $# = 4 ]; then
+    vector_file=$1
+    rtstruct_ref_image=$2
+    rtstruct_file=$3
+    select_roi
+  else
+    echo Invalid arguments. Type \'`basename $0` -h\' for help
+    exit -1
+  fi
+else
+  gui_mode=0
+  vector_file=$1
+  rtstruct_ref_image=$2
+  rtstruct_file=$3
+  if [ $# = 4 ]; then
+    rtstruct_roi=$4
+    rtstruct_roi_name=$rtstruct_roi
+  elif [ $# = 3 ]; then
+    select_roi
+  else
+    echo Invalid arguments. Type \'`basename $0` -h\' for help
+    exit -1
+  fi
 fi
 
-vector_file=$1
-rtstruct_file=$2
-rtstruct_roi=$3
-rtstruct_ref_image=$4
-
 if ! cat $vector_file | grep -q "Channels = 3"; then
   echo Vector file must have 3 channels.
   exit -2
@@ -29,7 +78,7 @@ fi
 
 # create ROI mask from rtstruct
 roi_mask=roi_${rtstruct_roi}.mhd
-clitkDicomRTStruct2BinaryImage -i ${rtstruct_file} -o ${roi_mask} -j ${rtstruct_ref_image} -r ${rtstruct_roi} 2> /tmp/err.txt
+clitkDicomRTStruct2Image -i ${rtstruct_file} -o ${roi_mask} -j ${rtstruct_ref_image} -r ${rtstruct_roi} 2> /tmp/err.txt
 if cat /tmp/err.txt | grep -q "No ROI"; then
   echo Invalid contour number.
   exit -3
@@ -39,20 +88,20 @@ fi
 roi_mask2=resampled_${roi_mask}
 clitkResampleImage -i ${roi_mask} -o ${roi_mask2} --like ${vector_file}
 
-# calculate motion amplitudes along the 3 image axes
-dir=( sagittal coronal axial )
-for i in 0 1 2; do
-  echo Motion along ${dir[$i]} direction
-  clitkImageStatistics -i ${vector_file} -m ${roi_mask2} -c $i --verbose 2> /dev/null | tail -n 8 | head -n 6 > /tmp/res.txt
-  min=`tail -n 2 /tmp/res.txt | head -n 1 | cut -f 2 -d ':'`
-  max=`tail -n 1 /tmp/res.txt | cut -f 2 -d ':'`
-  amp=`echo $max-$min | bc`
-  cat /tmp/res.txt
-  echo "Amplitude: $amp"
-  echo
-done
+if [ $gui_mode = 1 ]; then
+  calculate_motion | zenity --progress --auto-close --percentage=0 --text=""
+else
+  calculate_motion
+fi
+
+if [ $gui_mode = 1 ]; then
+  cat /tmp/result.txt | zenity --text-info --title "Restuls for \"${rtstruct_roi_name}\""
+else
+  echo "Restuls for \"${rtstruct_roi_name}\""
+  cat /tmp/result.txt 
+fi
 
 rm `basename $roi_mask .mhd`.{mhd,raw}
 rm `basename $roi_mask2 .mhd`.{mhd,raw}
 rm /tmp/err.txt
-rm /tmp/res.txt
+rm /tmp/result.txt
diff --git a/scripts/compress_mhd.sh b/scripts/compress_mhd.sh
new file mode 100755 (executable)
index 0000000..f2e8912
--- /dev/null
@@ -0,0 +1,69 @@
+#! /bin/bash 
+
+compress_file()
+{
+  local f=$1
+  if [ "$verbose" = "1" ]; then
+    echo "Compressing $f..."
+  fi
+
+  local msg=`clitkImageConvert -i $f -o $f -c`
+  if [ -z "$msg" ]; then
+    raw=`echo $f | sed 's/\.mhd/\.raw/'`
+    if test -e $raw; then
+      rm $raw
+    fi
+  fi
+}
+
+compress_directory()
+{
+  local input=$1
+
+  files=$(find $input -name "*.mhd" | sort)
+  for f in $files; do
+    if ! grep -iq 'LIST' $f; then
+      # process all except 4D files
+      compress_file $f
+    else
+      # process only 4D files (just update pointers to new zraw files)
+      # assumes each .RAW in the list has a corresponding .MHD, which
+      # must be compressed separately
+      sed -i 's/\.raw/\.zraw/g' $f
+      if grep -q "CompressedData" $f; then
+        sed -i 's/CompressedData.*/CompressedData = True/' $f
+      else
+        tmp=/tmp/$RANDOM.mhd
+        echo "CompressedData = True" > $tmp
+        cat $f >> $tmp
+        mv $tmp $f
+      fi 
+    fi
+  done
+}
+
+# main program
+
+if [ $# -lt 1 -o $# -gt 2 ]; then
+  echo "Invalid params. `basename $0` [-h | --help] for help" 1>&2
+  exit -1
+fi
+
+if [ -n "`echo $@ | grep '\-h\|--help'`" ]; then
+  echo "Usage: `basename $0` {FILE | DIRECTORY | -h | --help | -v}"
+  exit 0
+fi
+
+if [ -n "`echo $@ | grep '\-v'`" ]; then
+  echo Verbose mode : ON
+  verbose=1
+fi  
+
+input=$1
+if test -d $input; then
+  compress_directory $input
+elif test -f $input; then
+  compress_file $input
+else 
+  echo "Unknow input file type." 1>&2
+fi
index b363f7e3034c3143755923a3904b0fbbf8a7596e..24d3fd1d5110d80c60e2d57676e1eca183dd21f5 100755 (executable)
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/sh +x
 
 
 write_mhd_4D()
@@ -12,11 +12,12 @@ write_mhd_4D()
                  /DimSize/ s/.*/& $nbph/
                  s/ElementDataFile = .*/ElementDataFile = LIST/" > "$1/$file_name_4D"
   
-  for ph in $listph
+  for ph in ${listph[@]}
   do
     ph=`basename $ph`
     echo "$ph" >> "$1/$file_name_4D"
   done
+  echo $1/$file_name_4D
 }
 
 #################################################
@@ -40,25 +41,41 @@ list_prefix=""
 list_phase_file=`find $1 -maxdepth 1 -iname "*[0-9]*.mhd"`
 for phase_file in $list_phase_file
 do
-  phase_file_name=`basename $phase_file`
-  if [[ ! -z `echo "$phase_file_name" | grep "__[0-9]"` ]]
+  if grep -q "NDims = 4" $phase_file 2> /dev/null
   then
-    prefix=`echo $phase_file_name | sed "s/__[0-9].*/__/"`
-  else
-    if [[ ! -z `echo "$phase_file_name" | grep "[0-9]-.*\]"` ]]
-    then
-      if [[ ! -z `echo "$phase_file_name" | grep "[0-9][0-9]-.*\]"` ]]
-      then
-       prefix=`echo $phase_file_name | sed "s/[0-9][0-9]-.*//"`
-      else
-       prefix=`echo $phase_file_name | sed "s/[0-9]-.*//"`
-      fi
-    else
-      prefix="NONE"
-    fi
+    #echo $phase_file is 4D
+    continue;
+  fi;
+
+  phase_file_name=`basename $phase_file .mhd`
+#   if [[ ! -z `echo "$phase_file_name" | grep "__[0-9]"` ]]
+#   then
+#     prefix=`echo $phase_file_name | sed "s/__[0-9].*/__/"`
+#   else
+#     if [[ ! -z `echo "$phase_file_name" | grep "[0-9]-.*\]"` ]] 
+#     then
+#       if [[ ! -z `echo "$phase_file_name" | grep "[0-9][0-9]-.*\]"` ]]
+#       then
+#      prefix=`echo $phase_file_name | sed "s/[0-9][0-9]-.*//"`
+#       else
+#      prefix=`echo $phase_file_name | sed "s/[0-9]-.*//"`
+#       fi
+#     else
+#       prefix="NONE"
+#     fi
+#   fi
+
+  # preffix: grep sequence of characters followed by sequence of numbers and remove sequence of numbers
+  # prefix=`echo $phase_file_name | grep -o "\(^[[:alpha:][:punct:]]*\)\([[:digit:]\.\_\-]\+\)" | sed 's/\(^[[:alpha:][:punct:]]*\)\([[:digit:]\.\_\-]\+\)/\1/'`
+  prefix=`echo $phase_file_name | grep -o "\(^[[:alpha:][:punct:]]*\)\([[:digit:]]\+\)\([\.\_\-]*\)"`
+  prefix=`echo $prefix | sed 's/^\-\+//' | sed 's/\(^[[:alpha:][:punct:]]*\)\([[:digit:]]\+\)\([\.\_\-]*\)/\1/'`
+  if [[ -z $prefix ]]
+  then 
+    prefix="NONE"
   fi
 
-  if [[ -z `echo "$list_prefix" | grep "$prefix"` ]]
+  # register new preffix if not yet done
+  if [[ -z `echo "$list_prefix" | grep -w -- "$prefix"` ]]
   then
     list_prefix="$list_prefix $prefix"
   fi
@@ -76,38 +93,60 @@ do
   list_phase_file_prefix=`find $1 -maxdepth 1 -iname "${prefix}[0-9]*.mhd"`
   for phase_file_prefix in $list_phase_file_prefix
   do
-    phase_file_prefix_name=`basename $phase_file_prefix`
-    if [[ ! -z `echo "$phase_file_prefix_name" | grep "__[0-9]"` ]]
+    if grep -q "NDims = 4" $phase_file_prefix  2> /dev/null
     then
+      #echo $phase_file_prefix is 4D
+      continue;
+    fi;
+    phase_file_prefix_name=`basename $phase_file_prefix .mhd`
+#     if [[ ! -z `echo "$phase_file_prefix_name" | grep "__[0-9]"` ]]
+#     then
+#       suffix="NONE"
+#     else
+#       if [[ ! -z `echo "$phase_file_prefix_name" | grep "[0-9]-.*\]"` ]]
+#       then
+#      suffix=`echo $phase_file_prefix_name | sed "s/.*[0-9]-//;s/_\.mhd//;s/\.mhd//"`
+#       else
+#      suffix="NONE"
+#       fi
+#     fi
+# 
+
+    # suffix: grep sequence of numbers followed by sequence of characters and remove sequence of numbers
+    # suffix=`echo $phase_file_prefix_name | grep -o "\([[:digit:]\.\_\-]\+\)\([[:alpha:][:punct:]]*$\)" | sed 's/\([[:digit:]\.\_\-]\+\)\([[:alpha:][:punct:]]*$\)/\2/'`
+    suffix=`echo $phase_file_prefix_name | grep -o "\([\.\_\-]*\)\([[:digit:]]\+\)\([[:alpha:][:punct:]]*$\)"`
+    if ! echo $suffix | grep -qo "^\-\+"; then
+      suffix=`echo $suffix | sed 's/\([\.\_\-]*\)\([[:digit:]]\+\)\([[:alpha:][:punct:]]*$\)/\3/'`
+    fi
+    suffix=`echo $suffix | sed 's/[\.\_\-]\+$//'`
+    if [[ -z $suffix ]]
+    then 
       suffix="NONE"
-    else
-      if [[ ! -z `echo "$phase_file_prefix_name" | grep "[0-9]-.*\]"` ]]
-      then
-       suffix=`echo $phase_file_prefix_name | sed "s/.*[0-9]-//;s/_\.mhd//;s/\.mhd//"`
-      else
-       suffix="NONE"
-      fi
     fi
 
-    if [[ -z `echo "$list_suffix" | grep "$suffix"` ]]
+    # register new suffix if not yet done
+    if [[ -z `echo "$list_suffix" | grep -w -- "$suffix"` ]]
     then
       list_suffix="$list_suffix $suffix"
     fi
   done
 
+  
   for suffix in $list_suffix
   do
     if [ "$suffix" = "NONE" ]
     then
       suffix=""
     fi
-    nbph=`find $1 -maxdepth 1 -iname "*${prefix}*[0-9]*${suffix}*.mhd" | wc -l`
-    orig=`find $1 -maxdepth 1 -iname "*${prefix}*[0-9]*${suffix}*.mhd" | sort | head -n 1`
-    listph=`find $1 -maxdepth 1 -iname "*${prefix}*[0-9]*${suffix}*.raw" | sort`
-
-    file_name_4D="${prefix}4D${suffix}.mhd"
-    
-    write_mhd_4D $1
+    orig=`find $1 -maxdepth 1 -iname "${prefix}[0-9]*${suffix}*.mhd" | grep "${prefix}[[:digit:][:punct:]]\+${suffix}[\.\_\-]*.mhd" | sort | head -n 1`
+    listph=( `find $1 -maxdepth 1 -iname "${prefix}[0-9]*${suffix}*.*raw" | grep "${prefix}[[:digit:][:punct:]]\+${suffix}[\.\_\-]*.z*raw" | sort` )
+    nbph=${#listph[@]}
+
+    # only create 4D file if potential number of phases is > 1
+    if [ $nbph -gt 1 ]; then
+      file_name_4D="${prefix}4D${suffix}.mhd"
+      write_mhd_4D $1
+    fi
 
   done
 
index 6fa7476ffb156b0ab53dd1cd03518502e90abf35..10cd52a12bb5991d49b805a322dd19f2842d3025 100755 (executable)
@@ -53,8 +53,12 @@ resample()
   echo "$phase_file -> Resampling..."
   clitkResampleImage -i $mask_dir_tmp/patient_$phase_nb.mhd -o $mask_dir_tmp/patient_$phase_nb.mhd --spacing $resample_spacing --interp $resample_algo
   clitkResampleImage -i $mask_dir_tmp/patient_mask_$phase_nb.mhd -o $mask_dir_tmp/patient_mask_$phase_nb.mhd --spacing $resample_spacing --interp $resample_algo
-  clitkResampleImage -i $mask_dir_tmp/lungs_$phase_nb.mhd -o $mask_dir_tmp/lungs_$phase_nb.mhd --like $mask_dir_tmp/patient_$phase_nb.mhd
-  clitkResampleImage -i $mask_dir_tmp/bones_$phase_nb.mhd -o $mask_dir_tmp/bones_$phase_nb.mhd --like $mask_dir_tmp/patient_$phase_nb.mhd
+  if [ "$mask_type" != "patient" ]; then
+    clitkResampleImage -i $mask_dir_tmp/lungs_$phase_nb.mhd -o $mask_dir_tmp/lungs_$phase_nb.mhd --like $mask_dir_tmp/patient_$phase_nb.mhd
+  fi
+  if [ "$mask_type" == "mm" ]; then
+    clitkResampleImage -i $mask_dir_tmp/bones_$phase_nb.mhd -o $mask_dir_tmp/bones_$phase_nb.mhd --like $mask_dir_tmp/patient_$phase_nb.mhd
+  fi
 }
 
 compute_motion_mask()
@@ -66,7 +70,6 @@ compute_motion_mask()
     FillingLevel=94
   fi
 
-  #clitkMotionMask -i $mask_dir_tmp/patient_$phase_nb.mhd -o $mask_dir_tmp/mm_$phase_nb.mhd --featureLungs $mask_dir_tmp/lungs_$phase_nb.mhd --upperThresholdLungs -400 --fillingLevel $FillingLevel --offsetDetect $MotionMaskOffsetDetect --pad --writeFeature=$mask_dir_tmp/feature_$phase_nb.mhd $MotionMaskExtra
   clitkMotionMask -i $mask_dir_tmp/patient_$phase_nb.mhd -o $mask_dir_tmp/mm_$phase_nb.mhd --featureLungs $mask_dir_tmp/lungs_$phase_nb.mhd --upperThresholdLungs -400 --featureBones $mask_dir_tmp/bones_$phase_nb.mhd --fillingLevel $FillingLevel --offsetDetect $MotionMaskOffsetDetect --pad --writeFeature $mask_dir_tmp/feature_$phase_nb.mhd $MotionMaskExtra  
   #--monitor=$mask_dir_tmp/monitor_$phase_nb.mhd
 }
@@ -130,55 +133,18 @@ create_registration_masks()
   create_banded_mask $mask_dir_tmp/outside_$phase_nb.mhd $mask_dir_tmp/${mask_type}_outside_$phase_nb.mhd $mask_dir_tmp/banded_outside_$phase_nb.mhd $mask_dir_tmp/banded_mask_outside_$phase_nb.mhd 4
 }
 
-create_registration_motion_masks()
+mm_preprocessing()
 {
-  # extract inside and outside regions from the patient image, 
-  # using the motion mask computed previously
-  echo "$phase_file -> Setting Background..."
-  clitkSetBackground -i $mask_dir_tmp/patient_$phase_nb.mhd -o $mask_dir_tmp/inside_$phase_nb.mhd --mask $mask_dir_tmp/mm_$phase_nb.mhd --outsideValue -1200
-  clitkSetBackground -i $mask_dir_tmp/patient_$phase_nb.mhd -o $mask_dir_tmp/outside_$phase_nb.mhd --mask $mask_dir_tmp/mm_$phase_nb.mhd --outsideValue -1200 --fg
-
-  # the registration masks for inside (and outside) region correspond
-  # to the motion mask (and its complement) plus extra grey value bands,
-  # obtained with morphological dilations.
-  # 
-  echo "$phase_file -> Creating registration masks..."
-  # inside
-  clitkMorphoMath -i $mask_dir_tmp/mm_$phase_nb.mhd -o $mask_dir_tmp/mask_inside_$phase_nb.mhd --type 1 --radius 8
-  create_banded_mask $mask_dir_tmp/inside_$phase_nb.mhd $mask_dir_tmp/mm_$phase_nb.mhd $mask_dir_tmp/banded_inside_$phase_nb.mhd $mask_dir_tmp/banded_mask_inside_$phase_nb.mhd 4
-  # outside 
-  clitkExtractPatient -i $mask_dir_tmp/outside_$phase_nb.mhd -o $mask_dir_tmp/mm_outside_$phase_nb.mhd --noAutoCrop
-  clitkMorphoMath -i $mask_dir_tmp/mm_outside_$phase_nb.mhd -o $mask_dir_tmp/mask_outside_$phase_nb.mhd --type 1 --radius 8
-  create_banded_mask $mask_dir_tmp/outside_$phase_nb.mhd $mask_dir_tmp/mm_outside_$phase_nb.mhd $mask_dir_tmp/banded_outside_$phase_nb.mhd $mask_dir_tmp/banded_mask_outside_$phase_nb.mhd 4
-}
+  extract_patient
 
-create_registration_lung_masks()
-{
-  # extract inside and outside lung regions from the patient image, 
-  # using the motion mask computed previously
-  echo "$phase_file -> Setting Background..."
-  clitkSetBackground -i $mask_dir_tmp/patient_$phase_nb.mhd -o $mask_dir_tmp/inside_$phase_nb.mhd --mask $mask_dir_tmp/lungs_$phase_nb.mhd --outsideValue -1200
-  clitkSetBackground -i $mask_dir_tmp/patient_$phase_nb.mhd -o $mask_dir_tmp/outside_$phase_nb.mhd --mask $mask_dir_tmp/lungs_$phase_nb.mhd --outsideValue -1200 --fg
+  if [ "$mask_type" != "patient" ]; then
+    extract_lungs
+  fi
 
-  # the registration masks for inside (and outside) region correspond
-  # to the motion mask (and its complement) plus extra grey value bands,
-  # obtained with morphological dilations.
-  # 
-  echo "$phase_file -> Creating registration masks..."
-  # inside
-  clitkMorphoMath -i $mask_dir_tmp/lungs_$phase_nb.mhd -o $mask_dir_tmp/mask_inside_$phase_nb.mhd --type 1 --radius 8
-  create_banded_mask $mask_dir_tmp/inside_$phase_nb.mhd $mask_dir_tmp/lungs_$phase_nb.mhd $mask_dir_tmp/banded_inside_$phase_nb.mhd $mask_dir_tmp/banded_mask_inside_$phase_nb.mhd 4
-  # outside 
-  clitkBinarizeImage -i $mask_dir_tmp/outside_$phase_nb.mhd -o $mask_dir_tmp/lungs_outside_$phase_nb.mhd -l -999 -u 4000 --mode both 
-  clitkMorphoMath -i $mask_dir_tmp/lungs_outside_$phase_nb.mhd -o $mask_dir_tmp/mask_outside_$phase_nb.mhd --type 1 --radius 8
-  create_banded_mask $mask_dir_tmp/outside_$phase_nb.mhd $mask_dir_tmp/lungs_outside_$phase_nb.mhd $mask_dir_tmp/banded_outside_$phase_nb.mhd $mask_dir_tmp/banded_mask_outside_$phase_nb.mhd 4
-}
+  if [ "$mask_type" == "mm" ]; then
+    extract_bones
+  fi
 
-mm_preprocessing()
-{
-  extract_patient
-  extract_bones
-  extract_lungs
   # remove_tmp_masks 1
   if [ $resample_spacing -ne 0 ] ; then 
     resample
@@ -233,25 +199,6 @@ wait_mm_creation()
         do_mm=1
       fi
     fi
-#     elif [ "$mask_type" == "lungs" ]; then
-#       nb_mm_masks=`ls $mask_dir/lungs_outside*.mhd | wc -l`
-#       nb_in_masks=`ls $mask_dir/mask_in*.mhd | wc -l`
-#       nb_out_masks=`ls $mask_dir/mask_out*.mhd | wc -l`
-#       if [ $nb_mm_masks != $nb_phases -o $nb_in_masks != $nb_phases -o $nb_out_masks != $nb_phases ]; then
-#         # if the mask dir is invalid, remove it and recreate all masks, just in case.
-#         rm -fr $mask_dir 2> /dev/null
-#         do_mm=1
-#       fi
-#     elif [ "$mask_type" == "mm" ]; then
-#       nb_mm_masks=`ls $mask_dir/mm_outside*.mhd | wc -l`
-#       nb_in_masks=`ls $mask_dir/mask_in*.mhd | wc -l`
-#       nb_out_masks=`ls $mask_dir/mask_out*.mhd | wc -l`
-#       if [ $nb_mm_masks != $nb_phases -o $nb_in_masks != $nb_phases -o $nb_out_masks != $nb_phases ]; then
-#         # if the mask dir is invalid, remove it and recreate all masks, just in case.
-#         rm -fr $mask_dir 2> /dev/null
-#         do_mm=1
-#       fi
-#     fi
   fi
   
   if [ $do_mm = 1 ]; then
@@ -401,7 +348,7 @@ motion_mask()
 
 if [ $# -ne 4 -a $# -ne 2 -a $# -ne 1 ]; then
   echo "Usage: $0 CT_4D TYPE [RESAMPLE_SPACING RESAMPLE_ALGORITHM]"
-  echo "  TYPE: \"motion\" (traditional motion masks); \"lungs\" (lung masks); \"patient\" (patient mask only)"
+  echo "  TYPE: \"mm\" (traditional motion masks); \"lungs\" (lung masks); \"patient\" (patient mask only)"
   exit -1
 fi
 
index 1ac9529223840adf5bbb52232e172dc91839378e..a5d0bafecedab8873c7a1615729fa2ed9cac92be 100755 (executable)
@@ -98,28 +98,28 @@ extract_4d_phase_numbers()
   nb_phases=${#phase_files[@]}
 
   # get everything except numbers and punctuation
-  cat $mhd4d | grep ".raw" | sed 's:.raw:.mhd:' | sed 's/.mhd//' | grep -o "[^0-9[:punct:]]*" | sort -u > /tmp/patterns.txt
+  cat $mhd4d | grep ".z*raw" | sed 's:.z*raw:.mhd:' | sed 's/.mhd//' | grep -o "[^0-9[:punct:]]*" | sort -u > /tmp/patterns.txt
 
   # find which patterns have the phases connected to it
   patterns=`cat /tmp/patterns.txt`
   if [ -z "$patterns" ]; then
-    phase_nbs=( `cat $mhd4d | grep ".raw" | sed 's:.raw:.mhd:' | sed 's/.mhd//' | grep "[0-9]\+"` )
+    phase_nbs=( `cat $mhd4d | grep ".z*raw" | sed 's:.z*raw:.mhd:' | sed 's/.mhd//' | grep "[0-9]\+"` )
   else
     for i in $patterns; do 
 
       # check if the pattern appears before the phase number
-      nb_phases_found=`cat $mhd4d | grep ".raw" | sed 's:.raw:.mhd:' | sed 's/.mhd//' | grep -o "$i[0-9[:punct:]]\+" | sort -u | wc -l`
+      nb_phases_found=`cat $mhd4d | grep ".z*raw" | sed 's:.z*raw:.mhd:' | sed 's/.mhd//' | grep -o "$i[0-9[:punct:]]\+" | sort -u | wc -l`
       if [ $nb_phases_found == $nb_phases ]; then
         # keep only what identifies the phase number
-        phase_nbs=( `cat $mhd4d | grep ".raw" | sed 's:.raw:.mhd:' | sed 's/.mhd//' | grep -o "$i[0-9[:punct:]]\+" | grep -o "[^${i}]\+" | grep -o "[0-9]\+[[:punct:]]*[0-9]*" | grep -o "[0-9]*[[:punct:]]*[0-9]\+"` ) 
+        phase_nbs=( `cat $mhd4d | grep ".z*raw" | sed 's:.z*raw:.mhd:' | sed 's/.mhd//' | grep -o "$i[0-9[:punct:]]\+" | grep -o "[^${i}]\+" | grep -o "[0-9]\+[[:punct:]]*[0-9]*" | grep -o "[0-9]*[[:punct:]]*[0-9]\+"` ) 
         break
       fi
     
       # check if the pattern appears after the phase number
-      nb_phases_found=`cat $mhd4d | grep ".raw" | sed 's:.raw:.mhd:' | sed 's/.mhd//' | grep -o "[0-9[:punct:]]\+$i" | sort -u | wc -l`
+      nb_phases_found=`cat $mhd4d | grep ".z*raw" | sed 's:.z*raw:.mhd:' | sed 's/.mhd//' | grep -o "[0-9[:punct:]]\+$i" | sort -u | wc -l`
       if [ $nb_phases_found == $nb_phases ]; then
         # keep only what identifies the phase number
-        phase_nbs=( `cat $mhd4d | grep ".raw" | sed 's:.raw:.mhd:' | sed 's/.mhd//' | grep -o "[0-9[:punct:]]\+$i" | grep -o "[^${i}]\+" | grep -o "[0-9]\+[[:punct:]]*[0-9]*" | grep -o "[0-9]*[[:punct:]]*[0-9]\+"` ) 
+        phase_nbs=( `cat $mhd4d | grep ".z*raw" | sed 's:.z*raw:.mhd:' | sed 's/.mhd//' | grep -o "[0-9[:punct:]]\+$i" | grep -o "[^${i}]\+" | grep -o "[0-9]\+[[:punct:]]*[0-9]*" | grep -o "[0-9]*[[:punct:]]*[0-9]\+"` ) 
         break
       fi
 
@@ -142,7 +142,7 @@ extract_4d_phases()
   echo "4D file is $mhd4d"
 
   # array of phase files
-  phase_files=( `cat $mhd4d | grep ".raw" | sed 's:.raw:.mhd:'` )
+  phase_files=( `cat $mhd4d | grep ".z*raw" | sed 's:.z*raw:.mhd:'` )
   echo "Phase files are ${phase_files[@]}"
 
   extract_4d_phase_numbers $mhd4d 
@@ -161,7 +161,7 @@ extract_4d_phases_ref()
   extract_4d_phases $1
 
   # reference phase file
-  ref_phase_file=`cat $mhd4d | grep ".raw" | sed 's:.raw:.mhd:' | grep $2`
+  ref_phase_file=`cat $mhd4d | grep ".z*raw" | sed 's:.z*raw:.mhd:' | grep $2`
   echo "Reference phase is $ref_phase_file"
 
   # reference phase number
@@ -198,14 +198,81 @@ average_temporal_dimension()
   local tot=$tmp.mhd
 
   local dir=`dirname $1` 
-  local first=`grep raw $1 | sed 's/raw/mhd/g' | head -n 1`
+  local first=`grep z*raw $1 | sed 's/z*raw/mhd/g' | head -n 1`
   clitkImageArithm -i $dir/$first -o $tot -t 1 -s 0
 
-  local nbphases=`grep raw $1 | sed 's/raw/mhd/g' | wc -l`
-  for i in $(grep raw $1 | sed 's/raw/mhd/g'); do
+  local nbphases=`grep z*raw $1 | sed 's/z*raw/mhd/g' | wc -l`
+  for i in $(grep z*raw $1 | sed 's/z*raw/mhd/g'); do
     clitkImageArithm -i $dir/$i -j $tot -o $tot
   done
 
   clitkImageArithm -i $tot -o $2 -t 11 -s $nbphases
   rm $tmp.*
 }
+
+select_contour_gui()
+{
+  local roi_list=$@
+  roi=`zenity --list --title="Available Contours" --column="Please choose a contour:" $roi_list`
+  case $? in
+    0)
+    if [ -z $roi ]
+    then
+      zenity --warning --text="You must choose one contour."
+      select_contour $roi_list
+    else
+      rtstruct_roi_name=$roi
+    fi;;
+    1)
+    if zenity --question --text="Do you really wish to quit?"
+    then
+      exit
+    else
+      select_contour $roi_list
+    fi;;
+    -1)
+      zenity --error --text="Unexpected error. Please relaunch the application."
+      exit;;
+  esac
+}
+
+select_contour()
+{
+  local roi_list=$@
+  echo "Available Contours:" 
+  for r in $roi_list; do
+    echo $r
+  done
+
+  echo "Please choose a contour number:"
+  read rtstruct_roi_index
+  let i=0
+  for r in $roi_list; do
+    if [ $rtstruct_roi_index = `echo $r | cut -d ':' -f 1` ]; then
+      rtstruct_roi_index=$i
+      break;
+    fi
+    let i=i+1
+  done
+  
+}
+
+select_roi()
+{
+  rtstruct_roi_name_list=( `clitkDicomInfo ${rtstruct_file} | grep "3006|0026" | cut -d '[' -f 4 | sed 's/| V 3006|0026[LO] [ROI Name] \|]//'` )
+  rtstruct_roi_number_list=( `clitkDicomInfo ${rtstruct_file} | grep "3006|0022" | cut -d '[' -f 4 | sed 's/| V 3006|0026[LO] [ROI Number] \|]//'` )
+  rtstruct_roi_list=( )
+  for i in $(seq 0 1 $(( ${#rtstruct_roi_name_list[@]} - 1 ))); do
+    rtstruct_roi_list[$i]=${rtstruct_roi_number_list[$i]}:${rtstruct_roi_name_list[$i]}
+  done
+
+  if [ $gui_mode = 1 ]; then
+    select_contour_gui ${rtstruct_roi_list[@]}
+    rtstruct_roi=`echo ${rtstruct_roi_name} | cut -d ':' -f 1`
+    rtstruct_roi_name=`echo ${rtstruct_roi_name} | cut -d ':' -f 2`
+  else
+    select_contour ${rtstruct_roi_list[@]}
+    rtstruct_roi=${rtstruct_roi_number_list[$(( $rtstruct_roi_index ))]}
+    rtstruct_roi_name=${rtstruct_roi_name_list[$(( $rtstruct_roi_index ))]}
+  fi
+}
\ No newline at end of file
index f879a36ade6c53a71cfd5d8f123b208b67d8ff6c..b9e9d1cd7fc0fbbbc9656c0e9454fe9a1c1b03ed 100644 (file)
@@ -32,10 +32,12 @@ option "writeFeature"               -       "Write the combined feature image"                      string  no
 section "Ellipsoide initialization"
 
 option "ellips"        -       "Input ellipsoide image (=1, at half resolution)"                                          string       no
-option "offset"        -       "Offset for ellips center from body center of gravity (default= 0,-50,0 mm)"       double       no      multiple
-option         "axes"          -       "Half axes of the ellips (default= 100,30,150)"                                    double       no      multiple
 option  "writeEllips"  -       "Write the initial ellipsoide image"                    string  no  
 option "writeDistMap"   - "Write the distance map"      string  no  
+#defgroup "EllipseParams" groupdesc="an option of this group is required" required
+option  "ellipseAutoDetect"  - "Auto-detect offset and axes of initial ellipse"          flag  off  
+option  "offset"  - "Offset for ellips center from body center of gravity (default= 0,-50,0 mm)"       double no  multiple
+option  "axes"    - "Half axes of the ellips (default= 100,30,150)"            double   no  multiple
 
 
 section "Ellipsoide growing"
index dfab4285b5dba9c06f95952e1d0b3c56296b3407..2a89fc7965f8090ab8f1bc6a146d73bd6d4d6d50 100644 (file)
@@ -118,7 +118,7 @@ protected:
   template <unsigned int Dimension, class PixelType>
   typename itk::Image<InternalPixelType, Dimension>::Pointer Resample(typename itk::Image<InternalPixelType, Dimension>::Pointer input );
   template <unsigned int Dimension, class PixelType>
-  typename itk::Image<InternalPixelType, Dimension>::Pointer InitializeEllips( typename itk::Vector<double,Dimension> center, typename itk::Image<InternalPixelType, Dimension>::Pointer bones_low);
+  typename itk::Image<InternalPixelType, Dimension>::Pointer InitializeEllips( typename itk::Vector<double,Dimension> center, typename itk::Image<InternalPixelType, Dimension>::Pointer bones_low, typename itk::Image<InternalPixelType,Dimension>::Pointer lungs_low);
 
 
   template <unsigned int Dimension>  void UpdateWithDim(std::string PixelType);
index 56fadac84f5e977f016677a0cd68bce42470e62c..c6476c2c3d75214c79f5202f9350fd42089fb351 100644 (file)
@@ -27,6 +27,8 @@
  *
  ===================================================*/
 
+#include "itkLabelImageToShapeLabelMapFilter.h"
+#include "itkShapeLabelObject.h"
 
 namespace clitk
 {
@@ -480,7 +482,7 @@ MotionMaskGenericFilter::Resample( typename itk::Image<InternalPixelType,Dimensi
 //-------------------------------------------------------------------
 template <unsigned int Dimension, class  PixelType>
 typename itk::Image<MotionMaskGenericFilter::InternalPixelType, Dimension>::Pointer
-MotionMaskGenericFilter::InitializeEllips( typename itk::Vector<double,Dimension> center, typename itk::Image<InternalPixelType,Dimension>::Pointer bones_low )
+MotionMaskGenericFilter::InitializeEllips( typename itk::Vector<double,Dimension> center, typename itk::Image<InternalPixelType,Dimension>::Pointer bones_low, typename itk::Image<InternalPixelType,Dimension>::Pointer lungs_low )
 {
 
   // ImageTypes
@@ -511,24 +513,88 @@ MotionMaskGenericFilter::InitializeEllips( typename itk::Vector<double,Dimension
       std::cout<<"=========================================="<<std::endl;
     }
 
-    //---------------------------------
-    // Offset from center
-    //---------------------------------
-    typename itk::Vector<double,Dimension> offset;
-    if(m_ArgsInfo.offset_given== Dimension) {
-      for(unsigned int i=0; i<Dimension; i++)
-        offset[i]=m_ArgsInfo.offset_arg[i];
-    } else {
-      offset.Fill(0.);
-      offset[1]=-50;
+    itk::Vector<double,Dimension> centerEllips;
+    typename itk::Vector<double, Dimension> axes;
+    if (m_ArgsInfo.ellipseAutoDetect_flag) {
+      if(m_Verbose) {
+        std::cout<<"Auto-detecting intial ellipse..."<<std::endl;
+      }
+
+      typename InternalImageType::RegionType region, region_before = lungs_low->GetLargestPossibleRegion();
+      typename InternalImageType::SizeType size = region_before.GetSize();
+      size[2] /= 2;
+      region.SetSize(size);
+      lungs_low->SetRegions(region);
+      
+      // compute statistics of the (mirroed) lung region in order to guess the params of the ellipse
+      typedef itk::LabelImageToShapeLabelMapFilter<InternalImageType>  LabelImageToShapeLabelMapFilter;
+      typename LabelImageToShapeLabelMapFilter::Pointer label_filter = LabelImageToShapeLabelMapFilter::New();
+      label_filter->SetInput(lungs_low);
+      label_filter->Update();
+      
+      typename InternalImageType::SpacingType spacing = lungs_low->GetSpacing();
+      typedef typename LabelImageToShapeLabelMapFilter::OutputImageType::LabelObjectType LabelType;
+      const LabelType* label = dynamic_cast<LabelType*>(label_filter->GetOutput()->GetNthLabelObject(0));
+
+      // lungs' barycenter
+      typename LabelType::CentroidType lung_centroid = label->GetCentroid();
+
+      // try to guess ideal ellipse axes from the lungs' bounding box and centroid
+      // with some hard-coded "magic" constants...
+#if ITK_VERSION_MAJOR >= 4
+      typename LabelType::RegionType lung_bbox = label->GetBoundingBox();
+#else
+      typename LabelType::RegionType lung_bbox = label->GetRegion();
+#endif
+      axes[0] = 0.95*lung_bbox.GetSize()[0]*spacing[0]/2;
+      axes[1] = 0.3*lung_bbox.GetSize()[1]*spacing[1]/2;
+      axes[2] = 1.25*fabs(lung_centroid[2] - center[2]);
+
+      // ellipse's center in XY is the center of the lungs' bounding box
+      typename InternalImageType::PointType origin = lungs_low->GetOrigin();
+      centerEllips[0] = origin[0] + (lung_bbox.GetIndex()[0] + lung_bbox.GetSize()[0]/2)*spacing[0];
+      centerEllips[1] = origin[1] + (lung_bbox.GetIndex()[1] + lung_bbox.GetSize()[1]/2)*spacing[1];
+      centerEllips[2] = center[2];
+      
+      lungs_low->SetRegions(region_before);
+      
+      if(m_Verbose) {
+        std::cout << "Lungs'centroid at " << lung_centroid << std::endl;
+        std::cout << "Ellipse center at " << centerEllips << std::endl;
+        std::cout << "Ellipse axes as " << axes << std::endl;
+        std::cout << "Lung's bounding box (index,size) " << lung_bbox.GetIndex() << lung_bbox.GetSize() << std::endl;
+      }
     }
-    itk::Vector<double,Dimension> centerEllips=center+offset;
-    if (m_Verbose) {
-      std::cout<<"Placing the center of the initial ellipsoide at (mm) "<<std::endl;
-      std::cout<<centerEllips[0];
-      for (unsigned int i=1; i<Dimension; i++)
-        std::cout<<" "<<centerEllips[i];
-      std::cout<<std::endl;
+    else {
+      //---------------------------------
+      // Offset from center
+      //---------------------------------
+      typename itk::Vector<double,Dimension> offset;
+      if(m_ArgsInfo.offset_given== Dimension) {
+        for(unsigned int i=0; i<Dimension; i++)
+          offset[i]=m_ArgsInfo.offset_arg[i];
+      } else {
+        offset.Fill(0.);
+        offset[1]=-50;
+      }
+      centerEllips=center+offset;
+      if (m_Verbose) {
+        std::cout<<"Placing the center of the initial ellipsoide at (mm) "<<std::endl;
+        std::cout<<centerEllips[0];
+        for (unsigned int i=1; i<Dimension; i++)
+          std::cout<<" "<<centerEllips[i];
+        std::cout<<std::endl;
+      }
+
+      // Axes
+      if (m_ArgsInfo.axes_given==Dimension)
+        for(unsigned int i=0; i<Dimension; i++)
+          axes[i]=m_ArgsInfo.axes_arg[i];
+      else {
+        axes[0]=100;
+        axes[1]=30;
+        axes[2]=150;
+      }
     }
 
     //---------------------------------
@@ -541,17 +607,6 @@ MotionMaskGenericFilter::InitializeEllips( typename itk::Vector<double,Dimension
     ellips->Allocate();
     ellips->FillBuffer(0);
 
-    // Axes
-    typename itk::Vector<double, Dimension> axes;
-    if (m_ArgsInfo.axes_given==Dimension)
-      for(unsigned int i=0; i<Dimension; i++)
-        axes[i]=m_ArgsInfo.axes_arg[i];
-    else {
-      axes[0]=100;
-      axes[1]=30;
-      axes[2]=150;
-    }
-
     // Draw an ellips
     IteratorType itEllips(ellips, ellips->GetLargestPossibleRegion());
     itEllips.GoToBegin();
@@ -727,7 +782,7 @@ MotionMaskGenericFilter::UpdateWithDimAndPixelType()
   //----------------------------------------------------------------------------------------------------
   // Ellipsoide initialization
   //----------------------------------------------------------------------------------------------------
-  typename InternalImageType::Pointer m_Ellips= InitializeEllips<Dimension, PixelType>(center,bones_low);
+  typename InternalImageType::Pointer m_Ellips= InitializeEllips<Dimension, PixelType>(center,bones_low,lungs_low);
 
   //----------------------------------------------------------------------------------------------------
   // Grow ellips
@@ -1075,6 +1130,10 @@ MotionMaskGenericFilter::UpdateWithDimAndPixelType()
     distanceMapImageFilter->SetInsideIsPositive(false);
     if (m_Verbose) std::cout<<"Calculating distance map..."<<std::endl;
     distanceMapImageFilter->Update();
+    if (m_ArgsInfo.writeDistMap_given) {
+      writeImage<LevelSetImageType>(distanceMapImageFilter->GetOutput(), m_ArgsInfo.writeDistMap_arg, m_Verbose);
+      
+    }
 
     //---------------------------------
     // Grow while monitoring lung volume coverage
index 24e1de1ca36dd1656c63821ad19d67431ffe9e53..995c14c1b916cfdc34cd0efff80a1b9acd8b5d7d 100644 (file)
@@ -29,6 +29,7 @@ option "axis"                 -       "Specify the source to axis distance in mm"     float           no      d
 option "angle"                 -       "Specify the projection angle"                  float           no      default="0.0"
 option "matrix"                -       "Rigid tranform prior to projection (4x4)"      string          no      
 option "pad"                           -       "Padding value"                                 float           no      default="0.0"
+option "panel_shift"            -       "Precise position of the panel in mm"           double          multiple        no
 
 
 section "Output Image"
index 01dfe6ae32a62e66030f3d6756d6cf1b2feb1046..52dd428c778749ae7930a6d8abe70adf0810a559 100644 (file)
@@ -72,6 +72,8 @@ namespace clitk
          iso[i]=m_ArgsInfo.iso_arg[i];
        filter->SetIsoCenter(iso);
       }
+    if (m_ArgsInfo.panel_shift_given)
+      filter->SetPanelShift(m_ArgsInfo.panel_shift_arg[0], m_ArgsInfo.panel_shift_arg[1]);
     filter->SetSourceToScreen(m_ArgsInfo.screen_arg);
     filter->SetSourceToAxis(m_ArgsInfo.axis_arg); 
     filter->SetProjectionAngle(m_ArgsInfo.angle_arg);
index b7702cc694aa5450cff434d37f0c6a5698df53a4..e8d8efb79d9f8c6a54d9cc1b5f37e0401d613c75 100644 (file)
@@ -25,9 +25,10 @@ clitk::ImageConvertGenericFilter::ImageConvertGenericFilter():
   clitk::ImageToImageGenericFilter<Self>("ImageConvert")
 {
   mOutputPixelTypeName = "NotSpecified";
-  mWarningOccur = false;
-  mWarning = "";
   mDisplayWarning = true;
+  mWarning = "";
+  mWarningOccur = false;
+  
   InitializeImageType<2>();
   InitializeImageType<3>();
   InitializeImageType<4>();
@@ -40,6 +41,10 @@ template<unsigned int Dim>
 void clitk::ImageConvertGenericFilter::InitializeImageType()
 {
   ADD_DEFAULT_IMAGE_TYPES(Dim);
+  ADD_VEC_IMAGE_TYPE(Dim, 2, float);
+  ADD_VEC_IMAGE_TYPE(Dim, 3, float);
+  ADD_VEC_IMAGE_TYPE(Dim, 2, double);
+  ADD_VEC_IMAGE_TYPE(Dim, 3, double);
 }
 //--------------------------------------------------------------------
 
@@ -48,7 +53,6 @@ void clitk::ImageConvertGenericFilter::InitializeImageType()
 template<class InputImageType>
 void clitk::ImageConvertGenericFilter::UpdateWithInputImageType()
 {
-
   // Verbose stuff
   if (m_IOVerbose) {
     if (m_InputFilenames.size() == 1) {
@@ -66,91 +70,57 @@ void clitk::ImageConvertGenericFilter::UpdateWithInputImageType()
     }
   }
 
-
   if ((m_PixelTypeName == mOutputPixelTypeName) || (mOutputPixelTypeName == "NotSpecified")) {
-    //    typename InputImageType::Pointer input = clitk::readImage<InputImageType>(m_InputFilenames);
     typename InputImageType::Pointer input = this->template GetInput<InputImageType>(0);
-    //clitk::writeImage<InputImageType>(input, mOutputFilename, m_IOVerbose);
     this->SetNextOutput<InputImageType>(input);
   } else {
-#define TRY_TYPE(TYPE)                                                 \
-    if (IsSameType<TYPE>(mOutputPixelTypeName)) { UpdateWithOutputType<InputImageType, TYPE>(); return; }
-    TRY_TYPE(char);
-    //    TRY_TYPE(signed char);
-    TRY_TYPE(uchar);
-    TRY_TYPE(short);
-    TRY_TYPE(ushort);
-    TRY_TYPE(int); // no uint ...
-    TRY_TYPE(float);
-    TRY_TYPE(double);
-#undef TRY_TYPE
-
-    std::string list = CreateListOfTypes<char, uchar, short, ushort, int, float, double>();
-    std::cerr << "Error, I don't know the output type '" << mOutputPixelTypeName
-              << "'. " << std::endl << "Known types are " << list << "." << std::endl;
-    exit(0);
+    // "trick" to call independent versions of update according to the 
+    // pixel type (vector or scalar), using partial specializations
+    if (!UpdateWithSelectiveOutputType<InputImageType, ImageConvertTraits<typename InputImageType::PixelType>::IS_VECTOR>::Run(*this, mOutputPixelTypeName))    
+      exit(-1);
   }
 }
 //====================================================================
 
 //====================================================================
-template<class InputImageType, class OutputPixelType>
-void clitk::ImageConvertGenericFilter::UpdateWithOutputType()
-{
-  // Read
-  typename InputImageType::Pointer input =this->template GetInput<InputImageType>(0);
-
-  // Typedef
-  typedef typename InputImageType::PixelType PixelType;
 
-  // Warning
+template<class PixelType, class OutputPixelType>
+void clitk::ImageConvertGenericFilter::CheckTypes(
+  std::string inType, std::string outType
+)
+{
   std::ostringstream osstream;
   if (std::numeric_limits<PixelType>::is_signed) {
     if (!std::numeric_limits<OutputPixelType>::is_signed) {
-      osstream << "Warning, input type is signed (" << m_PixelTypeName << ") while output type is not ("
-               << mOutputPixelTypeName << "), use at your own responsability." << std::endl;
-      mWarningOccur = true;
+      osstream << "Warning, input type is signed (";
     }
   }
   if (!std::numeric_limits<PixelType>::is_integer) {
     if (std::numeric_limits<OutputPixelType>::is_integer) {
-      osstream << "Warning, input type is not integer (" << m_PixelTypeName << ") while output type is ("
-               << mOutputPixelTypeName << "), use at your own responsability." << std::endl;
-      mWarningOccur = true;
+      osstream << "Warning, input type is not integer (";
     }
   }
   //  DD(std::numeric_limits<PixelType>::digits10);
   // DD(std::numeric_limits<OutputPixelType>::digits10);
   if (!std::numeric_limits<PixelType>::is_integer) {
     if (std::numeric_limits<OutputPixelType>::is_integer) {
-      osstream << "Warning, input type is not integer (" << m_PixelTypeName << ") while output type is ("
-               << mOutputPixelTypeName << "), use at your own responsability." << std::endl;
-      mWarningOccur = true;
+      osstream << "Warning, input type is not integer (";
     }
   }
   if (std::numeric_limits<PixelType>::digits10 > std::numeric_limits<OutputPixelType>::digits10) {
-    osstream << "Warning, possible loss of precision : input type is (" << m_PixelTypeName << ") while output type is ("
-             << mOutputPixelTypeName << "), use at your own responsability." << std::endl;
-    mWarningOccur = true;
+    osstream << "Warning, possible loss of precision : input type is (" ;
   }
 
-  mWarning = osstream.str();
-  if (mDisplayWarning) {
-    std::cerr << mWarning;
+  if (!osstream.str().empty())
+  {
+    mWarningOccur = true;
+    osstream << inType << ") while output type is (" << outType << "), use at your own responsability." << std::endl;
+    mWarning = osstream.str();
+    if (mDisplayWarning) {
+      std::cerr << mWarning;
+    }
   }
-
-  // Cast
-  typedef itk::Image<OutputPixelType,InputImageType::ImageDimension> OutputImageType;
-  typedef itk::CastImageFilter<InputImageType, OutputImageType> FilterType;
-  typename FilterType::Pointer filter = FilterType::New();
-  filter->SetInput(input);
-  filter->Update();
-
-  // Write
-  SetNextOutput<OutputImageType>(filter->GetOutput());
-  //clitk::writeImage<OutputImageType>(filter->GetOutput(), mOutputFilename, m_IOVerbose);
 }
-//====================================================================
 
 
 #endif /* end #define CLITKIMAGECONVERTGENERICFILTER_CXX */
index 6064b1821dbd0a6593c063fa452b8c05021bdeda..20717144431725a5f793d061467e10f170dc61bb 100644 (file)
 
 // itk include
 #include "itkCastImageFilter.h"
+#include "itkVectorCastImageFilter.h"
+
 
 namespace clitk {
   
+  template <class TPixel>
+  class ImageConvertTraits
+  {
+  public:
+    enum { IS_VECTOR = false };
+    ImageConvertTraits() {
+      TPixel p = "SCALAR";
+    }
+  };
+
+  template < class TPixel, unsigned int Comp > 
+  class ImageConvertTraits< itk::Vector<TPixel, Comp> > 
+  { 
+  public: 
+    enum { IS_VECTOR = true }; 
+  };
+
   class ImageConvertGenericFilter: 
     public clitk::ImageToImageGenericFilter<ImageConvertGenericFilter> {
     
@@ -51,6 +70,8 @@ namespace clitk {
     itkNewMacro(Self);
     
     // Members functions
+    std::string GetInputPixelTypeName() { return m_PixelTypeName; }
+    std::string GetOutputPixelTypeName() { return mOutputPixelTypeName; }
     void SetOutputPixelType(std::string p) { mOutputPixelTypeName = p; }
     bool IsWarningOccur() { return mWarningOccur; }
     std::string & GetWarning() { return mWarning; }
@@ -61,18 +82,138 @@ namespace clitk {
     template<class InputImageType>  
     void UpdateWithInputImageType();
 
+    template<class PixelType, class OutputPixelType>
+    void CheckTypes(std::string inType, std::string outType);
+    
   protected:
+
     template<unsigned int Dim> void InitializeImageType();
     std::string mOutputPixelTypeName;
     std::string mWarning;
     bool mWarningOccur;
     bool mDisplayWarning;
 
-    template<class InputImageType, class OutputPixelType> void UpdateWithOutputType();
-
+  private:
+    template <class InputImageType, bool isVector>
+    class UpdateWithSelectiveOutputType
+    {
+    public:
+      static bool Run(ImageConvertGenericFilter& filter, std::string outputPixelType)
+      {
+          if (IsSameType<char>(outputPixelType))
+            UpdateWithOutputType<char>(filter);
+          else if (IsSameType<uchar>(outputPixelType))
+            UpdateWithOutputType<uchar>(filter);
+          else if (IsSameType<short>(outputPixelType))
+            UpdateWithOutputType<short>(filter);
+          else if (IsSameType<ushort>(outputPixelType))
+            UpdateWithOutputType<ushort>(filter);
+          else if (IsSameType<int>(outputPixelType))
+            UpdateWithOutputType<int>(filter);
+          else if (IsSameType<float>(outputPixelType))
+            UpdateWithOutputType<float>(filter);
+          else if (IsSameType<double>(outputPixelType))
+            UpdateWithOutputType<double>(filter);
+          else
+          {
+            std::string list = CreateListOfTypes<float, double>();
+            std::cerr << "Error, I don't know the vector output type '" << outputPixelType 
+                      << "'. " << std::endl << "Known types are " << list << "." << std::endl;
+            return false;
+          }
+          
+          return true;
+      }
+
+    private:
+      
+      template <class OutputPixelType> 
+      static void UpdateWithOutputType(ImageConvertGenericFilter& filter)
+      {
+        // Read
+        typename InputImageType::Pointer input =filter.template GetInput<InputImageType>(0);
+
+        // Typedef
+        typedef typename InputImageType::PixelType PixelType;
+
+        // Warning
+        filter.CheckTypes<PixelType, OutputPixelType>(filter.GetInputPixelTypeName(), filter.GetOutputPixelTypeName());
+
+        // Cast
+        typedef itk::Image<OutputPixelType,InputImageType::ImageDimension> OutputImageType;
+        typedef itk::CastImageFilter<InputImageType, OutputImageType> FilterType;
+        typename FilterType::Pointer cast_filter = FilterType::New();
+        cast_filter->SetInput(input);
+        cast_filter->Update();
+
+        // Write
+        filter.SetNextOutput<OutputImageType>(cast_filter->GetOutput());
+      }
+    };
+    
+    template <class InputImageType>
+    class UpdateWithSelectiveOutputType<InputImageType, true>
+    {
+    public:
+      static bool Run(ImageConvertGenericFilter& filter, std::string outputPixelType)
+      {
+        /*
+        // RP: future conversions? 
+        if (IsSameType<char>(outputPixelType))
+          UpdateWithOutputVectorType<char>();
+        else if (IsSameType<uchar>(outputPixelType))
+          UpdateWithOutputVectorType<uchar>();
+        else if (IsSameType<short>(outputPixelType))
+          UpdateWithOutputVectorType<short>();
+        else if (IsSameType<ushort>(outputPixelType))
+          UpdateWithOutputVectorType<ushort>();
+        else if (IsSameType<int>(outputPixelType))
+          UpdateWithOutputVectorType<int>();
+        else 
+          */
+        if (IsSameType<float>(outputPixelType))
+          UpdateWithOutputVectorType<float>(filter);
+        else if (IsSameType<double>(outputPixelType))
+          UpdateWithOutputVectorType<double>(filter);
+        else
+        {
+          std::string list = CreateListOfTypes<float, double>();
+          std::cerr << "Error, I don't know the vector output type '" << outputPixelType  
+                    << "'. " << std::endl << "Known types are " << list << "." << std::endl;
+          return false;
+        }
+        
+        return true;
+      }
+      
+    private:
+      
+      template <class OutputPixelType> 
+      static void UpdateWithOutputVectorType(ImageConvertGenericFilter& filter)
+      {
+        // Read
+        typename InputImageType::Pointer input =filter.template GetInput<InputImageType>(0);
+
+        // Typedef
+        typedef typename InputImageType::PixelType::ValueType PixelType;
+
+        // Warning
+        filter.CheckTypes<PixelType, OutputPixelType>(filter.GetInputPixelTypeName(), filter.GetOutputPixelTypeName());
+        
+        // Cast
+        typedef itk::Image<itk::Vector<OutputPixelType, InputImageType::PixelType::Dimension>, InputImageType::ImageDimension> OutputImageType;
+        typedef itk::VectorCastImageFilter<InputImageType, OutputImageType> FilterType;
+        typename FilterType::Pointer cast_filter = FilterType::New();
+        cast_filter->SetInput(input);
+        cast_filter->Update();
+
+        // Write
+        filter.SetNextOutput<OutputImageType>(cast_filter->GetOutput());
+      }
+    };
   }; // end class ImageConvertGenericFilter
 
-  //#include "clitkImageConvertGenericFilter.txx"
+//#include "clitkImageConvertGenericFilter.txx"
 
 } // end namespace
 
index 5f86337f0238f96f725e1405b83ad6eb6c84eacf..2224a9ac9748dd6abb32b09a79185048f93137fc 100644 (file)
@@ -1168,33 +1168,38 @@ void vvSlicer::SetOverlayColorLevel(double level)
 
 //----------------------------------------------------------------------------
 // Returns the min an the max value in a 41x41 region around the mouse pointer
-void vvSlicer::GetExtremasAroundMousePointer(double & min, double & max, vtkImageData *image)
+void vvSlicer::GetExtremasAroundMousePointer(double & min, double & max, vtkImageData *image, vtkTransform *transform)
 {
   //Get mouse pointer position in view coordinates
-  double fLocalExtents[6];
+  double corner1[3];
+  double corner2[3];
   for(int i=0; i<3; i++) {
-    fLocalExtents[i*2  ] = mCurrent[i];
-    fLocalExtents[i*2+1] = mCurrent[i];
+    corner1[i] = mCurrent[i];
+    corner2[i] = mCurrent[i];
   }
-  this->Renderer->WorldToView(fLocalExtents[0], fLocalExtents[2], fLocalExtents[4]);
-  this->Renderer->WorldToView(fLocalExtents[1], fLocalExtents[3], fLocalExtents[5]);
-  for(int i=0; i<3; i++) {
-    if (i!=SliceOrientation) { //SR: assumes that SliceOrientation is valid in ViewCoordinates (???)
-      fLocalExtents[i*2  ] -= 0.2;
-      fLocalExtents[i*2+1] += 0.2;
-    }
-  }
-  this->Renderer->ViewToWorld(fLocalExtents[0], fLocalExtents[2], fLocalExtents[4]);
-  this->Renderer->ViewToWorld(fLocalExtents[1], fLocalExtents[3], fLocalExtents[5]);
+  this->Renderer->WorldToView(corner1[0], corner1[1], corner1[2]);
+  this->Renderer->WorldToView(corner2[0], corner2[1], corner2[2]);
+
+  // In view coordinates, x is the slicer width and y is the slicer height are the in-plane axis
+  int w, h;
+  this->Renderer->GetTiledSize(&w, &h);
+  corner1[0] -= 0.2*h/(double)w;
+  corner2[0] += 0.2*h/(double)w;
+  corner1[1] -= 0.2;
+  corner2[1] += 0.2;
+  this->Renderer->ViewToWorld(corner1[0], corner1[1], corner1[2]);
+  this->Renderer->ViewToWorld(corner2[0], corner2[1], corner2[2]);
 
   //Convert to image pixel coordinates (rounded)
+  transform->TransformPoint(corner1, corner1);
+  transform->TransformPoint(corner2, corner2);
   int iLocalExtents[6];
   for(int i=0; i<3; i++) {
-    fLocalExtents[i*2  ] = (fLocalExtents[i*2  ] - image->GetOrigin()[i])/image->GetSpacing()[i];
-    fLocalExtents[i*2+1] = (fLocalExtents[i*2+1] - image->GetOrigin()[i])/image->GetSpacing()[i];
+    corner1[i] = (corner1[i] - image->GetOrigin()[i])/image->GetSpacing()[i];
+    corner2[i] = (corner2[i] - image->GetOrigin()[i])/image->GetSpacing()[i];
 
-    iLocalExtents[i*2  ] = lrint(fLocalExtents[i*2  ]);
-    iLocalExtents[i*2+1] = lrint(fLocalExtents[i*2+1]);
+    iLocalExtents[i*2  ] = lrint(corner1[i]);
+    iLocalExtents[i*2+1] = lrint(corner2[i]);
 
     if(iLocalExtents[i*2  ]>iLocalExtents[i*2+1])
       std::swap(iLocalExtents[i*2], iLocalExtents[i*2+1]);
index b9cc334047acbd6d74e82da91d9714ef7cbbb6cc..c09001dcb38e90d66080459f0152d4ea77c80e28 100644 (file)
@@ -154,7 +154,7 @@ public:
   void SetCornerAnnotationVisibility(bool s);
   bool GetCornerAnnotationVisibility();
 
-  void GetExtremasAroundMousePointer(double & min, double & max, vtkImageData *image);
+  void GetExtremasAroundMousePointer(double & min, double & max, vtkImageData *image, vtkTransform *transform);
 
   void UpdateLandmarks();
   void ForceUpdateDisplayExtent();
index a787370e70629b8d1ec3814ff02b8d9970fad6bc..3f6f9139fc2e1bec9540eb3480dc49c52b2fdc34 100644 (file)
@@ -1117,13 +1117,17 @@ void vvSlicerManager::SetLocalColorWindowing(const int slicer, const bool bCtrlK
   double min, max;
   int t = this->mSlicers[slicer]->GetTSlice();
   if(bCtrlKey && this->mSlicers[slicer]->GetFusion()) {
-    this->mSlicers[slicer]->GetExtremasAroundMousePointer(min, max, this->mSlicers[slicer]->GetFusion()->GetVTKImages()[t]);
+    this->mSlicers[slicer]->GetExtremasAroundMousePointer(min, max,
+                                                          this->mSlicers[slicer]->GetFusion()->GetVTKImages()[t],
+                                                          this->mSlicers[slicer]->GetFusion()->GetTransform());
     this->SetFusionWindow(max-min);
     this->SetFusionLevel(0.5*(min+max));
     this->SetColorMap(mColorMap);
   }
   else if(bCtrlKey && this->mSlicers[slicer]->GetOverlay()) {
-    this->mSlicers[slicer]->GetExtremasAroundMousePointer(min, max, this->mSlicers[slicer]->GetOverlay()->GetVTKImages()[t]);
+    this->mSlicers[slicer]->GetExtremasAroundMousePointer(min, max,
+                                                          this->mSlicers[slicer]->GetOverlay()->GetVTKImages()[t],
+                                                          this->mSlicers[slicer]->GetOverlay()->GetTransform());
     if(this->mSlicers[slicer]->GetLinkOverlayWindowLevel()){
       this->SetColorWindow(max-min);
       this->SetColorLevel(0.5*(min+max));
@@ -1133,7 +1137,9 @@ void vvSlicerManager::SetLocalColorWindowing(const int slicer, const bool bCtrlK
     }
   }
   else {
-    this->mSlicers[slicer]->GetExtremasAroundMousePointer(min, max, this->mSlicers[slicer]->GetInput());
+    this->mSlicers[slicer]->GetExtremasAroundMousePointer(min, max,
+                                                          this->mSlicers[slicer]->GetImage()->GetVTKImages()[t],
+                                                          this->mSlicers[slicer]->GetImage()->GetTransform());
     this->SetColorWindow(max-min);
     this->SetColorLevel(0.5*(min+max));
     this->SetPreset(6);