# 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})
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")
ENDMACRO (ROOT_GENERATE_DICTIONARY)
-#MESSAGE("la")
\ No newline at end of file
+#MESSAGE("la")
+++ /dev/null
-# - 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)
-
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
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})
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})
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} )
#include <gdcmReader.h>
#endif
+#include <set>
+
//====================================================================
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
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)
{
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;
//===========================================
// 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;
}
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
// 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);
- }
- }
}
}; // 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
//--------------------------------------------------------------------
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);
}
//--------------------------------------------------------------------
--- /dev/null
+/*=========================================================================
+ 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 */
--- /dev/null
+#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"
+
--- /dev/null
+/*=========================================================================
+ 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
+
--- /dev/null
+/*=========================================================================
+ 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 */
+
--- /dev/null
+/*=========================================================================
+ 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 */
+
--- /dev/null
+/*=========================================================================
+ 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
--- /dev/null
+#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
--- /dev/null
+/*=========================================================================
+ 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
--- /dev/null
+/*=========================================================================
+ 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
+
--- /dev/null
+/*=========================================================================
+ 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
<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">
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
}
//------------------------------------------------------------------------------
void vvMainWindow::WindowLevelEdited()
{
- presetComboBox->setCurrentIndex(6);
+ presetComboBox->setCurrentIndex(WL_USER);
UpdateWindowLevel();
}
//------------------------------------------------------------------------------
{
windowSpinBox->setValue(w);
levelSpinBox->setValue(l);
- presetComboBox->setCurrentIndex(6);
+ presetComboBox->setCurrentIndex(WL_USER);
colorMapComboBox->setCurrentIndex(0);
UpdateWindowLevel();
}
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());
{
int index = GetSlicerIndexFromItem(DataTree->selectedItems()[0]);
int window = mSlicerManagers[index]->GetColorWindow();
- presetComboBox->setCurrentIndex(6);
+ presetComboBox->setCurrentIndex(WL_USER);
windowSpinBox->setValue(-window);
UpdateWindowLevel();
}
continue;
mSlicerManagers[i]->SetColorWindow(window);
mSlicerManagers[i]->SetColorLevel(level);
- mSlicerManagers[i]->SetPreset(6);
+ mSlicerManagers[i]->SetPreset(WL_USER);
mSlicerManagers[i]->Render();
}
}
if (mSlicerManagers[i] == NULL)
continue;
mSlicerManagers[i]->SetColorWindow(window);
- mSlicerManagers[i]->SetPreset(6);
+ mSlicerManagers[i]->SetPreset(WL_USER);
mSlicerManagers[i]->Render();
}
}
if (mSlicerManagers[i] == NULL)
continue;
mSlicerManagers[i]->SetColorLevel(level);
- mSlicerManagers[i]->SetPreset(6);
+ mSlicerManagers[i]->SetPreset(WL_USER);
mSlicerManagers[i]->Render();
}
}
#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");
this->InstallPipeline();
mLinkOverlayWindowLevel = true;
+ mImageVisibility = true;
#if VTK_MAJOR_VERSION >= 6 || (VTK_MAJOR_VERSION >= 5 && VTK_MINOR_VERSION >= 10)
this->GetImageActor()->GetMapper()->BorderOn();
{
if (overlay->GetVTKImages().size()) {
mOverlay = overlay;
+ mOverlayVisibility = true;
if (!mOverlayReslice) {
mOverlayReslice = vtkSmartPointer<vtkImageReslice>::New();
mFusionSequenceCode = fusionSequenceCode;
if (fusion->GetVTKImages().size()) {
mFusion = fusion;
+ mFusionVisibility = true;
if (!mFusionReslice) {
mFusionReslice = vtkSmartPointer<vtkImageReslice>::New();
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;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
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();
{
if (vf->GetVTKImages().size()) {
mVF = vf;
+ mVFVisibility = true;
if (!mAAFilter) {
mAAFilter= vtkSmartPointer<vtkAssignAttribute>::New();
// 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];
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();
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;
position[this->SliceOrientation] += offset;
mVFActor->SetPosition(position);
}
-
+ else if(mVF)
+ mVFActor->SetVisibility(false);
+
// Landmarks actor
if (mLandActor) {
if (mClipBox) {
// 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] ) {
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;
}
//----------------------------------------------------------------------------
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();
///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
//----------------------------------------------------------------------------\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
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
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
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;
}
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;
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;