]> Creatis software - clitk.git/commitdiff
Merge branch 'master' of git.creatis.insa-lyon.fr:clitk
authorBenoît Presles <benoit.presles@creatis.insa-lyon.fr>
Mon, 4 Feb 2013 18:22:31 +0000 (19:22 +0100)
committerBenoît Presles <benoit.presles@creatis.insa-lyon.fr>
Mon, 4 Feb 2013 18:22:31 +0000 (19:22 +0100)
26 files changed:
cmake/FindROOT.cmake [moved from cmake/FindROOT.cmake1 with 94% similarity]
cmake/FindROOT.cmake2 [deleted file]
registration/clitkConvertBLUTCoeffsToVFFilter.txx
tools/CMakeLists.txt
tools/clitkDicom2Image.cxx
tools/clitkDicom2Image.ggo
tools/clitkImageArithmGenericFilter.cxx
tools/clitkImageArithmGenericFilter.h
tools/clitkImageArithmGenericFilter.txx
tools/clitkVFInterpolate.cxx [new file with mode: 0644]
tools/clitkVFInterpolate.ggo [new file with mode: 0644]
tools/clitkVFInterpolateGenericFilter.cxx [new file with mode: 0644]
tools/clitkVFInterpolateGenericFilter.h [new file with mode: 0644]
tools/clitkVFInterpolateGenericFilter.txx [new file with mode: 0644]
tools/clitkVectorArithm.cxx [new file with mode: 0644]
tools/clitkVectorArithm.ggo [new file with mode: 0644]
tools/clitkVectorArithmGenericFilter.cxx [new file with mode: 0644]
tools/clitkVectorArithmGenericFilter.h [new file with mode: 0644]
tools/clitkVectorArithmGenericFilter.txx [new file with mode: 0644]
vv/qt_ui/vvMainWindow.ui
vv/vvMainWindow.cxx
vv/vvSlicer.cxx
vv/vvSlicer.h
vv/vvSlicerManager.cxx
vv/vvSlicerManager.h
vv/vvSlicerManagerCommand.cxx

similarity index 94%
rename from cmake/FindROOT.cmake1
rename to cmake/FindROOT.cmake
index d01b212a6751eb0b34e49149d3166026bacf7f67..db14f988662d855e6bd8a44129ad86137f2aa6e2 100644 (file)
@@ -8,30 +8,22 @@
 # This module defines a number of key variables and macros.
 
 
-MESSAGE("Looking for Root...")
 MESSAGE(STATUS "Looking for Root...")
 
-SET(ROOT_CONFIG_SEARCHPATH
-  ${SIMPATH}/tools/root/bin
-  $ENV{ROOTSYS}/bin
-)
-
 SET(ROOT_DEFINITIONS "")
 
 SET(ROOT_INSTALLED_VERSION_TOO_OLD FALSE)
 
 SET(ROOT_CONFIG_EXECUTABLE ROOT_CONFIG_EXECUTABLE-NOTFOUND)
 
-FIND_PROGRAM(ROOT_CONFIG_EXECUTABLE NAMES root-config PATHS
-   ${ROOT_CONFIG_SEARCHPATH}
-   NO_SYSTEM_ENVIRONMENT_PATH)
+FIND_PROGRAM(ROOT_CONFIG_EXECUTABLE NAMES root-config PATHS)
     
 IF (${ROOT_CONFIG_EXECUTABLE} MATCHES "ROOT_CONFIG_EXECUTABLE-NOTFOUND")
   MESSAGE( FATAL_ERROR "ROOT not installed in the searchpath and ROOTSYS is not set. Please
  set ROOTSYS or add the path to your ROOT installation in the Macro FindROOT.cmake in the
  subdirectory cmake/modules.")
 ELSE (${ROOT_CONFIG_EXECUTABLE} MATCHES "ROOT_CONFIG_EXECUTABLE-NOTFOUND")
-  MESSAGE("root-config found")
+               MESSAGE(STATUS "root-config found")
   STRING(REGEX REPLACE "(^.*)/bin/root-config" "\\1" test ${ROOT_CONFIG_EXECUTABLE}) 
   SET( ENV{ROOTSYS} ${test})
   set( ROOTSYS ${test})
@@ -47,9 +39,6 @@ IF (ROOT_CONFIG_EXECUTABLE)
   MESSAGE(STATUS "Looking for Root... - found $ENV{ROOTSYS}/bin/root")
   MESSAGE(STATUS "Looking for Root... - version ${ROOTVERSION} ")   
 
-  MESSAGE( "Looking for Root... - found $ENV{ROOTSYS}/bin/root")
-  MESSAGE( "Looking for Root... - version ${ROOTVERSION} ")   
-
   # we need at least version 5.00/00
   IF (NOT ROOT_MIN_VERSION)
     SET(ROOT_MIN_VERSION "5.00/00")
@@ -226,4 +215,4 @@ MACRO (ROOT_GENERATE_DICTIONARY INFILES LINKDEF_FILE OUTFILE INCLUDE_DIRS_IN)
 
 ENDMACRO (ROOT_GENERATE_DICTIONARY)
 
-#MESSAGE("la")
\ No newline at end of file
+#MESSAGE("la")
diff --git a/cmake/FindROOT.cmake2 b/cmake/FindROOT.cmake2
deleted file mode 100644 (file)
index 02b456a..0000000
+++ /dev/null
@@ -1,225 +0,0 @@
-# - Find ROOT instalation # This module tries to find the ROOT installation on your system.
-# It tries to find the root-config script which gives you all the needed information.
-# If the system variable ROOTSYS is set this is straight forward.
-# If not the module uses the pathes given in ROOT_CONFIG_SEARCHPATH.
-# If you need an other path you should add this path to this varaible.  
-# The root-config script is then used to detect basically everything else.
-# This module defines a number of key variables and macros.
-
-
-MESSAGE(STATUS "Looking for Root...")
-
-SET(ROOT_CONFIG_SEARCHPATH
-  $ENV{ROOTSYS}/bin
-  )
-
-SET(ROOT_DEFINITIONS "")
-
-SET(ROOT_INSTALLED_VERSION_TOO_OLD FALSE)
-
-SET(ROOT_CONFIG_EXECUTABLE ROOT_CONFIG_EXECUTABLE-NOTFOUND)
-
-FIND_PROGRAM(ROOT_CONFIG_EXECUTABLE NAMES root-config PATHS
-  ${ROOT_CONFIG_SEARCHPATH}
-  NO_SYSTEM_ENVIRONMENT_PATH)
-
-FIND_FILE( RVERSION_H NAMES RVersion.h PATHS $ENV{ROOTSYS}/include )
-
-IF ( RVERSION_H )
-  FILE( READ ${RVERSION_H} RVERS_CONTENT )
-  STRING( REGEX MATCH "#define ROOT_RELEASE \"[^\n]+\"\n" _line "${RVERS_CONTENT}" )
-  STRING( REGEX REPLACE "#define ROOT_RELEASE \"([^\n]+)\"\n" "\\1" _match "${_line}")
-  IF(_match)
-    SET( ROOTVERSION ${_match})
-  ENDIF(_match)
-ENDIF( RVERSION_H )
-
-
-IF (ROOTVERSION)
-  
-  SET(ROOT_FOUND FALSE)
-
-  MESSAGE(STATUS "Looking for Root... - found $ENV{ROOTSYS}/bin/root")
-  MESSAGE(STATUS "Looking for Root... - version ${ROOTVERSION} ")   
-
-  # we need at least version 5.00/00
-  IF (NOT ROOT_MIN_VERSION)
-    SET(ROOT_MIN_VERSION "5.00/00")
-  ENDIF (NOT ROOT_MIN_VERSION)
-  
-  # now parse the parts of the user given version string into variables
-  STRING(REGEX REPLACE "^([0-9]+)\\.[0-9][0-9]+\\/[0-9][0-9]+" "\\1" req_root_major_vers "${ROOT_MIN_VERSION}")
-  STRING(REGEX REPLACE "^[0-9]+\\.([0-9][0-9])+\\/[0-9][0-9]+.*" "\\1" req_root_minor_vers "${ROOT_MIN_VERSION}")
-  STRING(REGEX REPLACE "^[0-9]+\\.[0-9][0-9]+\\/([0-9][0-9]+)" "\\1" req_root_patch_vers "${ROOT_MIN_VERSION}")
-  
-  # and now the version string given by qmake
-  STRING(REGEX REPLACE "^([0-9]+)\\.[0-9][0-9]+\\/[0-9][0-9]+.*" "\\1" found_root_major_vers "${ROOTVERSION}")
-  STRING(REGEX REPLACE "^[0-9]+\\.([0-9][0-9])+\\/[0-9][0-9]+.*" "\\1" found_root_minor_vers "${ROOTVERSION}")
-  STRING(REGEX REPLACE "^[0-9]+\\.[0-9][0-9]+\\/([0-9][0-9]+).*" "\\1" found_root_patch_vers "${ROOTVERSION}")
-
-  IF (found_root_major_vers LESS 5)
-    MESSAGE( FATAL_ERROR "Invalid ROOT version \"${ROOTERSION}\", at least major version 4 is required, e.g. \"5.00/00\"")
-  ENDIF (found_root_major_vers LESS 5)
-
-  # compute an overall version number which can be compared at once
-  MATH(EXPR req_vers "${req_root_major_vers}*10000 + ${req_root_minor_vers}*100 + ${req_root_patch_vers}")
-  MATH(EXPR found_vers "${found_root_major_vers}*10000 + ${found_root_minor_vers}*100 + ${found_root_patch_vers}")
-  
-  IF (found_vers LESS req_vers)
-    SET(ROOT_FOUND FALSE)
-    SET(ROOT_INSTALLED_VERSION_TOO_OLD TRUE)
-  ELSE (found_vers LESS req_vers)
-    SET(ROOT_FOUND TRUE)
-  ENDIF (found_vers LESS req_vers)
-
-ENDIF (ROOTVERSION)
-
-
-IF (ROOT_FOUND)
-
-  # ask root-config for the library dir
-  # Set ROOT_LIBRARY_DIR
-  IF( WIN32 )
-    SET( ROOT_LIBRARY_DIR $ENV{ROOTSYS}/lib )
-    SET( ROOT_INCLUDE_DIR $ENV{ROOTSYS}/include )
-    SET( ROOT_BINARY_DIR  $ENV{ROOTSYS}/bin )
-
-  ELSE( WIN32 )
-
-    EXEC_PROGRAM( ${ROOT_CONFIG_EXECUTABLE}
-      ARGS "--libdir"
-      OUTPUT_VARIABLE ROOT_LIBRARY_DIR_TMP )
-
-    IF(EXISTS "${ROOT_LIBRARY_DIR_TMP}")
-      SET(ROOT_LIBRARY_DIR ${ROOT_LIBRARY_DIR_TMP} )
-    ELSE(EXISTS "${ROOT_LIBRARY_DIR_TMP}")
-      MESSAGE("Warning: ROOT_CONFIG_EXECUTABLE reported ${ROOT_LIBRARY_DIR_TMP} as library path,")
-      MESSAGE("Warning: but ${ROOT_LIBRARY_DIR_TMP} does NOT exist, ROOT must NOT be installed correctly.")
-    ENDIF(EXISTS "${ROOT_LIBRARY_DIR_TMP}")
-    
-    # ask root-config for the binary dir
-    EXEC_PROGRAM(${ROOT_CONFIG_EXECUTABLE}
-      ARGS "--bindir"
-      OUTPUT_VARIABLE root_bins )
-    SET(ROOT_BINARY_DIR ${root_bins})
-
-    # ask root-config for the include dir
-    EXEC_PROGRAM( ${ROOT_CONFIG_EXECUTABLE}
-      ARGS "--incdir" 
-      OUTPUT_VARIABLE root_headers )
-    SET(ROOT_INCLUDE_DIR ${root_headers})
-    # CACHE INTERNAL "")
-
-    # ask root-config for the library varaibles
-    EXEC_PROGRAM( ${ROOT_CONFIG_EXECUTABLE}
-      ARGS "--noldflags --noauxlibs --libs" 
-      OUTPUT_VARIABLE root_flags )
-
-    #  STRING(REGEX MATCHALL "([^ ])+"  root_libs_all ${root_flags})
-    #  STRING(REGEX MATCHALL "-L([^ ])+"  root_library ${root_flags})
-    #  REMOVE_FROM_LIST(root_flags "${root_libs_all}" "${root_library}")
-
-    SET(ROOT_LIBRARIES ${root_flags})
-
-  ENDIF( WIN32 )
-
-  # Make variables changeble to the advanced user
-  MARK_AS_ADVANCED( ROOT_LIBRARY_DIR ROOT_INCLUDE_DIR ROOT_DEFINITIONS)
-
-  # Set ROOT_INCLUDES
-  SET( ROOT_INCLUDES ${ROOT_INCLUDE_DIR})
-
-  SET(LD_LIBRARY_PATH ${LD_LIBRARY_PATH} ${ROOT_LIBRARY_DIR})
-
-  #######################################
-  #
-  #       Check the executables of ROOT 
-  #          ( rootcint ) 
-  #
-  #######################################
-
-  FIND_PROGRAM(ROOT_CINT_EXECUTABLE
-    NAMES rootcint
-    PATHS ${ROOT_BINARY_DIR}
-    NO_DEFAULT_PATH
-    )
-
-ENDIF (ROOT_FOUND)
-
-
-
-###########################################
-#
-#       Macros for building ROOT dictionary
-#
-###########################################
-
-MACRO (ROOT_GENERATE_DICTIONARY_OLD )
-  
-  set(INFILES "")    
-
-  foreach (_current_FILE ${ARGN})
-
-    IF (${_current_FILE} MATCHES "^.*\\.h$")
-      IF (${_current_FILE} MATCHES "^.*Link.*$")
-        set(LINKDEF_FILE ${_current_FILE})
-      ELSE (${_current_FILE} MATCHES "^.*Link.*$")
-        set(INFILES ${INFILES} ${_current_FILE})
-      ENDIF (${_current_FILE} MATCHES "^.*Link.*$")
-    ELSE (${_current_FILE} MATCHES "^.*\\.h$")
-      IF (${_current_FILE} MATCHES "^.*\\.cxx$")
-        set(OUTFILE ${_current_FILE})
-      ELSE (${_current_FILE} MATCHES "^.*\\.cxx$")
-        set(INCLUDE_DIRS ${INCLUDE_DIRS} -I${_current_FILE})   
-      ENDIF (${_current_FILE} MATCHES "^.*\\.cxx$")
-    ENDIF (${_current_FILE} MATCHES "^.*\\.h$")
-    
-  endforeach (_current_FILE ${ARGN})
-  
-  #  MESSAGE("INFILES: ${INFILES}")
-  #  MESSAGE("OutFILE: ${OUTFILE}")
-  #  MESSAGE("LINKDEF_FILE: ${LINKDEF_FILE}")
-  #  MESSAGE("INCLUDE_DIRS: ${INCLUDE_DIRS}")
-
-  STRING(REGEX REPLACE "(^.*).cxx" "\\1.h" bla "${OUTFILE}")
-  #   MESSAGE("BLA: ${bla}")
-  SET (OUTFILES ${OUTFILE} ${bla})
-
-  ADD_CUSTOM_COMMAND(OUTPUT ${OUTFILES}
-    COMMAND ${ROOT_CINT_EXECUTABLE}
-    ARGS -f ${OUTFILE} -c -DHAVE_CONFIG_H ${INCLUDE_DIRS} ${INFILES} ${LINKDEF_FILE} DEPENDS ${INFILES})
-
-  #   MESSAGE("ROOT_CINT_EXECUTABLE has created the dictionary ${OUTFILE}")
-
-ENDMACRO (ROOT_GENERATE_DICTIONARY_OLD)
-
-###########################################
-#
-#       Macros for building ROOT dictionary
-#
-###########################################
-
-MACRO (ROOT_GENERATE_DICTIONARY INFILES LINKDEF_FILE OUTFILE INCLUDE_DIRS_IN)
-  
-  set(INCLUDE_DIRS)
-
-  foreach (_current_FILE ${INCLUDE_DIRS_IN})
-    set(INCLUDE_DIRS ${INCLUDE_DIRS} -I${_current_FILE})   
-  endforeach (_current_FILE ${INCLUDE_DIRS_IN})
-  
-
-  #  MESSAGE("INFILES: ${INFILES}")
-  #  MESSAGE("OutFILE: ${OUTFILE}")
-  #  MESSAGE("LINKDEF_FILE: ${LINKDEF_FILE}")
-  #  MESSAGE("INCLUDE_DIRS: ${INCLUDE_DIRS}")
-
-  STRING(REGEX REPLACE "^(.*)\\.(.*)$" "\\1.h" bla "${OUTFILE}")
-  #  MESSAGE("BLA: ${bla}")
-  SET (OUTFILES ${OUTFILE} ${bla})
-
-  ADD_CUSTOM_COMMAND(OUTPUT ${OUTFILES}
-    COMMAND ${ROOT_CINT_EXECUTABLE}
-    ARGS -f ${OUTFILE} -c -DHAVE_CONFIG_H ${INCLUDE_DIRS} ${INFILES} ${LINKDEF_FILE} DEPENDS ${INFILES})
-
-ENDMACRO (ROOT_GENERATE_DICTIONARY)
-
index 491d049eaaed032e770184128d64feb55b61c227..ae1f9d539bd70d9425efbab1a760e324ba93771a 100644 (file)
@@ -162,8 +162,23 @@ namespace clitk
           component_filter[i]->Update();
           coefficient_images[i] = component_filter[i]->GetOutput();
       }
+
 #if ITK_VERSION_MAJOR >= 4
-      m_ITKTransform->SetCoefficientImages(coefficient_images);
+      // RP: 16/01/2013
+      // ATTENTION: Apparently, there's a bug in the SetCoefficientImages function of ITK 4.x
+      // I needed to use SetParametersByValue instead.
+      //
+      typename ITKTransformType::ParametersType params(input->GetPixelContainer()->Size() * BLUTCoefficientImageType::ImageDimension);
+      for (unsigned int i=0; i < BLUTCoefficientImageType::ImageDimension; i++) {
+        for (unsigned int j=0; j < coefficient_images[i]->GetPixelContainer()->Size(); j++)
+          params[input->GetPixelContainer()->Size() * i + j] = coefficient_images[i]->GetPixelContainer()->GetBufferPointer()[j]; 
+      }
+
+      m_ITKTransform->SetGridOrigin(input->GetOrigin());
+      m_ITKTransform->SetGridDirection(input->GetDirection());
+      m_ITKTransform->SetGridRegion(input->GetLargestPossibleRegion());
+      m_ITKTransform->SetGridSpacing(input->GetSpacing());
+      m_ITKTransform->SetParametersByValue(params);
 #else
       m_ITKTransform->SetCoefficientImage(coefficient_images);
 #endif
index 505c2109f1d2a0b48ea66394cd629df46290ebd2..71937728a25aea7f049db5e22bf1a9dbed95b14e 100644 (file)
@@ -11,6 +11,9 @@ ADD_LIBRARY(clitkBinarizeImageLib clitkBinarizeImageGenericFilter.cxx ${clitkBin
 WRAP_GGO(clitkImageArithm_GGO_C clitkImageArithm.ggo)
 ADD_LIBRARY(clitkImageArithmImageLib clitkImageArithmGenericFilter.cxx ${clitkImageArithm_GGO_C})
 
+WRAP_GGO(clitkVectorArithm_GGO_C clitkVectorArithm.ggo)
+ADD_LIBRARY(clitkVectorArithmLib clitkVectorArithmGenericFilter.cxx ${clitkVectorArithm_GGO_C})
+
 WRAP_GGO(clitkResampleImage_GGO_C clitkResampleImage.ggo)
 ADD_LIBRARY(clitkResampleImageLib clitkResampleImageGenericFilter.cxx ${clitkResampleImage_GGO_C})
 
@@ -54,6 +57,11 @@ IF (CLITK_BUILD_TOOLS)
   TARGET_LINK_LIBRARIES(clitkVFResample clitkCommon ${ITK_LIBRARIES})
   SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkVFResample)
 
+  WRAP_GGO(clitkVFInterpolate_GGO_C clitkVFInterpolate.ggo)
+  ADD_EXECUTABLE(clitkVFInterpolate clitkVFInterpolate.cxx clitkVFInterpolateGenericFilter.cxx ${clitkVFInterpolate_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkVFInterpolate clitkCommon ${ITK_LIBRARIES})
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkVFInterpolate)
+
   WRAP_GGO(clitkImageCreate_GGO_C clitkImageCreate.ggo)
   ADD_EXECUTABLE(clitkImageCreate clitkImageCreate.cxx ${clitkImageCreate_GGO_C})
   TARGET_LINK_LIBRARIES(clitkImageCreate clitkCommon  ${ITK_LIBRARIES})
@@ -109,6 +117,10 @@ IF (CLITK_BUILD_TOOLS)
   TARGET_LINK_LIBRARIES(clitkImageArithm clitkImageArithmImageLib clitkCommon ${ITK_LIBRARIES} )
   SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkImageArithm)
 
+  ADD_EXECUTABLE(clitkVectorArithm clitkVectorArithm.cxx)
+  TARGET_LINK_LIBRARIES(clitkVectorArithm clitkVectorArithmLib clitkCommon ${ITK_LIBRARIES} )
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkVectorArithm)
+
   WRAP_GGO(clitkUnsharpMask_GGO_C clitkUnsharpMask.ggo)
   ADD_EXECUTABLE(clitkUnsharpMask clitkUnsharpMask.cxx ${clitkUnsharpMask_GGO_C})
   TARGET_LINK_LIBRARIES(clitkUnsharpMask clitkCommon ${ITK_LIBRARIES} ) 
index 07a85653edc37eba8c30262676b860b5d1038207..2819fdea6a03fdf5f3bb47cd854deee5c942c437 100644 (file)
@@ -30,6 +30,8 @@
   #include <gdcmReader.h>
 #endif
 
+#include <set>
+
 //====================================================================
 int main(int argc, char * argv[])
 {
@@ -52,8 +54,11 @@ int main(int argc, char * argv[])
 
   //===========================================
   /// Get slices locations ...
-  std::vector<double> theorigin(3);
-  std::vector<double> sliceLocations;
+  int series_number = -1;
+  std::set<int> series_numbers;
+  std::map< int, std::vector<double> > theorigin;
+  std::map< int, std::vector<double> > sliceLocations;
+  std::map< int, std::vector<std::string> > seriesFiles;
   for(unsigned int i=0; i<args_info.inputs_num; i++) {
     //std::cout << "Reading <" << input_files[i] << std::endl;
 #if GDCM_MAJOR_VERSION == 2
@@ -62,10 +67,23 @@ int main(int argc, char * argv[])
     gdcm::Reader hreader;
     hreader.SetFileName(input_files[i].c_str());
     hreader.Read();
-    theorigin = gdcm::ImageHelper::GetOriginValue(hreader.GetFile());
-    sliceLocations.push_back(theorigin[2]);
-    gdcm::Attribute<0x28, 0x100> pixel_size;
     gdcm::DataSet& ds = hreader.GetFile().GetDataSet();
+
+    if (args_info.extract_series_flag) {
+      gdcm::Attribute<0x20,0x11> series_number_att;
+      series_number_att.SetFromDataSet(hreader.GetFile().GetDataSet());
+      series_number = series_number_att.GetValue();
+    }
+    
+    series_numbers.insert(series_number);
+    theorigin[series_number] = gdcm::ImageHelper::GetOriginValue(hreader.GetFile());
+    std::cout << "theorigin[series_number][0] " << theorigin[series_number][0] << std::endl;
+    std::cout << "theorigin[series_number][1] " << theorigin[series_number][1] << std::endl;
+    std::cout << "theorigin[series_number][2] " << theorigin[series_number][2] << std::endl;
+    sliceLocations[series_number].push_back(theorigin[series_number][2]);
+    seriesFiles[series_number].push_back(input_files[i]);
+    
+    gdcm::Attribute<0x28, 0x100> pixel_size;
     pixel_size.SetFromDataSet(ds);
     if (pixel_size.GetValue() != 16)
     {
@@ -80,10 +98,18 @@ int main(int argc, char * argv[])
   header->SetFileName(input_files[i]);
   header->SetMaxSizeLoadEntry(16384); // required ?
   header->Load();
-  theorigin[0] = header->GetXOrigin();
-  theorigin[1] = header->GetYOrigin();
-  theorigin[2] = header->GetZOrigin();
-  sliceLocations.push_back(theorigin[2]);
+
+  if (args_info.extract_series_flag) {
+    series_number = atoi(header->GetEntryValue(0x20,0x11).c_str());
+  }
+  
+  series_numbers.insert(series_number);
+  theorigin[series_number].resize(3);
+  theorigin[series_number][0] = header->GetXOrigin();
+  theorigin[series_number][1] = header->GetYOrigin();
+  theorigin[series_number][2] = header->GetZOrigin();
+  sliceLocations[series_number].push_back(theorigin[series_number][2]);
+  seriesFiles[series_number].push_back(input_files[i]);
   if (header->GetPixelSize() != 2) {
     std::cerr << "Pixel type 2 bytes ! " << std::endl;
     std::cerr << "In file " << input_files[i] << std::endl;
@@ -94,87 +120,103 @@ int main(int argc, char * argv[])
 
   //===========================================
   // Sort slices locations ...
-  std::vector<int> sliceIndex;
-  clitk::GetSortedIndex(sliceLocations, sliceIndex);
-  if (args_info.verboseSliceLocation_flag) {
-    std::cout << sliceLocations[sliceIndex[0]] << " -> "
-              << sliceIndex[0] << " / " << 0 << " => "
-              << "0 mm "
-              << input_files[sliceIndex[0]]
-              << std::endl;
-    for(unsigned int i=1; i<sliceIndex.size(); i++) {
-      std::cout << sliceLocations[sliceIndex[i]] << " -> "
-                << sliceIndex[i] << " / " << i << " => "
-                << sliceLocations[sliceIndex[i]] - sliceLocations[sliceIndex[i-1]]
-                << "mm "
-                << input_files[sliceIndex[i]]
+  std::set<int>::iterator sn = series_numbers.begin();
+  while ( sn != series_numbers.end() ) {
+    std::vector<double> locs = sliceLocations[*sn];
+    std::vector<double> origin = theorigin[*sn];
+    std::vector<std::string> files = seriesFiles[*sn];
+    std::vector<int> sliceIndex;
+    clitk::GetSortedIndex(locs, sliceIndex);
+    if (args_info.verboseSliceLocation_flag) {
+      std::cout << locs[sliceIndex[0]] << " -> "
+                << sliceIndex[0] << " / " << 0 << " => "
+                << "0 mm "
+                << files[sliceIndex[0]]
                 << std::endl;
-    }
-  }
-
-  //===========================================
-  // Analyze slices locations ...
-  double currentDist;
-  double dist=0;
-  double tolerance = args_info.tolerance_arg;
-  double previous = sliceLocations[sliceIndex[0]];
-  for(unsigned int i=1; i<sliceIndex.size(); i++) {
-    currentDist = sliceLocations[sliceIndex[i]]-previous;
-    if (i!=1) {
-      if (fabs(dist-currentDist) > tolerance) {
-        std::cout << "ERROR : " << std::endl
-                  << "Current slice pos is  = " << sliceLocations[sliceIndex[i]] << std::endl
-                  << "Previous slice pos is = " << previous << std::endl
-                  << "Current file is       = " << input_files[sliceIndex[i]] << std::endl
-                  << "Current index is      = " << i << std::endl
-                  << "Current sortindex is  = " << sliceIndex[i] << std::endl
-                  << "Current slice diff    = " << dist << std::endl
-                  << "Current error         = " << fabs(dist-currentDist) << std::endl;
-        exit(1);
+      for(unsigned int i=1; i<sliceIndex.size(); i++) {
+        std::cout << locs[sliceIndex[i]] << " -> "
+                  << sliceIndex[i] << " / " << i << " => "
+                  << locs[sliceIndex[i]] - locs[sliceIndex[i-1]]
+                  << "mm "
+                  << files[sliceIndex[i]]
+                  << std::endl;
       }
-    } else dist = currentDist;
-    previous = sliceLocations[sliceIndex[i]];
-  }
+    }
 
-  //===========================================
-  // Create ordered vector of filenames
-  std::vector<std::string> sorted_files;
-  sorted_files.resize(sliceIndex.size());
-  for(unsigned int i=0; i<sliceIndex.size(); i++)
-    sorted_files[i] = input_files[ sliceIndex[i] ];
+    //===========================================
+    // Analyze slices locations ...
+    double currentDist;
+    double dist=0;
+    double tolerance = args_info.tolerance_arg;
+    double previous = locs[sliceIndex[0]];
+    for(unsigned int i=1; i<sliceIndex.size(); i++) {
+      currentDist = locs[sliceIndex[i]]-previous;
+      if (i!=1) {
+        if (fabs(dist-currentDist) > tolerance) {
+          std::cout << "ERROR : " << std::endl
+                    << "Current slice pos is  = " << locs[sliceIndex[i]] << std::endl
+                    << "Previous slice pos is = " << previous << std::endl
+                    << "Current file is       = " << files[sliceIndex[i]] << std::endl
+                    << "Current index is      = " << i << std::endl
+                    << "Current sortindex is  = " << sliceIndex[i] << std::endl
+                    << "Current slice diff    = " << dist << std::endl
+                    << "Current error         = " << fabs(dist-currentDist) << std::endl;
+          exit(1);
+        }
+      } else dist = currentDist;
+      previous = locs[sliceIndex[i]];
+    }
 
-  //===========================================
-  // Read write serie
-  vvImageReader::Pointer reader = vvImageReader::New();
-  reader->SetInputFilenames(sorted_files);
-  reader->Update(vvImageReader::DICOM);
-  if (reader->GetLastError().size() != 0) {
-    std::cerr << reader->GetLastError() << std::endl;
-    return 1;
-  }
-  
-  vvImage::Pointer image = reader->GetOutput();
-  vtkImageData* vtk_image = image->GetFirstVTKImageData();
-  vtkImageChangeInformation* modifier = vtkImageChangeInformation::New();
-  if  (args_info.focal_origin_given) {
-    std::vector<double> spacing = image->GetSpacing();
-    std::vector<int> size = image->GetSize();
-    theorigin[0] = -spacing[0]*size[0]/2.0;
-    theorigin[1] = -spacing[1]*size[1]/2.0;
-    modifier->SetInput(vtk_image);
-    modifier->SetOutputOrigin(theorigin[0], theorigin[1], sliceLocations[sliceIndex[0]]);
-    modifier->Update();
-    vvImage::Pointer focal_image = vvImage::New();
-    focal_image->AddVtkImage(modifier->GetOutput());
-    image = focal_image;
-  }
+    //===========================================
+    // Create ordered vector of filenames
+    std::vector<std::string> sorted_files;
+    sorted_files.resize(sliceIndex.size());
+    for(unsigned int i=0; i<sliceIndex.size(); i++)
+      sorted_files[i] = files[ sliceIndex[i] ];
 
-  vvImageWriter::Pointer writer = vvImageWriter::New();
-  writer->SetInput(image);
-  writer->SetOutputFileName(args_info.output_arg);
-  writer->Update();
+    //===========================================
+    // Read write serie
+    vvImageReader::Pointer reader = vvImageReader::New();
+    reader->SetInputFilenames(sorted_files);
+    reader->Update(vvImageReader::DICOM);
+    if (reader->GetLastError().size() != 0) {
+      std::cerr << reader->GetLastError() << std::endl;
+      return 1;
+    }
+    
+    vvImage::Pointer image = reader->GetOutput();
+    vtkImageData* vtk_image = image->GetFirstVTKImageData();
+    vtkImageChangeInformation* modifier = vtkImageChangeInformation::New();
+    if  (args_info.focal_origin_given) {
+      std::vector<double> spacing = image->GetSpacing();
+      std::vector<int> size = image->GetSize();
+      origin[0] = -spacing[0]*size[0]/2.0;
+      origin[1] = -spacing[1]*size[1]/2.0;
+      modifier->SetInput(vtk_image);
+      modifier->SetOutputOrigin(origin[0], origin[1], locs[sliceIndex[0]]);
+      modifier->Update();
+      vvImage::Pointer focal_image = vvImage::New();
+      focal_image->AddVtkImage(modifier->GetOutput());
+      image = focal_image;
+    }
 
-  modifier->Delete();
+    std::string outfile;
+    if (series_numbers.size() == 1)
+      outfile = args_info.output_arg;
+    else {
+      std::ostringstream name;
+      name << *sn << "_" << args_info.output_arg;
+      outfile = name.str();
+    }
+    vvImageWriter::Pointer writer = vvImageWriter::New();
+    writer->SetInput(image);
+    writer->SetOutputFileName(outfile);
+    writer->Update();
 
+    modifier->Delete();
+    
+    sn++;
+  }
+  
   return 0;
 }
index fb511358b543b71c9d87d7b24466f98e14b99614..a2d3a89beb6cb8b89f1d80ee392752606683c8a2 100644 (file)
@@ -10,3 +10,4 @@ option "tolerance"     t "Tolerance for slice position"        double default="0" no
 option "output"      o "Output image filename"         string  yes
 option "std_input"   - "Take the like of input file from stdin, to support huge lists of filenames" flag off
 option "focal_origin" - "Output files with FOCAL-like origin, instead of the origin present in the dicom files" flag off
+option "extract_series" s "Identify different series in the file list and create the MHDs accordinly" flag off
index f0d55c292d8df6e4f18d3d29e426dff95f6420a6..2509b1a71d88ef5368ecea0d2717629a7430585d 100644 (file)
@@ -25,669 +25,6 @@ namespace clitk {
 //   template<>
 //   class ImageArithmGenericFilter<args_info_clitkImageArithm>;
 
-////////////////////////////////////////////////////////////////////
-  // specializations for itk::Vector<float, 3u>, 3u
-  template<>
-  template<>
-  void ImageArithmGenericFilter<args_info_clitkImageArithm>::UpdateWithInputImageType< itk::Image< itk::Vector<float, 3u>, 3u > >()
-  {
-    typedef itk::Image< itk::Vector<float, 3u>, 3u > ImageType;
-    
-    // Read input1
-    ImageType::Pointer input1 = this->GetInput<ImageType>(0);
-
-    // Set input image iterator
-    typedef itk::ImageRegionIterator<ImageType> IteratorType;
-    IteratorType it(input1, input1->GetLargestPossibleRegion());
-
-    // typedef input2
-    ImageType::Pointer input2 = NULL;
-    IteratorType it2;
-
-    /*
-    // Special case for normalisation
-    if (mTypeOfOperation == 12) {
-      typedef itk::MinimumMaximumImageCalculator<ImageType> MinMaxFilterType;
-      typename MinMaxFilterType::Pointer ff = MinMaxFilterType::New();
-      ff->SetImage(input1);
-      ff->ComputeMaximum();
-      mScalar = ff->GetMaximum();
-      mTypeOfOperation = 11; // divide
-    }
-    */
-
-    if (mIsOperationUseASecondImage) {
-        // Read input2
-        input2 = this->GetInput<ImageType>(1);
-        // Set input image iterator
-        it2 = IteratorType(input2, input2->GetLargestPossibleRegion());
-        // Check dimension
-        if (!clitk::HaveSameSize<ImageType, ImageType>(input1, input2)) {
-          itkExceptionMacro(<< "The images (input and input2) must have the same size");
-        }
-        if(!clitk::HaveSameSpacing<ImageType, ImageType>(input1, input2)) {
-          itkWarningMacro(<< "The images (input and input2) do not have the same spacing. "
-                          << "Using first input's information.");
-        }
-    }
-
-    /*
-    // Check if overwrite and outputisfloat and pixeltype is not float -> do not overwrite
-    if (mOverwriteInputImage && mOutputIsFloat && (typeid(typename ImageType::PixelType) != typeid(float))) {
-      // std::cerr << "Warning. Could not use both mOverwriteInputImage and mOutputIsFloat, because input is "
-      //                     << typeid(PixelType).name()
-      //                     << std::endl;
-      mOverwriteInputImage = false;
-    }
-    */
-    
-    // ---------------- Overwrite input Image ---------------------
-    if (mOverwriteInputImage) {
-      // Set output iterator (to input1)
-      IteratorType ito = IteratorType(input1, input1->GetLargestPossibleRegion());
-      if (mIsOperationUseASecondImage) ComputeImage(it, it2, ito);
-      else ComputeImage(it, ito);
-      this->SetNextOutput<ImageType>(input1);
-    }
-    // ---------------- Create new output Image ---------------------
-    else {
-      /*if (mOutputIsFloat) {
-        // Create output image
-        typedef itk::Image<float,ImageType::ImageDimension> OutputImageType;
-        typename OutputImageType::Pointer output = OutputImageType::New();
-        output->SetRegions(input1->GetLargestPossibleRegion());
-        output->SetOrigin(input1->GetOrigin());
-        output->SetSpacing(input1->GetSpacing());
-        output->Allocate();
-        // Set output iterator
-        typedef itk::ImageRegionIterator<OutputImageType> IteratorOutputType;
-        IteratorOutputType ito = IteratorOutputType(output, output->GetLargestPossibleRegion());
-        if (mIsOperationUseASecondImage) ComputeImage(it, it2, ito);
-        else ComputeImage(it, ito);
-        this->template SetNextOutput<OutputImageType>(output);
-      } else*/ {
-        // Create output image
-        typedef ImageType OutputImageType;
-        OutputImageType::Pointer output = OutputImageType::New();
-        output->SetRegions(input1->GetLargestPossibleRegion());
-        output->SetOrigin(input1->GetOrigin());
-        output->SetSpacing(input1->GetSpacing());
-        output->Allocate();
-        // Set output iterator
-        typedef itk::ImageRegionIterator<OutputImageType> IteratorOutputType;
-        IteratorOutputType ito = IteratorOutputType(output, output->GetLargestPossibleRegion());
-        if (mIsOperationUseASecondImage) ComputeImage(it, it2, ito);
-        else ComputeImage(it, ito);
-        this->SetNextOutput<OutputImageType>(output);
-      }
-    }
-  }
-
-  template<>
-  template<>
-  void ImageArithmGenericFilter<args_info_clitkImageArithm>::ComputeImage< 
-    itk::ImageRegionIterator< itk::Image< itk::Vector<float, 3u>, 3u > >, 
-    itk::ImageRegionIterator< itk::Image< itk::Vector<float, 3u>, 3u > > >
-    (itk::ImageRegionIterator< itk::Image< itk::Vector<float, 3u>, 3u > > it, 
-    itk::ImageRegionIterator< itk::Image< itk::Vector<float, 3u>, 3u > > ito)
-  {
-    typedef itk::ImageRegionIterator< itk::Image< itk::Vector<float, 3u>, 3u > > Iter2;
-
-    ito.GoToBegin();
-    it.GoToBegin();
-    
-    typedef Iter2::PixelType PixelType;
-
-    PixelType scalar_vector;
-    scalar_vector.Fill(mScalar);
-    
-    // Perform operation
-    switch (mTypeOfOperation) {
-    case 0: // Addition
-      while (!it.IsAtEnd()) {
-        ito.Set(it.Get() + scalar_vector);
-        ++it;
-        ++ito;
-      }
-      break;
-    case 1: // Multiply
-      while (!it.IsAtEnd()) {
-        ito.Set(it.Get() * mScalar);
-        ++it;
-        ++ito;
-      }
-      break;
-      /*
-    case 2: // Inverse
-      while (!it.IsAtEnd()) {
-        if (it.Get() != 0)
-          ito.Set(mScalar / it.Get()));
-        else ito.Set(mDefaultPixelValue);
-        ++it;
-        ++ito;
-      }
-      break;
-    case 3: // Max
-      while (!it.IsAtEnd()) {
-        if (it.Get() < mScalar) ito.Set(PixelTypeDownCast<double, PixelType>(mScalar));
-        else ito.Set(PixelTypeDownCast<double, PixelType>(it.Get()));
-        ++it;
-        ++ito;
-      }
-      break;
-    case 4: // Min
-      while (!it.IsAtEnd()) {
-        if (it.Get() > mScalar) ito.Set(PixelTypeDownCast<double, PixelType>(mScalar));
-        else ito.Set(PixelTypeDownCast<double, PixelType>(it.Get()));
-        ++it;
-        ++ito;
-      }
-      break;
-    case 5: // Absolute value
-      while (!it.IsAtEnd()) {
-        if (it.Get() <= 0) ito.Set(PixelTypeDownCast<double, PixelType>(-it.Get()));
-        // <= zero to avoid warning for unsigned types
-        else ito.Set(PixelTypeDownCast<double, PixelType>(it.Get()));
-        ++it;
-        ++ito;
-      }
-      break;
-    case 6: // Squared value
-      while (!it.IsAtEnd()) {
-        ito.Set(PixelTypeDownCast<double, PixelType>((double)it.Get()*(double)it.Get()));
-        ++it;
-        ++ito;
-      }
-      break;
-    case 7: // Log
-      while (!it.IsAtEnd()) {
-        if (it.Get() > 0)
-          ito.Set(PixelTypeDownCast<double, PixelType>(log((double)it.Get())));
-        else ito.Set(mDefaultPixelValue);
-        ++it;
-        ++ito;
-      }
-      break;
-    case 8: // exp
-      while (!it.IsAtEnd()) {
-        ito.Set(PixelTypeDownCast<double, PixelType>(exp((double)it.Get())));
-        ++it;
-        ++ito;
-      }
-      break;
-    case 9: // sqrt
-      while (!it.IsAtEnd()) {
-        if (it.Get() > 0)
-          ito.Set(PixelTypeDownCast<double, PixelType>(sqrt((double)it.Get())));
-        else {
-          if (it.Get() ==0) ito.Set(0);
-          else ito.Set(mDefaultPixelValue);
-        }
-        ++it;
-        ++ito;
-      }
-      break;
-    case 10: // exp
-      while (!it.IsAtEnd()) {
-        ito.Set(PixelTypeDownCast<double, PixelType>((0x10000 - (double)it.Get())/mScalar));
-        ++it;
-        ++ito;
-      }
-      break;
-      */
-    case 11: // divide
-      while (!it.IsAtEnd()) {
-        ito.Set(it.Get() / mScalar);
-        ++it;
-        ++ito;
-      }
-      break;
-    default: // error ?
-      std::cerr << "ERROR : the operation number (" << mTypeOfOperation << ") is not known." << std::endl;
-      exit(-1);
-    }
-    
-  }
-
-  template<>
-  template<>
-  void ImageArithmGenericFilter<args_info_clitkImageArithm>::ComputeImage< 
-    itk::ImageRegionIterator< itk::Image< itk::Vector<float, 3u>, 3u > >, 
-    itk::ImageRegionIterator< itk::Image< itk::Vector<float, 3u>, 3u > >, 
-    itk::ImageRegionIterator< itk::Image< itk::Vector<float, 3u>, 3u > > 
-    >
-    (itk::ImageRegionIterator< itk::Image< itk::Vector<float, 3u>, 3u > > it1, 
-    itk::ImageRegionIterator< itk::Image< itk::Vector<float, 3u>, 3u > > it2, 
-    itk::ImageRegionIterator< itk::Image< itk::Vector<float, 3u>, 3u > > ito)
-  {
-    typedef itk::ImageRegionIterator< itk::Image< itk::Vector<float, 3u>, 3u > > Iter1;
-    typedef itk::ImageRegionIterator< itk::Image< itk::Vector<float, 3u>, 3u > > Iter2;
-    typedef itk::ImageRegionIterator< itk::Image< itk::Vector<float, 3u>, 3u > > Iter3;
-    
-    it1.GoToBegin();
-    it2.GoToBegin();
-    ito.GoToBegin();
-    typedef Iter3::PixelType PixelType;
-
-    switch (mTypeOfOperation) {
-    case 0: // Addition
-      while (!ito.IsAtEnd()) {
-        ito.Set(it1.Get() + it2.Get());
-        ++it1;
-        ++it2;
-        ++ito;
-      }
-      break;
-      /*
-    case 1: // Multiply
-      while (!ito.IsAtEnd()) {
-        ito.Set(it1.Get() * it2.Get()) );
-        ++it1;
-        ++it2;
-        ++ito;
-      }
-      break;
-    case 2: // Divide
-      while (!ito.IsAtEnd()) {
-        if (it1.Get() != 0)
-          ito.Set(it1.Get() / it2.Get()));
-        else ito.Set(mDefaultPixelValue);
-        ++it1;
-        ++it2;
-        ++ito;
-      }
-      break;
-    case 3: // Max
-      while (!ito.IsAtEnd()) {
-        if (it1.Get() < it2.Get()) ito.Set(it2.Get());
-        ++it1;
-        ++it2;
-        ++ito;
-      }
-      break;
-    case 4: // Min
-      while (!ito.IsAtEnd()) {
-        if (it1.Get() > it2.Get()) ito.Set(it2.Get());
-        ++it1;
-        ++it2;
-        ++ito;
-      }
-      break;
-      */
-    case 5: // Absolute difference
-      while (!ito.IsAtEnd()) {
-        ito.Set(it2.Get()-it1.Get());
-        ++it1;
-        ++it2;
-        ++ito;
-      }
-      break;
-      /*
-    case 6: // Squared differences
-      while (!ito.IsAtEnd()) {
-        ito.Set(pow(it1.Get()-it2.Get(),2)));
-        ++it1;
-        ++it2;
-        ++ito;
-      }
-      break;
-      */
-    case 7: // Difference
-      while (!ito.IsAtEnd()) {
-        ito.Set(it1.Get()-it2.Get());
-        ++it1;
-        ++it2;
-        ++ito;
-      }
-      break;
-      /*
-    case 8: // Relative Difference
-      while (!ito.IsAtEnd()) {
-        if (it1.Get() != 0) ito.Set(PixelTypeDownCast<double, PixelType>(((double)it1.Get()-(double)it2.Get()))/(double)it1.Get());
-        else ito.Set(0.0);
-        ++it1;
-        ++it2;
-        ++ito;
-      }
-      break;
-      */
-    default: // error ?
-      std::cerr << "ERROR : the operation number (" << mTypeOfOperation << ") is not known." << std::endl;
-      exit(-1);
-    }
-  }
-
-////////////////////////////////////////////////////////////////////
-  // specializations for itk::Vector<double, 3u>, 3u
-  template<>
-  template<>
-  void ImageArithmGenericFilter<args_info_clitkImageArithm>::UpdateWithInputImageType< itk::Image< itk::Vector<double, 3u>, 3u > >()
-  {
-    typedef itk::Image< itk::Vector<double, 3u>, 3u > ImageType;
-    
-    // Read input1
-    ImageType::Pointer input1 = this->GetInput<ImageType>(0);
-
-    // Set input image iterator
-    typedef itk::ImageRegionIterator<ImageType> IteratorType;
-    IteratorType it(input1, input1->GetLargestPossibleRegion());
-
-    // typedef input2
-    ImageType::Pointer input2 = NULL;
-    IteratorType it2;
-
-    /*
-    // Special case for normalisation
-    if (mTypeOfOperation == 12) {
-      typedef itk::MinimumMaximumImageCalculator<ImageType> MinMaxFilterType;
-      typename MinMaxFilterType::Pointer ff = MinMaxFilterType::New();
-      ff->SetImage(input1);
-      ff->ComputeMaximum();
-      mScalar = ff->GetMaximum();
-      mTypeOfOperation = 11; // divide
-    }
-    */
-
-    if (mIsOperationUseASecondImage) {
-        // Read input2
-        input2 = this->GetInput<ImageType>(1);
-        // Set input image iterator
-        it2 = IteratorType(input2, input2->GetLargestPossibleRegion());
-        // Check dimension
-        if (!clitk::HaveSameSize<ImageType, ImageType>(input1, input2)) {
-          itkExceptionMacro(<< "The images (input and input2) must have the same size");
-        }
-        if(!clitk::HaveSameSpacing<ImageType, ImageType>(input1, input2)) {
-          itkWarningMacro(<< "The images (input and input2) do not have the same spacing. "
-                          << "Using first input's information.");
-        }
-    }
-
-    /*
-    // Check if overwrite and outputisfloat and pixeltype is not float -> do not overwrite
-    if (mOverwriteInputImage && mOutputIsFloat && (typeid(typename ImageType::PixelType) != typeid(float))) {
-      // std::cerr << "Warning. Could not use both mOverwriteInputImage and mOutputIsFloat, because input is "
-      //                     << typeid(PixelType).name()
-      //                     << std::endl;
-      mOverwriteInputImage = false;
-    }
-    */
-    
-    // ---------------- Overwrite input Image ---------------------
-    if (mOverwriteInputImage) {
-      // Set output iterator (to input1)
-      IteratorType ito = IteratorType(input1, input1->GetLargestPossibleRegion());
-      if (mIsOperationUseASecondImage) ComputeImage(it, it2, ito);
-      else ComputeImage(it, ito);
-      this->SetNextOutput<ImageType>(input1);
-    }
-    // ---------------- Create new output Image ---------------------
-    else {
-      /*if (mOutputIsFloat) {
-        // Create output image
-        typedef itk::Image<float,ImageType::ImageDimension> OutputImageType;
-        typename OutputImageType::Pointer output = OutputImageType::New();
-        output->SetRegions(input1->GetLargestPossibleRegion());
-        output->SetOrigin(input1->GetOrigin());
-        output->SetSpacing(input1->GetSpacing());
-        output->Allocate();
-        // Set output iterator
-        typedef itk::ImageRegionIterator<OutputImageType> IteratorOutputType;
-        IteratorOutputType ito = IteratorOutputType(output, output->GetLargestPossibleRegion());
-        if (mIsOperationUseASecondImage) ComputeImage(it, it2, ito);
-        else ComputeImage(it, ito);
-        this->template SetNextOutput<OutputImageType>(output);
-      } else*/ {
-        // Create output image
-        typedef ImageType OutputImageType;
-        OutputImageType::Pointer output = OutputImageType::New();
-        output->SetRegions(input1->GetLargestPossibleRegion());
-        output->SetOrigin(input1->GetOrigin());
-        output->SetSpacing(input1->GetSpacing());
-        output->Allocate();
-        // Set output iterator
-        typedef itk::ImageRegionIterator<OutputImageType> IteratorOutputType;
-        IteratorOutputType ito = IteratorOutputType(output, output->GetLargestPossibleRegion());
-        if (mIsOperationUseASecondImage) ComputeImage(it, it2, ito);
-        else ComputeImage(it, ito);
-        this->SetNextOutput<OutputImageType>(output);
-      }
-    }
-  }
-
-  template<>
-  template<>
-  void ImageArithmGenericFilter<args_info_clitkImageArithm>::ComputeImage< 
-    itk::ImageRegionIterator< itk::Image< itk::Vector<double, 3u>, 3u > >, 
-    itk::ImageRegionIterator< itk::Image< itk::Vector<double, 3u>, 3u > > >
-    (itk::ImageRegionIterator< itk::Image< itk::Vector<double, 3u>, 3u > > it, 
-    itk::ImageRegionIterator< itk::Image< itk::Vector<double, 3u>, 3u > > ito)
-  {
-    typedef itk::ImageRegionIterator< itk::Image< itk::Vector<double, 3u>, 3u > > Iter2;
-
-    ito.GoToBegin();
-    it.GoToBegin();
-    
-    typedef Iter2::PixelType PixelType;
-
-    PixelType scalar_vector;
-    scalar_vector.Fill(mScalar);
-    
-    // Perform operation
-    switch (mTypeOfOperation) {
-    case 0: // Addition
-      while (!it.IsAtEnd()) {
-        ito.Set(it.Get() + scalar_vector);
-        ++it;
-        ++ito;
-      }
-      break;
-    case 1: // Multiply
-      while (!it.IsAtEnd()) {
-        ito.Set(it.Get() * mScalar);
-        ++it;
-        ++ito;
-      }
-      break;
-      /*
-    case 2: // Inverse
-      while (!it.IsAtEnd()) {
-        if (it.Get() != 0)
-          ito.Set(mScalar / it.Get()));
-        else ito.Set(mDefaultPixelValue);
-        ++it;
-        ++ito;
-      }
-      break;
-    case 3: // Max
-      while (!it.IsAtEnd()) {
-        if (it.Get() < mScalar) ito.Set(PixelTypeDownCast<double, PixelType>(mScalar));
-        else ito.Set(PixelTypeDownCast<double, PixelType>(it.Get()));
-        ++it;
-        ++ito;
-      }
-      break;
-    case 4: // Min
-      while (!it.IsAtEnd()) {
-        if (it.Get() > mScalar) ito.Set(PixelTypeDownCast<double, PixelType>(mScalar));
-        else ito.Set(PixelTypeDownCast<double, PixelType>(it.Get()));
-        ++it;
-        ++ito;
-      }
-      break;
-    case 5: // Absolute value
-      while (!it.IsAtEnd()) {
-        if (it.Get() <= 0) ito.Set(PixelTypeDownCast<double, PixelType>(-it.Get()));
-        // <= zero to avoid warning for unsigned types
-        else ito.Set(PixelTypeDownCast<double, PixelType>(it.Get()));
-        ++it;
-        ++ito;
-      }
-      break;
-    case 6: // Squared value
-      while (!it.IsAtEnd()) {
-        ito.Set(PixelTypeDownCast<double, PixelType>((double)it.Get()*(double)it.Get()));
-        ++it;
-        ++ito;
-      }
-      break;
-    case 7: // Log
-      while (!it.IsAtEnd()) {
-        if (it.Get() > 0)
-          ito.Set(PixelTypeDownCast<double, PixelType>(log((double)it.Get())));
-        else ito.Set(mDefaultPixelValue);
-        ++it;
-        ++ito;
-      }
-      break;
-    case 8: // exp
-      while (!it.IsAtEnd()) {
-        ito.Set(PixelTypeDownCast<double, PixelType>(exp((double)it.Get())));
-        ++it;
-        ++ito;
-      }
-      break;
-    case 9: // sqrt
-      while (!it.IsAtEnd()) {
-        if (it.Get() > 0)
-          ito.Set(PixelTypeDownCast<double, PixelType>(sqrt((double)it.Get())));
-        else {
-          if (it.Get() ==0) ito.Set(0);
-          else ito.Set(mDefaultPixelValue);
-        }
-        ++it;
-        ++ito;
-      }
-      break;
-    case 10: // exp
-      while (!it.IsAtEnd()) {
-        ito.Set(PixelTypeDownCast<double, PixelType>((0x10000 - (double)it.Get())/mScalar));
-        ++it;
-        ++ito;
-      }
-      break;
-      */
-    case 11: // divide
-      while (!it.IsAtEnd()) {
-        ito.Set(it.Get() / mScalar);
-        ++it;
-        ++ito;
-      }
-      break;
-    default: // error ?
-      std::cerr << "ERROR : the operation number (" << mTypeOfOperation << ") is not known." << std::endl;
-      exit(-1);
-    }
-    
-  }
-
-  template<>
-  template<>
-  void ImageArithmGenericFilter<args_info_clitkImageArithm>::ComputeImage< 
-    itk::ImageRegionIterator< itk::Image< itk::Vector<double, 3u>, 3u > >, 
-    itk::ImageRegionIterator< itk::Image< itk::Vector<double, 3u>, 3u > >, 
-    itk::ImageRegionIterator< itk::Image< itk::Vector<double, 3u>, 3u > > 
-    >
-    (itk::ImageRegionIterator< itk::Image< itk::Vector<double, 3u>, 3u > > it1, 
-    itk::ImageRegionIterator< itk::Image< itk::Vector<double, 3u>, 3u > > it2, 
-    itk::ImageRegionIterator< itk::Image< itk::Vector<double, 3u>, 3u > > ito)
-  {
-    typedef itk::ImageRegionIterator< itk::Image< itk::Vector<double, 3u>, 3u > > Iter1;
-    typedef itk::ImageRegionIterator< itk::Image< itk::Vector<double, 3u>, 3u > > Iter2;
-    typedef itk::ImageRegionIterator< itk::Image< itk::Vector<double, 3u>, 3u > > Iter3;
-    
-    it1.GoToBegin();
-    it2.GoToBegin();
-    ito.GoToBegin();
-    typedef Iter3::PixelType PixelType;
-
-    switch (mTypeOfOperation) {
-    case 0: // Addition
-      while (!ito.IsAtEnd()) {
-        ito.Set(it1.Get() + it2.Get());
-        ++it1;
-        ++it2;
-        ++ito;
-      }
-      break;
-      /*
-    case 1: // Multiply
-      while (!ito.IsAtEnd()) {
-        ito.Set(it1.Get() * it2.Get()) );
-        ++it1;
-        ++it2;
-        ++ito;
-      }
-      break;
-    case 2: // Divide
-      while (!ito.IsAtEnd()) {
-        if (it1.Get() != 0)
-          ito.Set(it1.Get() / it2.Get()));
-        else ito.Set(mDefaultPixelValue);
-        ++it1;
-        ++it2;
-        ++ito;
-      }
-      break;
-    case 3: // Max
-      while (!ito.IsAtEnd()) {
-        if (it1.Get() < it2.Get()) ito.Set(it2.Get());
-        ++it1;
-        ++it2;
-        ++ito;
-      }
-      break;
-    case 4: // Min
-      while (!ito.IsAtEnd()) {
-        if (it1.Get() > it2.Get()) ito.Set(it2.Get());
-        ++it1;
-        ++it2;
-        ++ito;
-      }
-      break;
-      */
-    case 5: // Absolute difference
-      while (!ito.IsAtEnd()) {
-        ito.Set(it2.Get()-it1.Get());
-        ++it1;
-        ++it2;
-        ++ito;
-      }
-      break;
-      /*
-    case 6: // Squared differences
-      while (!ito.IsAtEnd()) {
-        ito.Set(pow(it1.Get()-it2.Get(),2)));
-        ++it1;
-        ++it2;
-        ++ito;
-      }
-      break;
-      */
-    case 7: // Difference
-      while (!ito.IsAtEnd()) {
-        ito.Set(it1.Get()-it2.Get());
-        ++it1;
-        ++it2;
-        ++ito;
-      }
-      break;
-      /*
-    case 8: // Relative Difference
-      while (!ito.IsAtEnd()) {
-        if (it1.Get() != 0) ito.Set(PixelTypeDownCast<double, PixelType>(((double)it1.Get()-(double)it2.Get()))/(double)it1.Get());
-        else ito.Set(0.0);
-        ++it1;
-        ++it2;
-        ++ito;
-      }
-      break;
-      */
-    default: // error ?
-      std::cerr << "ERROR : the operation number (" << mTypeOfOperation << ") is not known." << std::endl;
-      exit(-1);
-    }
-  }
 
 }
 
index 39bfeb94d96181a937cf350efcf810e9f09c24d8..3c3579f87cfc1323b4601f491b387ea338e9e375 100644 (file)
@@ -97,49 +97,6 @@ namespace clitk {
 
   }; // end class ImageArithmGenericFilter
 
-  // specializations for itk::Vector<float, 3u>, 3u
-  template<> template<>
-  void ImageArithmGenericFilter<args_info_clitkImageArithm>::UpdateWithInputImageType< itk::Image< itk::Vector<float, 3u>, 3u > >();
-  
-  template<> template<>
-  void ImageArithmGenericFilter<args_info_clitkImageArithm>::ComputeImage< 
-    itk::ImageRegionIterator< itk::Image< itk::Vector<float, 3u>, 3u > >, 
-    itk::ImageRegionIterator< itk::Image< itk::Vector<float, 3u>, 3u > > 
-    >
-    (itk::ImageRegionIterator< itk::Image< itk::Vector<float, 3u>, 3u > > it, 
-     itk::ImageRegionIterator< itk::Image< itk::Vector<float, 3u>, 3u > > ito);
-
-  template<> template<>
-  void ImageArithmGenericFilter<args_info_clitkImageArithm>::ComputeImage< 
-    itk::ImageRegionIterator< itk::Image< itk::Vector<float, 3u>, 3u > >, 
-    itk::ImageRegionIterator< itk::Image< itk::Vector<float, 3u>, 3u > >, 
-    itk::ImageRegionIterator< itk::Image< itk::Vector<float, 3u>, 3u > > 
-    >
-    (itk::ImageRegionIterator< itk::Image< itk::Vector<float, 3u>, 3u > > it1, 
-     itk::ImageRegionIterator< itk::Image< itk::Vector<float, 3u>, 3u > > it2, 
-     itk::ImageRegionIterator< itk::Image< itk::Vector<float, 3u>, 3u > > ito);
-  
-  // specializations for itk::Vector<double, 3u>, 3u
-  template<> template<>
-  void ImageArithmGenericFilter<args_info_clitkImageArithm>::UpdateWithInputImageType< itk::Image< itk::Vector<double, 3u>, 3u > >();
-  
-  template<> template<>
-  void ImageArithmGenericFilter<args_info_clitkImageArithm>::ComputeImage< 
-    itk::ImageRegionIterator< itk::Image< itk::Vector<double, 3u>, 3u > >, 
-    itk::ImageRegionIterator< itk::Image< itk::Vector<double, 3u>, 3u > > 
-    >
-    (itk::ImageRegionIterator< itk::Image< itk::Vector<double, 3u>, 3u > > it, 
-     itk::ImageRegionIterator< itk::Image< itk::Vector<double, 3u>, 3u > > ito);
-
-  template<> template<>
-  void ImageArithmGenericFilter<args_info_clitkImageArithm>::ComputeImage< 
-    itk::ImageRegionIterator< itk::Image< itk::Vector<double, 3u>, 3u > >, 
-    itk::ImageRegionIterator< itk::Image< itk::Vector<double, 3u>, 3u > >, 
-    itk::ImageRegionIterator< itk::Image< itk::Vector<double, 3u>, 3u > > 
-    >
-    (itk::ImageRegionIterator< itk::Image< itk::Vector<double, 3u>, 3u > > it1, 
-     itk::ImageRegionIterator< itk::Image< itk::Vector<double, 3u>, 3u > > it2, 
-     itk::ImageRegionIterator< itk::Image< itk::Vector<double, 3u>, 3u > > ito);
 } // end namespace
 //--------------------------------------------------------------------
 
index 1316fc145c7caf0a524a9a77f3cf9255498f2c90..4c2f0a58c6ef1f32cf858ddb5a02cfef31c0a722 100644 (file)
@@ -45,8 +45,6 @@ template<unsigned int Dim>
 void ImageArithmGenericFilter<args_info_type>::InitializeImageType()
 {
   ADD_DEFAULT_IMAGE_TYPES(Dim);
-  ADD_VEC_IMAGE_TYPE(3u,3u,float);
-  ADD_VEC_IMAGE_TYPE(3u,3u,double);
 }
 //--------------------------------------------------------------------
 
diff --git a/tools/clitkVFInterpolate.cxx b/tools/clitkVFInterpolate.cxx
new file mode 100644 (file)
index 0000000..eaff9b1
--- /dev/null
@@ -0,0 +1,78 @@
+/*=========================================================================
+  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 CLITKVFRESAMPLE_CXX
+#define CLITKVFRESAMPLE_CXX
+
+// clitk
+#include "clitkVFInterpolate_ggo.h"
+#include "clitkIO.h"
+#include "clitkVFInterpolateGenericFilter.h"
+
+//--------------------------------------------------------------------
+int main(int argc, char * argv[])
+{
+
+    // Init command line
+    GGO(clitkVFInterpolate, args_info);
+    CLITK_INIT;
+
+    // Read input image header to check image dimension
+    itk::ImageIOBase::Pointer header = clitk::readImageHeader(args_info.input1_arg);
+    unsigned int dim = header->GetNumberOfDimensions();
+    std::string pixelTypeName = header->GetComponentTypeAsString(header->GetComponentType());
+
+    // Print image info if verbose
+    if (args_info.verbose_flag) {
+        std::cout << "Input image <" << args_info.input1_arg << "> is ";
+        clitk::printImageHeader(header, std::cout);
+        std::cout << std::endl;
+    }
+
+    // Get input size/spacing
+    std::vector<int>    inputSize;
+    std::vector<double> inputSpacing;
+    inputSize.resize(dim);
+    inputSpacing.resize(dim);
+    for (unsigned int i=0; i<dim; i++) {
+        inputSpacing[i] = header->GetSpacing(i);
+        inputSize[i] = header->GetDimensions(i);
+    }
+
+    if (args_info.verbose_flag) {
+        std::cout << "Output image will be : " << std::endl;
+    }
+
+    // Create a filter
+    clitk::VFInterpolateGenericFilter::Pointer filter = clitk::VFInterpolateGenericFilter::New();
+    filter->SetInputFilename(args_info.input1_arg);
+    filter->SetInputFilename2(args_info.input2_arg);
+    filter->SetInterpolationName(args_info.interp_arg);
+    filter->SetDistance(args_info.distance_arg);
+//     filter->SetBSplineOrder(args_info.order_arg);
+//     filter->SetBLUTSampling(args_info.sampling_arg);
+    filter->SetOutputFilename(args_info.output_arg);
+
+    // Go !
+    filter->Update();
+
+    // this is the end my friend
+    return 0;
+}// end main
+//--------------------------------------------------------------------
+
+#endif  /* end #define CLITKVFRESAMPLE_CXX */
diff --git a/tools/clitkVFInterpolate.ggo b/tools/clitkVFInterpolate.ggo
new file mode 100644 (file)
index 0000000..f6e0c1b
--- /dev/null
@@ -0,0 +1,15 @@
+#File clitkImageInterpolate.ggo
+package "clitkImageInterpolate"
+version "1.0"
+purpose "Interpolate an image. You can specify the interpolation, you can apply a Gaussian filter before."
+
+option "config"                -       "Config file"                     string        no
+option "input1"                i       "Input image filename"            string        yes
+option "input2"    j "Input image filename"      string    yes
+option "output"        o       "Output image filename"           string        yes
+option "distance"     d     "Distance (d in [0,1])"     float  yes
+option "verbose"       v       "Verbose"                         flag          off
+option "interp"                -       "Interpolation type: {nn, linear}"  string  no default="nn"
+#option "order"        b       "BSpline ordre (range 0-5)"             int     no      default="3"
+#option "sampling"     s       "BLUT sampling value"                   int     no      default="30"
+
diff --git a/tools/clitkVFInterpolateGenericFilter.cxx b/tools/clitkVFInterpolateGenericFilter.cxx
new file mode 100644 (file)
index 0000000..777bb13
--- /dev/null
@@ -0,0 +1,181 @@
+/*=========================================================================
+  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 CLITKVFRESAMPLEGENERICFILTER_CXX
+#define CLITKVFRESAMPLEGENERICFILTER_CXX
+
+#include "clitkVFInterpolateGenericFilter.h"
+#include "itkInterpolateImageFilter.h"
+#include "itkLinearInterpolateImageFunction.h"
+#include "itkNearestNeighborInterpolateImageFunction.h"
+#include "itkNthElementImageAdaptor.h"
+
+//--------------------------------------------------------------------
+clitk::VFInterpolateGenericFilter::VFInterpolateGenericFilter():
+  clitk::ImageToImageGenericFilter<Self>("VFInterpolate")
+{
+  //InitializeImageType<2>();
+  InitializeImageType<3>();
+  //  InitializeImageType<4>();
+  mInterpolatorName = "nn";
+  mBSplineOrder=3;
+  mDistance=0;
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template<unsigned int Dim>
+void clitk::VFInterpolateGenericFilter::InitializeImageType()
+{
+  //typedef itk::Vector<float,Dim> v3f;
+  //ADD_IMAGE_TYPE(Dim, v3f);
+//   ADD_VEC_IMAGE_TYPE(Dim,2,double)
+  ADD_VEC_IMAGE_TYPE(Dim,3,float)
+  ADD_VEC_IMAGE_TYPE(Dim,3,double)
+  
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template<class ImageType>
+void clitk::VFInterpolateGenericFilter::UpdateWithInputImageType()
+{
+
+  if (m_NbOfComponents == 1) {
+    std::cerr << "Error, only one components ? Use clitkImageInterpolate instead." << std::endl;
+    exit(0);
+  }
+  typedef typename ImageType::PixelType PixelType;
+//   if (m_NbOfComponents == 2) Update_WithDimAndPixelTypeAndComponent<ImageType::ImageDimension,PixelType,2>();
+  if (m_NbOfComponents == 3) Update_WithDimAndPixelTypeAndComponent<ImageType::ImageDimension,PixelType,3>();
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template<unsigned int Dim, class PixelType, unsigned int DimCompo>
+void clitk::VFInterpolateGenericFilter::Update_WithDimAndPixelTypeAndComponent()
+{
+  // Reading input
+  //  typedef itk::Vector<PixelType, DimCompo> DisplacementType;
+  typedef PixelType DisplacementType;
+  typedef itk::Image< DisplacementType, Dim > ImageType;
+
+  typename ImageType::Pointer input1 = clitk::readImage<ImageType>(m_InputFilenames[0], m_IOVerbose);
+  typename ImageType::Pointer input2 = clitk::readImage<ImageType>(mInputFilename2, m_IOVerbose);
+  
+  // Main filter
+  typename ImageType::Pointer outputImage = ComputeImage<ImageType>(input1, input2);
+
+  // Write results
+  SetNextOutput<ImageType>(outputImage);
+}
+//--------------------------------------------------------------------
+
+//--------------------------------------------------------------------
+template<class ImageType>
+typename ImageType::Pointer
+clitk::VFInterpolateGenericFilter::ComputeImage(typename ImageType::Pointer inputImage1, typename ImageType::Pointer inputImage2)
+{
+
+  // Some typedefs
+  typedef itk::Image<typename ImageType::PixelType::ValueType, ImageType::ImageDimension> ScalarImageType;
+  typedef itk::Image<typename ImageType::PixelType::ValueType, ImageType::ImageDimension + 1> InterpolationImageType;
+  typedef itk::NthElementImageAdaptor<ImageType, typename ImageType::PixelType::ValueType> ImageAdaptorType;
+  typename ImageAdaptorType::Pointer adaptor1 = ImageAdaptorType::New();
+  typename ImageAdaptorType::Pointer adaptor2 = ImageAdaptorType::New();
+  adaptor1->SetImage(inputImage1);
+  adaptor2->SetImage(inputImage2);
+  
+  // Create Image Filter
+  typedef itk::InterpolateImageFilter<ImageAdaptorType, ScalarImageType> FilterType;
+  typename FilterType::Pointer filter = FilterType::New();
+  filter->SetInput1(adaptor1);
+  filter->SetInput2(adaptor2);
+  filter->SetDistance(mDistance);
+
+  // Select interpolator
+  if (mInterpolatorName == "nn") {
+    typedef itk::NearestNeighborInterpolateImageFunction<InterpolationImageType> InterpolatorType;
+    typename InterpolatorType::Pointer interpolator = InterpolatorType::New();
+    filter->SetInterpolator(interpolator);
+  } else {
+    if (mInterpolatorName == "linear") {
+      typedef itk::LinearInterpolateImageFunction<InterpolationImageType> InterpolatorType;
+      typename InterpolatorType::Pointer interpolator =  InterpolatorType::New();
+      filter->SetInterpolator(interpolator);
+    } else {
+      std::cerr << "Sorry, I do not know the interpolator (for vector field) '" << mInterpolatorName
+                << "'. Known interpolators are :  nn, linear" << std::endl;
+      exit(0);
+    }
+  }
+
+  typename ImageType::Pointer output = ImageType::New();
+  typename ImageAdaptorType::Pointer adaptorOutput = ImageAdaptorType::New();
+  output->CopyInformation(inputImage1);
+  output->SetRegions(inputImage1->GetLargestPossibleRegion());
+  output->Allocate();
+
+  typedef itk::ImageRegionIterator<ScalarImageType> IteratorType1;
+  typedef itk::ImageRegionIterator<ImageAdaptorType> IteratorType2;
+  
+  for (unsigned int i = 0; i < ImageType::PixelType::Dimension; i++) {
+    adaptor1->SelectNthElement(i);
+    adaptor2->SelectNthElement(i);
+
+    // Go !
+    try {
+      filter->Update();
+    } catch( itk::ExceptionObject & err ) {
+      std::cerr << "Error while filtering " << m_InputFilenames[0].c_str()
+                << " " << err << std::endl;
+      exit(0);
+    }
+
+    adaptorOutput->SelectNthElement(i);
+    adaptorOutput->SetImage(output);
+    
+    IteratorType1 it1(filter->GetOutput(), filter->GetOutput()->GetLargestPossibleRegion());
+    IteratorType2 it2(adaptorOutput, adaptorOutput->GetLargestPossibleRegion());
+    
+    it1.GoToBegin();
+    it2.GoToBegin();
+    while ( ! it1.IsAtEnd() ) {
+      it2.Set(it1.Get());
+      ++it1;
+      ++it2;
+    }
+  }
+  
+  // Return result
+  return output;
+
+}
+//--------------------------------------------------------------------
+
+//--------------------------------------------------------------------
+void clitk::VFInterpolateGenericFilter::SetInterpolationName(const std::string & inter)
+{
+  mInterpolatorName = inter;
+}
+//--------------------------------------------------------------------
+
+#endif
+
diff --git a/tools/clitkVFInterpolateGenericFilter.h b/tools/clitkVFInterpolateGenericFilter.h
new file mode 100644 (file)
index 0000000..2d84dcf
--- /dev/null
@@ -0,0 +1,102 @@
+/*=========================================================================
+  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 CLITKIMAGERESAMPLEGENERICFILTER_H
+#define CLITKIMAGERESAMPLEGENERICFILTER_H
+/**
+ -------------------------------------------------------------------
+ * @file   clitkVFInterpolateGenericFilter.h
+ * @author David Sarrut <David.Sarrut@creatis.insa-lyon.fr>
+ * @date   23 Feb 2008 08:37:53
+
+ * @brief  
+ -------------------------------------------------------------------*/
+
+// clitk include
+#include "clitkCommon.h"
+#include "clitkImageCommon.h"
+#include "clitkImageToImageGenericFilter.h"
+
+// itk include
+#include "itkImage.h"
+#include "itkVectorImage.h"
+#include "itkFixedArray.h"
+#include "itkImageFileReader.h"
+#include "itkImageSeriesReader.h"
+#include "itkImageFileWriter.h"
+#include "itkRecursiveGaussianImageFilter.h"
+#include "itkInterpolateImageFilter.h"
+#include "itkAffineTransform.h"
+#include "itkVectorNearestNeighborInterpolateImageFunction.h"
+#include "itkVectorLinearInterpolateImageFunction.h"
+#include "itkBSplineInterpolateImageFunction.h"
+#include "itkBSplineInterpolateImageFunctionWithLUT.h"
+#include "itkCommand.h"
+
+namespace clitk {
+  
+  //--------------------------------------------------------------------
+  class VFInterpolateGenericFilter: 
+    public clitk::ImageToImageGenericFilter<VFInterpolateGenericFilter> {
+    
+  public: 
+    // constructor
+    VFInterpolateGenericFilter();
+
+    // Types
+    typedef VFInterpolateGenericFilter       Self;
+    typedef itk::SmartPointer<Self>       Pointer;
+    typedef itk::SmartPointer<const Self> ConstPointer;
+
+    // New
+    itkNewMacro(Self);
+    
+    void SetInputFilename1(const std::string& file) { mInputFilename1 = file; }
+    void SetInputFilename2(const std::string& file) { mInputFilename2 = file; }
+    void SetInterpolationName(const std::string & inter);
+    void SetDistance(double distance) { mDistance = distance; }
+    void SetBSplineOrder(int o) { mBSplineOrder = o; }
+    void SetBLUTSampling(int b) { mSamplingFactors.resize(1); mSamplingFactors[0] = b; }
+
+   //--------------------------------------------------------------------
+    // Main function called each time the filter is updated
+    template<class InputImageType>  
+    void UpdateWithInputImageType();
+
+  protected:
+    template<unsigned int Dim> void InitializeImageType();
+    //--------------------------------------------------------------------
+    std::string mInputFilename1, mInputFilename2;
+    std::string mInterpolatorName;
+    int mBSplineOrder;
+    std::vector<int> mSamplingFactors;
+    double mDistance;
+
+    //--------------------------------------------------------------------
+    template<unsigned int Dim, class PixelType, unsigned int DimCompo> 
+    void Update_WithDimAndPixelTypeAndComponent();
+    template<class ImageType>
+    typename ImageType::Pointer ComputeImage(typename ImageType::Pointer inputImage1, typename ImageType::Pointer inputImage2);
+    
+  }; // end class VFInterpolateGenericFilter
+  //--------------------------------------------------------------------
+    
+} // end namespace
+//--------------------------------------------------------------------
+    
+#endif /* end #define CLITKIMAGERESAMPLEGENERICFILTER_H */
+
diff --git a/tools/clitkVFInterpolateGenericFilter.txx b/tools/clitkVFInterpolateGenericFilter.txx
new file mode 100644 (file)
index 0000000..7b4aea1
--- /dev/null
@@ -0,0 +1,34 @@
+/*=========================================================================
+  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 CLITKVFRESAMPLEGENERICFILTER_TXX
+#define CLITKVFRESAMPLEGENERICFILTER_TXX
+/**
+   ------------------------------------------------=
+   * @file   clitkVFInterpolateGenericFilter.txx
+   * @author David Sarrut <david.sarrut@creatis.insa-lyon.fr>
+   * @date   23 Feb 2008 08:40:11
+   *
+   * @brief
+   *
+   *
+   ------------------------------------------------=*/
+
+//--------------------------------------------------------------------
+
+#endif /* end #define CLITKVFRESAMPLEGENERICFILTER_TXX */
+
diff --git a/tools/clitkVectorArithm.cxx b/tools/clitkVectorArithm.cxx
new file mode 100644 (file)
index 0000000..bc3ac3a
--- /dev/null
@@ -0,0 +1,52 @@
+/*=========================================================================
+  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 CLITKVECTORARITHM_CXX
+#define CLITKVECTORARITHM_CXX
+/**
+   -------------------------------------------------
+   * @file   clitkVectorArithm.cxx
+   * @author David Sarrut <David.Sarrut@creatis.insa-lyon.fr>
+   * @date   23 Feb 2008 08:37:53
+   -------------------------------------------------*/
+
+// clitk include
+#include "clitkVectorArithm_ggo.h"
+#include "clitkVectorArithmGenericFilter.h"
+#include "clitkIO.h"
+
+//--------------------------------------------------------------------
+int main(int argc, char * argv[])
+{
+
+  // Init command line
+  GGO(clitkVectorArithm, args_info);
+  CLITK_INIT;
+
+  // Creation of a generic filter
+  typedef clitk::VectorArithmGenericFilter<args_info_clitkVectorArithm> FilterType;
+  FilterType::Pointer filter = FilterType::New();
+
+  // Go !
+  filter->SetArgsInfo(args_info);
+  CLITK_TRY_CATCH_EXIT(filter->Update());
+
+  // this is the end my friend
+  return EXIT_SUCCESS;
+} // end main
+
+#endif //define CLITKVECTORARITHM_CXX
diff --git a/tools/clitkVectorArithm.ggo b/tools/clitkVectorArithm.ggo
new file mode 100644 (file)
index 0000000..5c7d65e
--- /dev/null
@@ -0,0 +1,21 @@
+#File  clitkVectorArithm.ggo
+package "clitkVectorArithm"
+version "1.0"
+purpose "Perform an arithmetic operation (+-*/ ...) using two images or using an image and a scalar value."
+
+
+option "config"      - "Config file"                     string   no
+option "verbose"     v         "Verbose"                         flag     off
+option "imagetypes"  -  "Display allowed image types"    flag     off
+
+option "input1"           i    "Input first image filename"      string   yes
+option "input2"           j    "Input second image filename"     string   no
+option "output"    o   "Output image filename"           string   yes
+
+option "scalar"           s    "Scalar value"            double   no
+option "operation" t   "Type of operation : \n With another image : 0=add, 1=multiply (dotproduct), 7=difference, 9=crossproduct\n; For 'scalar' : 0=add, 1=multiply, 5=absval (magnitude), 6=squared magnitude, 11=divide, 12=normalize"      int default="0" no 
+option "pixelValue" -  "Default value for NaN/Inf"     double   default="0.0"  no
+
+option "setFloatOutput" f "Set output to float pixel type" flag off
+
+#option "binary"   b    "Mask for binary operation"  string     no
diff --git a/tools/clitkVectorArithmGenericFilter.cxx b/tools/clitkVectorArithmGenericFilter.cxx
new file mode 100644 (file)
index 0000000..ff7b2d7
--- /dev/null
@@ -0,0 +1,31 @@
+/*=========================================================================
+  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 CLITKVECTORARITHMGENERICFILTER_CXX
+#define CLITKVECTORARITHMGENERICFILTER_CXX
+
+#include "clitkVectorArithmGenericFilter.h"
+
+namespace clitk {
+  // Specialisation
+//   template<>
+//   class VectorArithmGenericFilter<args_info_clitkVECTORARITHM>;
+
+
+}
+
+#endif //define CLITKVECTORARITHMGENERICFILTER_CXX
diff --git a/tools/clitkVectorArithmGenericFilter.h b/tools/clitkVectorArithmGenericFilter.h
new file mode 100644 (file)
index 0000000..1196b71
--- /dev/null
@@ -0,0 +1,117 @@
+/*=========================================================================
+  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 CLITKVectorArithmGENERICFILTER_H
+#define CLITKVectorArithmGENERICFILTER_H
+/**
+ -------------------------------------------------------------------
+ * @file   clitkVectorArithmGenericFilter.h
+ * @author David Sarrut <David.Sarrut@creatis.insa-lyon.fr>
+ * @date   23 Feb 2008 08:37:53
+
+ * @brief  
+ -------------------------------------------------------------------*/
+
+// clitk include
+#include "clitkCommon.h"
+#include "clitkImageToImageGenericFilter.h"
+#include "clitkVectorArithm_ggo.h"
+
+// itk include
+#include "itkImage.h"
+#include "itkImageIOBase.h"
+#include "itkImageRegionIterator.h"
+#include "itkImageRegionConstIterator.h"
+
+//--------------------------------------------------------------------
+namespace clitk {
+  
+  template<class args_info_type>
+  class ITK_EXPORT VectorArithmGenericFilter:
+    public clitk::ImageToImageGenericFilter<VectorArithmGenericFilter<args_info_type> > {
+    
+  public:
+       
+    // Constructor 
+    VectorArithmGenericFilter ();
+
+    // Types
+    typedef VectorArithmGenericFilter        Self;
+    typedef ImageToImageGenericFilterBase   Superclass;
+    typedef itk::SmartPointer<Self>         Pointer;
+    typedef itk::SmartPointer<const Self>   ConstPointer;
+
+    // New
+    itkNewMacro(Self);
+    
+    //--------------------------------------------------------------------
+    void SetArgsInfo(const args_info_type & a);
+
+    // Set methods
+    void SetDefaultPixelValue (double value) {  mDefaultPixelValue = value ;}
+    void SetTypeOfOperation (int value) {  mTypeOfOperation = value ;}
+    void SetScalar (double value) {  mScalar = value ;}
+    void EnableOverwriteInputImage(bool b);
+
+    // Get methods
+    double GetDefaultPixelValue () { return  mDefaultPixelValue ;} 
+    int GetTypeOfOperation () { return  mTypeOfOperation ;} 
+    double GetScalar () { return  mScalar ;} 
+
+    //--------------------------------------------------------------------
+    // Main function called each time the filter is updated
+    template<class InputImageType>  
+    void UpdateWithInputImageType();
+
+  protected:  
+    template<unsigned int Dim> void InitializeImageType();
+    bool mIsOperationUseASecondImage;
+    double mScalar;
+    double mDefaultPixelValue;
+    int mTypeOfOperation;  
+    args_info_type mArgsInfo;
+    bool mOverwriteInputImage;
+    bool mOutputIsFloat;
+    bool mIsOutputScalar;
+    
+    template<class Iter1, class Iter2>
+      void ComputeImage(Iter1 it, Iter2 ito);
+
+    template<class Iter1, class Iter2, class Iter3>
+      void ComputeImage(Iter1 it1, Iter2 it2, Iter3 ito);
+    
+    template<class Iter1, class Iter2>
+      void ComputeScalarImage(Iter1 it, Iter2 ito);
+
+    template<class Iter1, class Iter2, class Iter3>
+      void ComputeScalarImage(Iter1 it1, Iter2 it2, Iter3 ito);
+
+    //--------------------------------------------------------------------
+
+  }; // end class VectorArithmGenericFilter
+
+  // specializations for itk::Vector<float, 3u>, 3u
+} // end namespace
+//--------------------------------------------------------------------
+
+  
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "clitkVectorArithmGenericFilter.txx"
+#endif
+
+#endif //#define CLITKVectorArithmGENERICFILTER_H
+
diff --git a/tools/clitkVectorArithmGenericFilter.txx b/tools/clitkVectorArithmGenericFilter.txx
new file mode 100644 (file)
index 0000000..1f4cb72
--- /dev/null
@@ -0,0 +1,512 @@
+/*=========================================================================
+  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 CLITKVectorArithmGENERICFILTER_TXX
+#define CLITKVectorArithmGENERICFILTER_TXX
+
+#include "clitkImageCommon.h"
+
+#include "itkMinimumMaximumImageCalculator.h"
+
+namespace clitk
+{
+
+//--------------------------------------------------------------------
+template<class args_info_type>
+VectorArithmGenericFilter<args_info_type>::VectorArithmGenericFilter()
+  :ImageToImageGenericFilter<Self>("VectorArithmGenericFilter"),mTypeOfOperation(0)
+{
+  InitializeImageType<3>();
+  mIsOperationUseASecondImage = false;
+  mIsOutputScalar = false;
+  mOverwriteInputImage = true;
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template<class args_info_type>
+template<unsigned int Dim>
+void VectorArithmGenericFilter<args_info_type>::InitializeImageType()
+{
+  ADD_VEC_IMAGE_TYPE(Dim,3u,float);
+  ADD_VEC_IMAGE_TYPE(Dim,3u,double);
+  ADD_VEC_IMAGE_TYPE(Dim,2u,float);
+  ADD_VEC_IMAGE_TYPE(Dim,2u,double);
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template<class args_info_type>
+void VectorArithmGenericFilter<args_info_type>::EnableOverwriteInputImage(bool b)
+{
+  mOverwriteInputImage = b;
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template<class args_info_type>
+void VectorArithmGenericFilter<args_info_type>::SetArgsInfo(const args_info_type & a)
+{
+  mArgsInfo=a;
+
+  // Set value
+  this->SetIOVerbose(mArgsInfo.verbose_flag);
+  mTypeOfOperation = mArgsInfo.operation_arg;
+  mDefaultPixelValue = mArgsInfo.pixelValue_arg;
+  mScalar = mArgsInfo.scalar_arg;
+  mOutputIsFloat = mArgsInfo.setFloatOutput_flag;
+
+  if (mArgsInfo.imagetypes_flag) this->PrintAvailableImageTypes();
+
+  if (mArgsInfo.input1_given) this->AddInputFilename(mArgsInfo.input1_arg);
+  if (mArgsInfo.input2_given) {
+    mIsOperationUseASecondImage = true;
+    this->AddInputFilename(mArgsInfo.input2_arg);
+    if (mArgsInfo.operation_arg == 1)
+      mIsOutputScalar = true;
+  } 
+  else if (mArgsInfo.operation_arg == 5 || mArgsInfo.operation_arg == 6)
+    mIsOutputScalar = true;
+
+  if (mArgsInfo.output_given) this->SetOutputFilename(mArgsInfo.output_arg);
+
+  // Check type of operation (with scalar or with other image)
+  if ((mArgsInfo.input2_given) && (mArgsInfo.scalar_given)) {
+    std::cerr << "ERROR : you cannot provide both --scalar and --input2 option" << std::endl;
+    exit(-1);
+  }
+  if ((!mArgsInfo.input2_given) && (!mArgsInfo.scalar_given)) {
+    if (mArgsInfo.operation_arg < 5) {
+      std::cerr << "Such operation need the --scalar option." << std::endl;
+      exit(-1);
+    }
+  }
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template<class args_info_type>
+template<class ImageType>
+void VectorArithmGenericFilter<args_info_type>::UpdateWithInputImageType()
+{
+  // Read input1
+  typename ImageType::Pointer input1 = this->template GetInput<ImageType>(0);
+
+  // Set input image iterator
+  typedef itk::ImageRegionIterator<ImageType> IteratorType;
+  IteratorType it(input1, input1->GetLargestPossibleRegion());
+
+  // typedef input2
+  typename ImageType::Pointer input2 = NULL;
+  IteratorType it2;
+
+  // Special case for normalisation
+  /*
+  if (mTypeOfOperation == 12) {
+    typedef itk::MinimumMaximumImageCalculator<ImageType> MinMaxFilterType;
+    typename MinMaxFilterType::Pointer ff = MinMaxFilterType::New();
+    ff->SetImage(input1);
+    ff->ComputeMaximum();
+    mScalar = ff->GetMaximum();
+    mTypeOfOperation = 11; // divide
+  }
+  */
+
+  if (mIsOperationUseASecondImage) {
+      // Read input2
+      input2 = this->template GetInput<ImageType>(1);
+      // Set input image iterator
+      it2 = IteratorType(input2, input2->GetLargestPossibleRegion());
+      // Check dimension
+      if (!clitk::HaveSameSize<ImageType, ImageType>(input1, input2)) {
+        itkExceptionMacro(<< "The images (input and input2) must have the same size");
+      }
+      if(!clitk::HaveSameSpacing<ImageType, ImageType>(input1, input2)) {
+        itkWarningMacro(<< "The images (input and input2) do not have the same spacing. "
+                        << "Using first input's information.");
+      }
+  }
+
+  // Check if overwrite and outputisfloat and pixeltype is not float -> do not overwrite
+  if (mOverwriteInputImage && mOutputIsFloat && (typeid(typename ImageType::PixelType) != typeid(float))) {
+    // std::cerr << "Warning. Could not use both mOverwriteInputImage and mOutputIsFloat, because input is "
+    //                     << typeid(PixelType).name()
+    //                     << std::endl;
+    mOverwriteInputImage = false;
+  }
+
+  // ---------------- Overwrite input Image ---------------------
+  if (mOverwriteInputImage && !mIsOutputScalar) {
+    // Set output iterator (to input1)
+    IteratorType ito = IteratorType(input1, input1->GetLargestPossibleRegion());
+    if (mIsOperationUseASecondImage) ComputeImage(it, it2, ito);
+    else ComputeImage(it, ito);
+    this->template SetNextOutput<ImageType>(input1);
+  }
+
+  // ---------------- Create new output Image ---------------------
+  else {
+    // Create output image
+    if (!mIsOutputScalar) {
+      typedef ImageType OutputImageType;
+      typename OutputImageType::Pointer output = OutputImageType::New();
+      output->SetRegions(input1->GetLargestPossibleRegion());
+      output->SetOrigin(input1->GetOrigin());
+      output->SetSpacing(input1->GetSpacing());
+      output->Allocate();
+      // Set output iterator
+      typedef itk::ImageRegionIterator<OutputImageType> IteratorOutputType;
+      IteratorOutputType ito = IteratorOutputType(output, output->GetLargestPossibleRegion());
+      if (mIsOperationUseASecondImage) ComputeImage(it, it2, ito);
+      else ComputeImage(it, ito);
+      this->template SetNextOutput<OutputImageType>(output);
+    }
+    else {
+      // Create scalar output image
+      typedef itk::Image<typename ImageType::PixelType::ValueType, ImageType::ImageDimension> OutputImageType;
+      typename OutputImageType::Pointer output = OutputImageType::New();
+      output->SetRegions(input1->GetLargestPossibleRegion());
+      output->SetOrigin(input1->GetOrigin());
+      output->SetSpacing(input1->GetSpacing());
+      output->Allocate();
+      // Set output iterator
+      typedef itk::ImageRegionIterator<OutputImageType> IteratorOutputType;
+      IteratorOutputType ito = IteratorOutputType(output, output->GetLargestPossibleRegion());
+      if (mIsOperationUseASecondImage) ComputeScalarImage(it, it2, ito);
+      else ComputeScalarImage(it, ito);
+      this->template SetNextOutput<OutputImageType>(output);
+    }
+  }
+}
+//--------------------------------------------------------------------
+
+//--------------------------------------------------------------------
+template<class args_info_type>
+template<class Iter1, class Iter2, class Iter3>
+void  VectorArithmGenericFilter<args_info_type>::ComputeImage(Iter1 it1, Iter2 it2, Iter3 ito)
+{
+  it1.GoToBegin();
+  it2.GoToBegin();
+  ito.GoToBegin();
+  typedef typename Iter3::PixelType PixelType;
+
+  switch (mTypeOfOperation) {
+  case 0: // Addition
+    while (!ito.IsAtEnd()) {
+      ito.Set(it1.Get() + it2.Get());
+      ++it1;
+      ++it2;
+      ++ito;
+    }
+    break;
+    /*
+  case 1: // Multiply
+    while (!ito.IsAtEnd()) {
+      ito.Set(it1.Get() * it2.Get()) );
+      ++it1;
+      ++it2;
+      ++ito;
+    }
+    break;
+    */
+    /*
+  case 2: // Divide
+    while (!ito.IsAtEnd()) {
+      if (it1.Get() != 0)
+        ito.Set(it1.Get() / it2.Get()));
+      else ito.Set(mDefaultPixelValue);
+      ++it1;
+      ++it2;
+      ++ito;
+    }
+    break;
+  case 3: // Max
+    while (!ito.IsAtEnd()) {
+      if (it1.Get() < it2.Get()) ito.Set(it2.Get());
+      ++it1;
+      ++it2;
+      ++ito;
+    }
+    break;
+  case 4: // Min
+    while (!ito.IsAtEnd()) {
+      if (it1.Get() > it2.Get()) ito.Set(it2.Get());
+      ++it1;
+      ++it2;
+      ++ito;
+    }
+    break;
+    */
+    /*
+  case 5: // Absolute difference
+    while (!ito.IsAtEnd()) {
+      ito.Set(it2.Get()-it1.Get());
+      ++it1;
+      ++it2;
+      ++ito;
+    }
+    break;
+    */
+    /*
+  case 6: // Squared differences
+    while (!ito.IsAtEnd()) {
+      ito.Set(pow(it1.Get()-it2.Get(),2)));
+      ++it1;
+      ++it2;
+      ++ito;
+    }
+    break;
+    */
+  case 7: // Difference
+    while (!ito.IsAtEnd()) {
+      ito.Set(it1.Get()-it2.Get());
+      ++it1;
+      ++it2;
+      ++ito;
+    }
+    break;
+    /*
+  case 8: // Relative Difference
+    while (!ito.IsAtEnd()) {
+      if (it1.Get() != 0) ito.Set(PixelTypeDownCast<double, PixelType>(((double)it1.Get()-(double)it2.Get()))/(double)it1.Get());
+      else ito.Set(0.0);
+      ++it1;
+      ++it2;
+      ++ito;
+    }
+    break;
+    */
+    /*
+  case 9: // CrossProduct
+    while (!ito.IsAtEnd()) {
+      ito.Set(it1.Get()^it2.Get());
+      ++it1;
+      ++it2;
+      ++ito;
+    }
+    break;
+    */
+  default: // error ?
+    std::cerr << "ERROR : the operation number (" << mTypeOfOperation << ") is not known." << std::endl;
+    exit(-1);
+  }
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template<class args_info_type>
+template<class Iter1, class Iter2>
+void clitk::VectorArithmGenericFilter<args_info_type>::ComputeImage(Iter1 it, Iter2 ito)
+{
+  ito.GoToBegin();
+  it.GoToBegin();
+  
+  typedef typename Iter1::PixelType PixelType;
+
+  PixelType scalar_vector;
+  scalar_vector.Fill(mScalar);
+  
+  // Perform operation
+  switch (mTypeOfOperation) {
+  case 0: // Addition
+    while (!it.IsAtEnd()) {
+      ito.Set(it.Get() + scalar_vector);
+      ++it;
+      ++ito;
+    }
+    break;
+  case 1: // Multiply
+    while (!it.IsAtEnd()) {
+      ito.Set(it.Get() * mScalar);
+      ++it;
+      ++ito;
+    }
+    break;
+    /*
+  case 2: // Inverse
+    while (!it.IsAtEnd()) {
+      if (it.Get() != 0)
+        ito.Set(mScalar / it.Get()));
+      else ito.Set(mDefaultPixelValue);
+      ++it;
+      ++ito;
+    }
+    break;
+  case 3: // Max
+    while (!it.IsAtEnd()) {
+      if (it.Get() < mScalar) ito.Set(PixelTypeDownCast<double, PixelType>(mScalar));
+      else ito.Set(PixelTypeDownCast<double, PixelType>(it.Get()));
+      ++it;
+      ++ito;
+    }
+    break;
+  case 4: // Min
+    while (!it.IsAtEnd()) {
+      if (it.Get() > mScalar) ito.Set(PixelTypeDownCast<double, PixelType>(mScalar));
+      else ito.Set(PixelTypeDownCast<double, PixelType>(it.Get()));
+      ++it;
+      ++ito;
+    }
+    break;
+    */
+    /*
+  case 5: // Absolute value
+    while (!it.IsAtEnd()) {
+      ito.Set(PixelTypeDownCast<double, PixelType>(it.GetNorm()));
+      ++it;
+      ++ito;
+    }
+    break;
+  case 6: // Squared value
+    while (!it.IsAtEnd()) {
+      ito.Set(PixelTypeDownCast<double, PixelType>(it.GetSquaredNorm());
+      ++it;
+      ++ito;
+    }
+    break;
+    */
+    /*
+  case 7: // Log
+    while (!it.IsAtEnd()) {
+      if (it.Get() > 0)
+        ito.Set(PixelTypeDownCast<double, PixelType>(log((double)it.Get())));
+      else ito.Set(mDefaultPixelValue);
+      ++it;
+      ++ito;
+    }
+    break;
+  case 8: // exp
+    while (!it.IsAtEnd()) {
+      ito.Set(PixelTypeDownCast<double, PixelType>(exp((double)it.Get())));
+      ++it;
+      ++ito;
+    }
+    break;
+  case 9: // sqrt
+    while (!it.IsAtEnd()) {
+      if (it.Get() > 0)
+        ito.Set(PixelTypeDownCast<double, PixelType>(sqrt((double)it.Get())));
+      else {
+        if (it.Get() ==0) ito.Set(0);
+        else ito.Set(mDefaultPixelValue);
+      }
+      ++it;
+      ++ito;
+    }
+    break;
+  case 10: // exp
+    while (!it.IsAtEnd()) {
+      ito.Set(PixelTypeDownCast<double, PixelType>((0x10000 - (double)it.Get())/mScalar));
+      ++it;
+      ++ito;
+    }
+    break;
+    */
+  case 11: // divide
+    while (!it.IsAtEnd()) {
+      ito.Set(it.Get() / mScalar);
+      ++it;
+      ++ito;
+    }
+    break;
+  case 12: // normalize
+    while (!it.IsAtEnd()) {
+      PixelType n = it.Get();
+      if (n.GetNorm() != 0)
+        n.Normalize();
+      
+      ito.Set(n);
+      ++it;
+      ++ito;
+    }
+    break;
+  default: // error ?
+    std::cerr << "ERROR : the operation number (" << mTypeOfOperation << ") is not known." << std::endl;
+    exit(-1);
+  }
+}
+//--------------------------------------------------------------------
+
+//--------------------------------------------------------------------
+template<class args_info_type>
+template<class Iter1, class Iter2, class Iter3>
+void  VectorArithmGenericFilter<args_info_type>::ComputeScalarImage(Iter1 it1, Iter2 it2, Iter3 ito)
+{
+  it1.GoToBegin();
+  it2.GoToBegin();
+  ito.GoToBegin();
+  typedef typename Iter3::PixelType PixelType;
+
+  switch (mTypeOfOperation) {
+  case 1: // Multiply
+    while (!ito.IsAtEnd()) {
+      ito.Set(it1.Get() * it2.Get());
+      ++it1;
+      ++it2;
+      ++ito;
+    }
+    break;
+  default: // error ?
+    std::cerr << "ERROR : the operation number (" << mTypeOfOperation << ") is not known." << std::endl;
+    exit(-1);
+  }
+}
+//--------------------------------------------------------------------
+
+//--------------------------------------------------------------------
+template<class args_info_type>
+template<class Iter1, class Iter2>
+void clitk::VectorArithmGenericFilter<args_info_type>::ComputeScalarImage(Iter1 it, Iter2 ito)
+{
+  ito.GoToBegin();
+  it.GoToBegin();
+  
+  typedef typename Iter2::PixelType PixelType;
+
+  // Perform operation
+  switch (mTypeOfOperation) {
+  case 5: // Absolute value
+    while (!it.IsAtEnd()) {
+      ito.Set(PixelTypeDownCast<double, PixelType>(it.Get().GetNorm()));
+      ++it;
+      ++ito;
+    }
+    break;
+  case 6: // Squared value
+    while (!it.IsAtEnd()) {
+      ito.Set(PixelTypeDownCast<double, PixelType>(it.Get().GetSquaredNorm()));
+      ++it;
+      ++ito;
+    }
+    break;
+  default: // error ?
+    std::cerr << "ERROR : the operation number (" << mTypeOfOperation << ") is not known." << std::endl;
+    exit(-1);
+  }
+}
+//--------------------------------------------------------------------
+
+
+} // end namespace
+
+#endif  //#define CLITKVectorArithmGENERICFILTER_TXX
index 07ddeb2eeb520f2b49f97cb3012842a96522b844..67a467dd820c0f681cba79b8806956c7f61b6770 100644 (file)
            <string>Bones</string>
           </property>
          </item>
+         <item>
+          <property name="text">
+           <string>Head/Brain</string>
+          </property>
+         </item>
          <item>
           <property name="text">
            <string>[0,1] Scale</string>
      <x>0</x>
      <y>0</y>
      <width>1008</width>
-     <height>29</height>
+     <height>18</height>
     </rect>
    </property>
    <property name="defaultUp">
index eb5fe7ec96b6ffaee4501de96ffdb27438e63925..5c7bbfd76f3ccb531c54b1ae01fe0b0d0358b33e 100644 (file)
@@ -958,7 +958,7 @@ void vvMainWindow::LoadImages(std::vector<std::string> files, vvImageReader::Loa
     double range[2];
     mSlicerManagers.back()->GetImage()->GetFirstVTKImageData()->GetScalarRange(range);
     if ((range[0] == 0) && (range[1] == 1)) {
-      presetComboBox->setCurrentIndex(5);// binary
+      presetComboBox->setCurrentIndex(WL_BINARY);// binary
     } else {
       // TODO
     }
@@ -1797,7 +1797,7 @@ void vvMainWindow::WindowLevelChanged()
 //------------------------------------------------------------------------------
 void vvMainWindow::WindowLevelEdited()
 {
-  presetComboBox->setCurrentIndex(6);
+  presetComboBox->setCurrentIndex(WL_USER);
   UpdateWindowLevel();
 }
 //------------------------------------------------------------------------------
@@ -1807,7 +1807,7 @@ void vvMainWindow::SetWindowLevel(double w, double l)
 {
   windowSpinBox->setValue(w);
   levelSpinBox->setValue(l);
-  presetComboBox->setCurrentIndex(6);
+  presetComboBox->setCurrentIndex(WL_USER);
   colorMapComboBox->setCurrentIndex(0);
   UpdateWindowLevel();
 }
@@ -1817,7 +1817,7 @@ void vvMainWindow::SetWindowLevel(double w, double l)
 void vvMainWindow::UpdateWindowLevel()
 {
   if (DataTree->selectedItems().size()) {
-    if (presetComboBox->currentIndex() == 7) //For ventilation
+    if (presetComboBox->currentIndex() == WL_VENTILATION) //For ventilation
       colorMapComboBox->setCurrentIndex(5);
     int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
     mSlicerManagers[index]->SetColorWindow(windowSpinBox->value());
@@ -1853,7 +1853,7 @@ void vvMainWindow::SwitchWindowLevel()
 {
   int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
   int window = mSlicerManagers[index]->GetColorWindow();
-  presetComboBox->setCurrentIndex(6);
+  presetComboBox->setCurrentIndex(WL_USER);
   windowSpinBox->setValue(-window);
   UpdateWindowLevel();
 }
@@ -1872,7 +1872,7 @@ void vvMainWindow::ApplyWindowLevelToAllImages()
       continue;
     mSlicerManagers[i]->SetColorWindow(window);
     mSlicerManagers[i]->SetColorLevel(level);
-    mSlicerManagers[i]->SetPreset(6);
+    mSlicerManagers[i]->SetPreset(WL_USER);
     mSlicerManagers[i]->Render();
   }
 }
@@ -1885,7 +1885,7 @@ void vvMainWindow::ApplyWindowToSetOfImages(double window, unsigned int indexMin
     if (mSlicerManagers[i] == NULL)
       continue;
     mSlicerManagers[i]->SetColorWindow(window);
-    mSlicerManagers[i]->SetPreset(6);
+    mSlicerManagers[i]->SetPreset(WL_USER);
     mSlicerManagers[i]->Render();
   }
 }
@@ -1898,7 +1898,7 @@ void vvMainWindow::ApplyLevelToSetOfImages(double level, unsigned int indexMin,
     if (mSlicerManagers[i] == NULL)
       continue;
     mSlicerManagers[i]->SetColorLevel(level);
-    mSlicerManagers[i]->SetPreset(6);
+    mSlicerManagers[i]->SetPreset(WL_USER);
     mSlicerManagers[i]->Render();
   }
 }
index efaf80fde672006a3926428eb8b271163bd30eb5..30a8f1034931e169815e884c2ada69129a72ae4c 100644 (file)
@@ -71,6 +71,7 @@
 #include <vtkImageReslice.h>
 #if VTK_MAJOR_VERSION >= 6 || (VTK_MAJOR_VERSION >= 5 && VTK_MINOR_VERSION >= 10)
 #  include <vtkImageMapper3D.h>
+#  include <vtkImageSliceMapper.h>
 #endif
 
 vtkCxxRevisionMacro(vvSlicer, "DummyRevision");
@@ -144,6 +145,7 @@ vvSlicer::vvSlicer()
   this->InstallPipeline();
 
   mLinkOverlayWindowLevel = true;
+  mImageVisibility = true;
 
 #if VTK_MAJOR_VERSION >= 6 || (VTK_MAJOR_VERSION >= 5 && VTK_MINOR_VERSION >= 10)
   this->GetImageActor()->GetMapper()->BorderOn();
@@ -367,6 +369,7 @@ void vvSlicer::SetOverlay(vvImage::Pointer overlay)
 {
   if (overlay->GetVTKImages().size()) {
     mOverlay = overlay;
+    mOverlayVisibility = true;
     
     if (!mOverlayReslice) {
       mOverlayReslice = vtkSmartPointer<vtkImageReslice>::New();
@@ -420,6 +423,7 @@ void vvSlicer::SetFusion(vvImage::Pointer fusion, int fusionSequenceCode)
        mFusionSequenceCode = fusionSequenceCode;
   if (fusion->GetVTKImages().size()) {
     mFusion = fusion;
+    mFusionVisibility = true;
 
     if (!mFusionReslice) {
       mFusionReslice = vtkSmartPointer<vtkImageReslice>::New();
@@ -471,21 +475,16 @@ void vvSlicer::SetFusion(vvImage::Pointer fusion, int fusionSequenceCode)
 bool vvSlicer::GetActorVisibility(const std::string& actor_type, int overlay_index)
 {
   bool vis = false;
-  if (actor_type == "image") {
-    vis = this->ImageActor->GetVisibility();
-  }
-  else if (actor_type == "vector") {
-    vis = this->mVFActor->GetVisibility();
-  }
-  else if (actor_type == "overlay") {
-    vis = this->mOverlayActor->GetVisibility();
-  }
-  else if ( (actor_type == "fusion") || (actor_type == "fusionSequence") ){
-    vis = this->mFusionActor->GetVisibility();
-  }
+  if (actor_type == "image")
+    vis = mImageVisibility;
+  else if (actor_type == "vector")
+    vis = mVFVisibility;
+  else if (actor_type == "overlay")
+    vis = mOverlayVisibility;
+  else if ( (actor_type == "fusion") || (actor_type == "fusionSequence") )
+    vis = mFusionVisibility;
   else if (actor_type == "contour")
     vis = this->mSurfaceCutActors[overlay_index]->GetActor()->GetVisibility();
-
   return vis;
 }
 //------------------------------------------------------------------------------
@@ -493,18 +492,14 @@ bool vvSlicer::GetActorVisibility(const std::string& actor_type, int overlay_ind
 //------------------------------------------------------------------------------
 void vvSlicer::SetActorVisibility(const std::string& actor_type, int overlay_index ,bool vis)
 {
-  if (actor_type == "image") {
-    this->ImageActor->SetVisibility(vis);
-  }
-  else if (actor_type == "vector") {
-    this->mVFActor->SetVisibility(vis);
-  }
-  else if (actor_type == "overlay") {
-    this->mOverlayActor->SetVisibility(vis);
-  }
-  else if ( (actor_type == "fusion") || (actor_type == "fusionSequence") ){
-    this->mFusionActor->SetVisibility(vis);
-  }
+  if (actor_type == "image")
+    mImageVisibility = vis;
+  else if (actor_type == "vector")
+    mVFVisibility = vis;
+  else if (actor_type == "overlay")
+    mOverlayVisibility = vis;
+  else if ( (actor_type == "fusion") || (actor_type == "fusionSequence") )
+    mFusionVisibility = vis;
   else if (actor_type == "contour")
     this->mSurfaceCutActors[overlay_index]->GetActor()->SetVisibility(vis);
   UpdateDisplayExtent();
@@ -516,6 +511,7 @@ void vvSlicer::SetVF(vvImage::Pointer vf)
 {
   if (vf->GetVTKImages().size()) {
     mVF = vf;
+    mVFVisibility = true;
 
     if (!mAAFilter) {
       mAAFilter= vtkSmartPointer<vtkAssignAttribute>::New();
@@ -905,8 +901,13 @@ void vvSlicer::AdjustResliceToSliceOrientation(vtkImageReslice *reslice)
   // Step 1: from world coordinates to image coordinates
   origin[this->SliceOrientation] -= mImageReslice->GetOutput()->GetOrigin()[this->SliceOrientation];
   origin[this->SliceOrientation] /= mImageReslice->GetOutput()->GetSpacing()[this->SliceOrientation];
-  // Step 2: round to superior grid positionInc
-  origin[this->SliceOrientation] = itk::Math::Ceil<double>(origin[this->SliceOrientation]);
+
+  // Step 2: round to nearest grid positionInc. This has been validated as the only
+  // way to have something consistent with the thickness of a 2D slice visible on the
+  // other slices. The thickness is accounted for so if the 2D slice is to thin and
+  // between two slices, one will never be able to see this 2D slice (bug #1883).
+  origin[this->SliceOrientation] = itk::Math::Round<double>(origin[this->SliceOrientation]);
+
   // Step 3: back to world coordinates
   origin[this->SliceOrientation] *= mImageReslice->GetOutput()->GetSpacing()[this->SliceOrientation];
   origin[this->SliceOrientation] += mImageReslice->GetOutput()->GetOrigin()[this->SliceOrientation];
@@ -957,25 +958,44 @@ void vvSlicer::UpdateDisplayExtent()
   w_ext[ this->SliceOrientation*2+1 ] = this->Slice;
   
   // Image actor
+  this->ImageActor->SetVisibility(mImageVisibility);
   this->ImageActor->SetDisplayExtent(w_ext);
-  
+#if VTK_MAJOR_VERSION >= 6 || (VTK_MAJOR_VERSION >= 5 && VTK_MINOR_VERSION >= 10)
+  // Fix for bug #1882
+  dynamic_cast<vtkImageSliceMapper *>(this->ImageActor->GetMapper())->SetOrientation(this->GetOrientation());
+#endif
+
   // Overlay image actor
-  if (mOverlay && mOverlayActor->GetVisibility()) {
+  if (mOverlay && mOverlayVisibility) {
     AdjustResliceToSliceOrientation(mOverlayReslice);
     int overExtent[6];
     this->ConvertImageToImageDisplayExtent(input, w_ext, mOverlayReslice->GetOutput(), overExtent);
-    ClipDisplayedExtent(overExtent, mOverlayMapper->GetInput()->GetWholeExtent());
+    bool out = ClipDisplayedExtent(overExtent, mOverlayMapper->GetInput()->GetWholeExtent());
+    mOverlayActor->SetVisibility(!out);
     mOverlayActor->SetDisplayExtent( overExtent );
+#if VTK_MAJOR_VERSION >= 6 || (VTK_MAJOR_VERSION >= 5 && VTK_MINOR_VERSION >= 10)
+    // Fix for bug #1882
+    dynamic_cast<vtkImageSliceMapper *>(mOverlayActor->GetMapper())->SetOrientation(this->GetOrientation());
+#endif
   }
+  else if(mOverlay)
+    mOverlayActor->SetVisibility(false);
 
   // Fusion image actor
-  if (mFusion && mFusionActor->GetVisibility()) {
+  if (mFusion && mFusionVisibility) {
     AdjustResliceToSliceOrientation(mFusionReslice);
     int fusExtent[6];
     this->ConvertImageToImageDisplayExtent(input, w_ext, mFusionReslice->GetOutput(), fusExtent);
-    ClipDisplayedExtent(fusExtent, mFusionMapper->GetInput()->GetWholeExtent());
-    mFusionActor->SetDisplayExtent(fusExtent);
+    bool out = ClipDisplayedExtent(fusExtent, mFusionMapper->GetInput()->GetWholeExtent());
+    mFusionActor->SetVisibility(!out);
+    mFusionActor->SetDisplayExtent( fusExtent );
+#if VTK_MAJOR_VERSION >= 6 || (VTK_MAJOR_VERSION >= 5 && VTK_MINOR_VERSION >= 10)
+    // Fix for bug #1882
+    dynamic_cast<vtkImageSliceMapper *>(mFusionActor->GetMapper())->SetOrientation(this->GetOrientation());
+#endif
   }
+  else if(mFusion)
+    mFusionActor->SetVisibility(false);
 
   // Vector field actor
   double* camera = Renderer->GetActiveCamera()->GetPosition();
@@ -995,11 +1015,12 @@ void vvSlicer::UpdateDisplayExtent()
   if (camera[this->SliceOrientation] < image_bounds[this->SliceOrientation*2])
     offset = -1;
   
-  if (mVF && mVFActor->GetVisibility()) {
+  if (mVF && mVFVisibility) {
     int vfExtent[6];
     mVF->GetVTKImages()[0]->UpdateInformation();
     this->ConvertImageToImageDisplayExtent(input, w_ext, mVF->GetVTKImages()[0], vfExtent);
-    ClipDisplayedExtent(vfExtent, mVOIFilter->GetInput()->GetWholeExtent());
+    bool out = ClipDisplayedExtent(vfExtent, mVOIFilter->GetInput()->GetWholeExtent());
+    mVFActor->SetVisibility(!out);
     mVOIFilter->SetVOI(vfExtent);
     int orientation[3] = {1,1,1};
     orientation[this->SliceOrientation] = 0;
@@ -1009,7 +1030,9 @@ void vvSlicer::UpdateDisplayExtent()
     position[this->SliceOrientation] += offset;
     mVFActor->SetPosition(position);
   }
-  
+  else if(mVF)
+    mVFActor->SetVisibility(false);
+
   // Landmarks actor
   if (mLandActor) {
     if (mClipBox) {
@@ -1060,26 +1083,23 @@ void vvSlicer::ConvertImageToImageDisplayExtent(vtkImageData *sourceImage, const
     // From world coordinates to floating point target voxel coordinates
     dExtents[i] = (dExtents[i]- targetImage->GetOrigin()[i/2]) / targetImage->GetSpacing()[i/2];
     
-    // Round to nearest
-    //targetExtent[i] = itk::Math::Round<double>(dExtents[i]);
-    targetExtent[i] = itk::Math::Floor<double>(dExtents[i]);
+    // Round to current slice or larger extent
+    if(i/2==this->GetOrientation())
+      targetExtent[i] = itk::Math::Round<double>(dExtents[i]);
+    else if(i%2==1)
+      targetExtent[i] = itk::Math::Ceil<double>(dExtents[i]);
+    else
+      targetExtent[i] = itk::Math::Floor<double>(dExtents[i]);
   }
 }
 //----------------------------------------------------------------------------
 
 //----------------------------------------------------------------------------
-void vvSlicer::ClipDisplayedExtent(int extent[6], int refExtent[6])
+bool vvSlicer::ClipDisplayedExtent(int extent[6], int refExtent[6])
 {
   bool out = false;
   int maxBound = 6;
 
-  //2D overlay on 3D image specific case
-  if (refExtent[4] == refExtent[5]) {
-    maxBound = 4;
-    extent[4] = refExtent[4];
-    extent[5] = refExtent[5];
-  }
-
   for (int i = 0; i < maxBound; i = i+2) {
     //if we are totally outside the image
     if ( extent[i] > refExtent[i+1] || extent[i+1] < refExtent[i] ) {
@@ -1087,16 +1107,17 @@ void vvSlicer::ClipDisplayedExtent(int extent[6], int refExtent[6])
       break;
     }
     //crop to the limit of the image
-    extent[i] = (extent[i] > refExtent[i]) ? extent[i] : refExtent[i];
-    extent[i] = (extent[i] < refExtent[i+1]) ? extent[i] : refExtent[i+1];
-    extent[i+1] = (extent[i+1] > refExtent[i]) ? extent[i+1] : refExtent[i];
-    extent[i+1] = (extent[i+1] < refExtent[i+1]) ? extent[i+1] : refExtent[i+1];
+    extent[i] = std::max(extent[i], refExtent[i]);
+    extent[i] = std::min(extent[i], refExtent[i+1]);;
+    extent[i+1] = std::max(extent[i+1], refExtent[i]);
+    extent[i+1] = std::min(extent[i+1], refExtent[i+1]);;
   }
   if (out)
     for (int i = 0; i < maxBound; i = i+2) {
       extent[i] = refExtent[i];
       extent[i+1] = refExtent[i];
     }
+  return out;
 }
 //----------------------------------------------------------------------------
 
index 7746331a21d3ad2f337f63bdb7df79b44c011dab..570c43ddcbd83b027fab6b7ac7f2a87f7e0c453a 100644 (file)
@@ -197,7 +197,7 @@ public:
   void EnableReducedExtent(bool b);
   void SetReducedExtent(int * ext);
 
-  void ClipDisplayedExtent(int extent[6], int refExtent[6]);
+  bool ClipDisplayedExtent(int extent[6], int refExtent[6]);
   int GetOrientation();
   int * GetExtent();
 
@@ -289,6 +289,13 @@ private:
   ///Sets the surfaces to be cut on the image slice: update the vtkCutter
   void SetContourSlice();
 
-
+  // Visibility of the different elements that can be set from outside the object.
+  // Note that vvSlicer also check if the element is to be displayed according to
+  // the extent of the displayed object.
+  // These members have been introduced to fix Bug #1883.
+  bool mImageVisibility;
+  bool mOverlayVisibility;
+  bool mFusionVisibility;
+  bool mVFVisibility;
 };
 #endif
index 67f78bc71158122f40901ed5231230e5dee76acd..e975da28babd5ee04bdb31120ccd77bd50b5412f 100644 (file)
@@ -1244,41 +1244,46 @@ void vvSlicerManager::SetSlicingPreset(SlicingPresetType preset)
 //----------------------------------------------------------------------------\r
 void vvSlicerManager::SetPreset(int preset)\r
 {\r
+\r
   //vtkLookupTable* LUT = static_cast<vtkLookupTable*>(mSlicers[0]->GetWindowLevel()->GetLookupTable());\r
   double window = mSlicers[0]->GetColorWindow();\r
   double level = mSlicers[0]->GetColorLevel();\r
 \r
   std::string component_type=mImage->GetScalarTypeAsITKString();\r
   switch (preset) {\r
-  case 0:\r
+  case WL_AUTO:\r
     double range[2];\r
     mImage->GetScalarRange(range);\r
     window = range[1] - range[0];\r
     level = (range[1] + range[0])* 0.5;\r
     break;\r
-  case 1:\r
+  case WL_HOUNSFIELD:\r
     window = 2000;\r
     level = 0;\r
     break;\r
-  case 2:\r
+  case WL_SOFTTISSUE:\r
     window = 400;\r
     level = 20;\r
     break;\r
-  case 3: // lungs (same as FOCAL)\r
+  case WL_LUNGS: // lungs (same as FOCAL)\r
     window = 1700;\r
     level = -300;\r
     break;\r
-  case 4:\r
+  case WL_BONES:\r
     window = 1000;\r
     level = 500;\r
     break;\r
-  case 5:\r
+  case WL_HEAD:\r
+    window = 200;\r
+    level = 70;\r
+    break;\r
+  case WL_BINARY:\r
     window = 1;\r
     level = 0.5;\r
     break;\r
-  case 6:\r
+  case WL_USER:\r
     break;\r
-  case 7:\r
+  case WL_VENTILATION:\r
     window=1.;\r
     level=0.;\r
     break;\r
@@ -1328,7 +1333,7 @@ void vvSlicerManager::SetLocalColorWindowing(const int slicer, const bool bCtrlK
                                                           this->mSlicers[slicer]->GetConcatenatedTransform());\r
     this->SetColorWindow(max-min);\r
     this->SetColorLevel(0.5*(min+max));\r
-    this->SetPreset(6);\r
+    this->SetPreset(WL_USER);\r
   }\r
   this->Render();\r
   this->UpdateWindowLevel();\r
index d634fbddafd779ecf7ae817178e5536fad5ed1fb..3479dc6c887dfc20d5ea5e844187345261f52f00 100644 (file)
@@ -47,6 +47,18 @@ class vvImageReader;
 class vvImageReader;
 class vvLandmarks;
 
+enum WindowLevelPreset {
+  WL_AUTO,
+  WL_HOUNSFIELD,
+  WL_SOFTTISSUE,
+  WL_LUNGS,
+  WL_BONES,
+  WL_HEAD,
+  WL_BINARY,
+  WL_USER,
+  WL_VENTILATION
+};
+
 //------------------------------------------------------------------------------
 class vvSlicerManager : public QObject {
   Q_OBJECT
index ad80b925a6d0b5bfc34fe6516e5f1d889bf9c003..f5d2b699bd495e881d533abaad7c20a43d511c83 100644 (file)
@@ -113,33 +113,33 @@ void vvSlicerManagerCommand::Execute(vtkObject *caller,
           return;
         }
         if (KeyPress == "0") {
-          this->SM->SetPreset(0);
+          this->SM->SetPreset(WL_AUTO);
           this->SM->UpdateWindowLevel();
           return;
         }
         if (KeyPress == "1") {
-          this->SM->SetPreset(1);
+          this->SM->SetPreset(WL_HOUNSFIELD);
           this->SM->UpdateWindowLevel();
           return;
         }
         if (KeyPress == "2") {
-          this->SM->SetPreset(2);
+          this->SM->SetPreset(WL_SOFTTISSUE);
           this->SM->UpdateWindowLevel();
 
           return;
         }
         if (KeyPress == "3") {
-          this->SM->SetPreset(3);
+          this->SM->SetPreset(WL_LUNGS);
           this->SM->UpdateWindowLevel();
           return;
         }
         if (KeyPress == "4") {
-          this->SM->SetPreset(4);
+          this->SM->SetPreset(WL_BONES);
           this->SM->UpdateWindowLevel();
           return;
         }
         if (KeyPress == "5") {
-          this->SM->SetPreset(5);
+          this->SM->SetPreset(WL_HEAD);
           this->SM->UpdateWindowLevel();
           return;
         }
@@ -164,7 +164,7 @@ void vvSlicerManagerCommand::Execute(vtkObject *caller,
           return;
         }
         if (KeyPress == "equal") { //keycodes are in vtkWin32RenderWindowInteractor
-          this->SM->SetPreset(7);
+          this->SM->SetPreset(WL_VENTILATION);
           //this->SM->SetColorMap(1);
           this->SM->UpdateWindowLevel();
           return;
@@ -420,7 +420,7 @@ void vvSlicerManagerCommand::Execute(vtkObject *caller,
 
       this->SM->SetColorWindow(window*dx);
       this->SM->SetColorLevel(level-dy);
-      this->SM->SetPreset(6);
+      this->SM->SetPreset(WL_USER);
       this->SM->Render();
       this->SM->UpdateWindowLevel();
       return;