diff --git a/CMake/PackageDepends/MITK_Boost_Config.cmake b/CMake/PackageDepends/MITK_Boost_Config.cmake index c1606aaa95..e695001bf2 100644 --- a/CMake/PackageDepends/MITK_Boost_Config.cmake +++ b/CMake/PackageDepends/MITK_Boost_Config.cmake @@ -1,30 +1,31 @@ if(MITK_USE_Boost) if(NOT MITK_USE_SYSTEM_Boost) set(Boost_NO_SYSTEM_PATHS 1) endif() set(Boost_USE_MULTITHREADED 1) set(Boost_USE_STATIC_LIBS 0) set(Boost_USE_STATIC_RUNTIME 0) if(MITK_USE_Boost_LIBRARIES) if(NOT MITK_USE_SYSTEM_Boost) - set(BOOST_INCLUDEDIR ${CMAKE_BINARY_DIR}/../Boost-install/include/boost-1_54) + set(BOOST_INCLUDEDIR ${CMAKE_BINARY_DIR}/../Boost-install/include) set(BOOST_LIBRARYDIR ${CMAKE_BINARY_DIR}/../Boost-install/lib) + set(Boost_ADDITIONAL_VERSIONS 1.54) # Following line is temporary, see bug #15837. set(Boost_DEBUG TRUE) endif() find_package(Boost 1.54.0 REQUIRED COMPONENTS ${MITK_USE_Boost_LIBRARIES}) else() find_package(Boost 1.54.0 REQUIRED) endif() list(APPEND ALL_INCLUDE_DIRECTORIES ${Boost_INCLUDE_DIRS}) if(Boost_LIBRARIES) list(APPEND ALL_LIBRARIES ${Boost_LIBRARIES}) link_directories(${Boost_LIBRARY_DIRS}) endif() endif(MITK_USE_Boost) diff --git a/CMake/mitkFunctionGetLibrarySearchPaths.cmake b/CMake/mitkFunctionGetLibrarySearchPaths.cmake index 078c513b0d..4efd088b58 100644 --- a/CMake/mitkFunctionGetLibrarySearchPaths.cmake +++ b/CMake/mitkFunctionGetLibrarySearchPaths.cmake @@ -1,85 +1,85 @@ function(mitkFunctionGetLibrarySearchPaths search_path intermediate_dir) set(_dir_candidates ${MITK_VTK_LIBRARY_DIRS} ${MITK_ITK_LIBRARY_DIRS} ${QT_LIBRARY_DIR} ${QT_LIBRARY_DIR}/../bin ${MITK_BINARY_DIR}/bin ${MITK_BINARY_DIR}/bin/plugins) get_property(_additional_paths GLOBAL PROPERTY MITK_ADDITIONAL_LIBRARY_SEARCH_PATHS) if(_additional_paths) list(APPEND _dir_candidates ${_additional_paths}) endif() if(WIN32) if(DCMTK_DIR) list(APPEND _dir_candidates "${DCMTK_DIR}/bin") endif() list(APPEND _dir_candidates "${ITK_DIR}/bin") else() if(DCMTK_DIR) list(APPEND _dir_candidates "${DCMTK_DIR}/lib") endif() list(APPEND _dir_candidates "${ITK_DIR}/lib") endif() if(MITK_USE_Python AND CTK_PYTHONQT_INSTALL_DIR) list(APPEND _dir_candidates ${CTK_PYTHONQT_INSTALL_DIR}/bin) endif() if(MITK_USE_Boost AND MITK_USE_Boost_LIBRARIES AND NOT MITK_USE_SYSTEM_Boost) - list(APPEND _dir_candidates ${Boost_LIBRARY_DIRS}) + list(APPEND _dir_candidates ${Boost_LIBRARY_DIR}) endif() if(ACVD_DIR) list(APPEND _dir_candidates ${ACVD_DIR}/bin) endif() if(GDCM_DIR) list(APPEND _dir_candidates ${GDCM_DIR}/bin) endif() if(OpenCV_DIR) list(APPEND _dir_candidates ${OpenCV_DIR}/bin) endif() if(SOFA_DIR) list(APPEND _dir_candidates ${SOFA_DIR}/bin) endif() if(MITK_USE_TOF_PMDO3 OR MITK_USE_TOF_PMDCAMCUBE OR MITK_USE_TOF_PMDCAMBOARD) list(APPEND _dir_candidates ${MITK_PMD_SDK_DIR}/plugins) endif() if(MITK_USE_BLUEBERRY) list(APPEND _dir_candidates ${CTK_RUNTIME_LIBRARY_DIRS}) if(DEFINED CTK_PLUGIN_RUNTIME_OUTPUT_DIRECTORY) if(IS_ABSOLUTE "${CTK_PLUGIN_RUNTIME_OUTPUT_DIRECTORY}") list(APPEND _dir_candidates "${CTK_PLUGIN_RUNTIME_OUTPUT_DIRECTORY}") else() list(APPEND _dir_candidates "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CTK_PLUGIN_RUNTIME_OUTPUT_DIRECTORY}") endif() endif() endif() if(MITK_LIBRARY_DIRS) list(APPEND _dir_candidates ${MITK_LIBRARY_DIRS}) endif() list(REMOVE_DUPLICATES _dir_candidates) set(_search_dirs ) foreach(_dir ${_dir_candidates}) if(EXISTS "${_dir}/${intermediate_dir}") list(APPEND _search_dirs "${_dir}/${intermediate_dir}") else() list(APPEND _search_dirs ${_dir}) endif() endforeach() # Special handling for "internal" search dirs. The intermediate directory # might not have been created yet, so we can't check for its existence. # Hence we just add it for Windows without checking. set(_internal_search_dirs ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/plugins) if(WIN32) foreach(_dir ${_internal_search_dirs}) set(_search_dirs ${_dir}/${intermediate_dir} ${_search_dirs}) endforeach() else() set(_search_dirs ${_internal_search_dirs} ${_search_dirs}) endif() list(REMOVE_DUPLICATES _search_dirs) set(${search_path} ${_search_dirs} PARENT_SCOPE) endfunction() diff --git a/CMakeExternals/SOFA.cmake b/CMakeExternals/SOFA.cmake index c22c470b93..e1135c1736 100644 --- a/CMakeExternals/SOFA.cmake +++ b/CMakeExternals/SOFA.cmake @@ -1,78 +1,79 @@ #----------------------------------------------------------------------------- # SOFA #----------------------------------------------------------------------------- if(MITK_USE_SOFA) # Sanity checks if(DEFINED SOFA_DIR AND NOT EXISTS ${SOFA_DIR}) message(FATAL_ERROR "SOFA_DIR variable is defined but corresponds to non-existing directory") endif() set(proj SOFA) set(proj_DEPENDENCIES Boost) set(SOFA_DEPENDS ${proj}) set(additional_cmake_args -DSOFA-APPLICATION_MODELER:BOOL=OFF -DSOFA-APPLICATION_RUNSOFA:BOOL=OFF -DSOFA-APPLICATION_SOFABATCH:BOOL=OFF -DSOFA-EXTERNAL_BOOST_PATH:PATH=${CMAKE_BINARY_DIR}/Boost-install/lib -DSOFA-EXTERNAL_HAVE_BOOST:BOOL=ON -DSOFA-EXTERNAL_HAVE_GLEW:BOOL=OFF -DSOFA-EXTERNAL_HAVE_ZLIB:BOOL=OFF -DSOFA-EXTERNAL_HAVE_PNG:BOOL=OFF -DSOFA-LIB_COMPONENT_OPENGL_VISUAL:BOOL=OFF -DSOFA-LIB_GUI_GLUT:BOOL=OFF -DSOFA-LIB_GUI_QTVIEWER:BOOL=OFF -DSOFA-MISC_NO_OPENGL:BOOL=ON -DSOFA-TUTORIAL_CHAIN_HYBRID:BOOL=OFF -DSOFA-TUTORIAL_COMPOSITE_OBJECT:BOOL=OFF -DSOFA-TUTORIAL_MIXED_PENDULUM:BOOL=OFF -DSOFA-TUTORIAL_ONE_PARTICLE:BOOL=OFF -DSOFA-TUTORIAL_ONE_TETRAHEDRON:BOOL=OFF ) if(NOT MITK_USE_SYSTEM_Boost) list(APPEND boost_cmake_args -DBoost_DEBUG:BOOL=ON -DBoost_NO_SYSTEM_PATHS:BOOL=ON - -DBOOST_INCLUDEDIR:PATH=${CMAKE_BINARY_DIR}/Boost-install/include/boost-1_54 + -DBOOST_INCLUDEDIR:PATH=${CMAKE_BINARY_DIR}/Boost-install/include -DBOOST_LIBRARYDIR:PATH=${CMAKE_BINARY_DIR}/Boost-install/lib + -DBoost_ADDITIONAL_VERSIONS:STRING=1.54 ) endif() set(rev "9832") set(SOFA_PATCH_COMMAND ${CMAKE_COMMAND} -DTEMPLATE_FILE:FILEPATH=${MITK_SOURCE_DIR}/CMakeExternals/EmptyFileForPatching.dummy -P ${MITK_SOURCE_DIR}/CMakeExternals/PatchSOFA-rev${rev}.cmake) set(SOFA_PRECONFIGURE_COMMAND ${CMAKE_COMMAND} -G${gen} ${ep_common_args} ${boost_cmake_args} ${CMAKE_BINARY_DIR}/${proj}-src) if(NOT DEFINED SOFA_DIR) ExternalProject_Add(${proj} SOURCE_DIR ${CMAKE_BINARY_DIR}/${proj}-src BINARY_DIR ${proj}-build PREFIX ${proj}-cmake URL http://mitk.org/download/thirdparty/SOFA-rev${rev}.tar.gz URL_MD5 ff65b2813dcc27755844f95cb0392bcf PATCH_COMMAND ${SOFA_PATCH_COMMAND} INSTALL_COMMAND "" CMAKE_GENERATOR ${gen} CMAKE_ARGS ${ep_common_args} ${additional_cmake_args} ${boost_cmake_args} DEPENDS ${proj_DEPENDENCIES} ) ExternalProject_Add_Step(${proj} preconfigure COMMAND ${SOFA_PRECONFIGURE_COMMAND} WORKING_DIRECTORY ${proj}-build DEPENDEES patch DEPENDERS configure LOG 1 ) set(SOFA_DIR ${CMAKE_CURRENT_BINARY_DIR}/${proj}-build) else() mitkMacroEmptyExternalProject(${proj} "${proj}_DEPENDENCIES}") endif() endif() diff --git a/Core/Code/IO/mitkPixelTypeMultiplex.h b/Core/Code/IO/mitkPixelTypeMultiplex.h index 71431b9ed6..23b4434b0a 100644 --- a/Core/Code/IO/mitkPixelTypeMultiplex.h +++ b/Core/Code/IO/mitkPixelTypeMultiplex.h @@ -1,141 +1,141 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef MITKPIXELTYPEMULTIPLEX_H #define MITKPIXELTYPEMULTIPLEX_H #define mitkPixelTypeMultiplex0( function, ptype ) \ { \ if ( ptype.GetComponentType() == itk::ImageIOBase::CHAR )\ - function( ptype, );\ + function( ptype );\ else if ( ptype.GetComponentType() == itk::ImageIOBase::UCHAR)\ - function( ptype, );\ + function( ptype );\ else if ( ptype.GetComponentType() == itk::ImageIOBase::SHORT )\ - function( ptype, ); \ + function( ptype ); \ else if ( ptype.GetComponentType() == itk::ImageIOBase::USHORT )\ - function( ptype, );\ + function( ptype );\ else if ( ptype.GetComponentType() == itk::ImageIOBase::INT )\ - function( ptype, );\ + function( ptype );\ else if ( ptype.GetComponentType() == itk::ImageIOBase::UINT )\ - function( ptype, );\ + function( ptype );\ else if ( ptype.GetComponentType() == itk::ImageIOBase::LONG )\ - function( ptype, );\ + function( ptype );\ else if ( ptype.GetComponentType() == itk::ImageIOBase::ULONG )\ - function( ptype, );\ + function( ptype );\ else if ( ptype.GetComponentType() == itk::ImageIOBase::FLOAT )\ - function( ptype, );\ + function( ptype );\ else if ( ptype.GetComponentType() == itk::ImageIOBase::DOUBLE )\ - function( ptype, );\ + function( ptype );\ }\ #define mitkPixelTypeMultiplex1( function, ptype, param1 ) \ { \ if ( ptype.GetComponentType() == itk::ImageIOBase::CHAR )\ function( ptype, param1 );\ else if ( ptype.GetComponentType() == itk::ImageIOBase::UCHAR)\ function( ptype, param1 );\ else if ( ptype.GetComponentType() == itk::ImageIOBase::SHORT )\ function( ptype, param1 ); \ else if ( ptype.GetComponentType() == itk::ImageIOBase::USHORT )\ function( ptype, param1 );\ else if ( ptype.GetComponentType() == itk::ImageIOBase::INT )\ function( ptype, param1 );\ else if ( ptype.GetComponentType() == itk::ImageIOBase::UINT )\ function( ptype, param1 );\ else if ( ptype.GetComponentType() == itk::ImageIOBase::LONG )\ function( ptype, param1 );\ else if ( ptype.GetComponentType() == itk::ImageIOBase::ULONG )\ function( ptype, param1 );\ else if ( ptype.GetComponentType() == itk::ImageIOBase::FLOAT )\ function( ptype, param1 );\ else if ( ptype.GetComponentType() == itk::ImageIOBase::DOUBLE )\ function( ptype, param1 );\ }\ #define mitkPixelTypeMultiplex2( function, ptype, param1, param2 ) \ { \ if ( ptype.GetComponentType() == itk::ImageIOBase::CHAR )\ function( ptype, param1, param2 );\ else if ( ptype.GetComponentType() == itk::ImageIOBase::UCHAR)\ function( ptype, param1, param2 );\ else if ( ptype.GetComponentType() == itk::ImageIOBase::SHORT )\ function( ptype, param1, param2 ); \ else if ( ptype.GetComponentType() == itk::ImageIOBase::USHORT )\ function( ptype, param1, param2 );\ else if ( ptype.GetComponentType() == itk::ImageIOBase::INT )\ function( ptype, param1, param2 );\ else if ( ptype.GetComponentType() == itk::ImageIOBase::UINT )\ function( ptype, param1, param2 );\ else if ( ptype.GetComponentType() == itk::ImageIOBase::LONG )\ function( ptype, param1, param2 );\ else if ( ptype.GetComponentType() == itk::ImageIOBase::ULONG )\ function( ptype, param1, param2 );\ else if ( ptype.GetComponentType() == itk::ImageIOBase::FLOAT )\ function( ptype, param1, param2 );\ else if ( ptype.GetComponentType() == itk::ImageIOBase::DOUBLE )\ function( ptype, param1, param2 );\ }\ #define mitkPixelTypeMultiplex3( function, ptype, param1, param2, param3 ) \ { \ if ( ptype.GetComponentType() == itk::ImageIOBase::CHAR )\ function( ptype, param1, param2, param3 );\ else if ( ptype.GetComponentType() == itk::ImageIOBase::UCHAR)\ function( ptype, param1, param2, param3 );\ else if ( ptype.GetComponentType() == itk::ImageIOBase::SHORT )\ function( ptype, param1, param2, param3 ); \ else if ( ptype.GetComponentType() == itk::ImageIOBase::USHORT )\ function( ptype, param1, param2, param3 );\ else if ( ptype.GetComponentType() == itk::ImageIOBase::INT )\ function( ptype, param1, param2, param3 );\ else if ( ptype.GetComponentType() == itk::ImageIOBase::UINT )\ function( ptype, param1, param2, param3 );\ else if ( ptype.GetComponentType() == itk::ImageIOBase::LONG )\ function( ptype, param1, param2, param3 );\ else if ( ptype.GetComponentType() == itk::ImageIOBase::ULONG )\ function( ptype, param1, param2, param3 );\ else if ( ptype.GetComponentType() == itk::ImageIOBase::FLOAT )\ function( ptype, param1, param2, param3 );\ else if ( ptype.GetComponentType() == itk::ImageIOBase::DOUBLE )\ function( ptype, param1, param2, param3 );\ }\ #define mitkPixelTypeMultiplex4( function, ptype, param1, param2, param3, param4 ) \ { \ if ( ptype.GetComponentType() == itk::ImageIOBase::CHAR )\ function( ptype, param1, param2, param3, param4 );\ else if ( ptype.GetComponentType() == itk::ImageIOBase::UCHAR)\ function( ptype, param1, param2, param3, param4 );\ else if ( ptype.GetComponentType() == itk::ImageIOBase::SHORT )\ function( ptype, param1, param2, param3, param4 ); \ else if ( ptype.GetComponentType() == itk::ImageIOBase::USHORT )\ function( ptype, param1, param2, param3, param4 );\ else if ( ptype.GetComponentType() == itk::ImageIOBase::INT )\ function( ptype, param1, param2, param3, param4 );\ else if ( ptype.GetComponentType() == itk::ImageIOBase::UINT )\ function( ptype, param1, param2, param3, param4 );\ else if ( ptype.GetComponentType() == itk::ImageIOBase::LONG )\ function( ptype, param1, param2, param3, param4 );\ else if ( ptype.GetComponentType() == itk::ImageIOBase::ULONG )\ function( ptype, param1, param2, param3, param4 );\ else if ( ptype.GetComponentType() == itk::ImageIOBase::FLOAT )\ function( ptype, param1, param2, param3, param4 );\ else if ( ptype.GetComponentType() == itk::ImageIOBase::DOUBLE )\ function( ptype, param1, param2, param3, param4 );\ }\ #endif // MITKPIXELTYPEMULTIPLEX_H diff --git a/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkBatchedRegistration.cpp b/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkBatchedRegistration.cpp new file mode 100644 index 0000000000..da32c6ca8d --- /dev/null +++ b/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkBatchedRegistration.cpp @@ -0,0 +1,74 @@ +#include "mitkBatchedRegistration.h" +#include "mitkPyramidImageRegistrationMethod.h" +#include "mitkDiffusionImage.h" + +mitk::BatchedRegistration::BatchedRegistration() : + m_RegisteredImagesValid(false) +{ +} + +void mitk::BatchedRegistration::SetFixedImage(mitk::Image::Pointer& fixedImage) +{ + m_FixedImage = fixedImage; +} + +void mitk::BatchedRegistration::SetMovingReferenceImage(Image::Pointer &movingImage) +{ + m_MovingReference = movingImage; + m_RegisteredImagesValid = false; +} + +void mitk::BatchedRegistration::SetBatch(std::vector imageBatch) +{ + m_ImageBatch.clear(); + m_ImageBatch = imageBatch; +} + +std::vector mitk::BatchedRegistration::GetRegisteredImages() +{ + if (!m_RegisteredImagesValid) + { + m_RegisteredImages.clear(); + // First transform moving reference image + TransformType transf = GetTransformation(m_FixedImage, m_MovingReference); + // store it as first element in vector + m_RegisteredImages.push_back(ApplyTransformationToImage(m_MovingReference,transf)); + // apply transformation to whole batch + std::vector::const_iterator itEnd = m_ImageBatch.end(); + for (std::vector::iterator it = m_ImageBatch.begin(); it != itEnd; ++it) + { + m_RegisteredImages.push_back(ApplyTransformationToImage(*it,transf)); + } + } + return m_RegisteredImages; +} + +mitk::Image::Pointer mitk::BatchedRegistration::ApplyTransformationToImage(mitk::Image::Pointer &img, const mitk::BatchedRegistration::TransformType &transformation) const +{ + // TODO: perform some magic! + + if (dynamic_cast*> (img.GetPointer()) != NULL) // gaaaaahh template mist! + { + // apply transformation to image geometry as well as to all gradients !? + } + else + { + // do regular stuff + } + + return NULL; +} + +mitk::BatchedRegistration::TransformType mitk::BatchedRegistration::GetTransformation(mitk::Image::Pointer fixedImage, mitk::Image::Pointer movingImage) +{ + mitk::PyramidImageRegistrationMethod::Pointer registrationMethod = mitk::PyramidImageRegistrationMethod::New(); + registrationMethod->SetFixedImage( fixedImage ); + registrationMethod->SetTransformToRigid(); + registrationMethod->SetCrossModalityOn(); + registrationMethod->SetMovingImage(movingImage); + registrationMethod->Update(); + // TODO fancy shit, where you query and create a transformation type object thingy + TransformType transformation; + + return transformation; +} diff --git a/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkBatchedRegistration.h b/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkBatchedRegistration.h new file mode 100644 index 0000000000..093742c8e8 --- /dev/null +++ b/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkBatchedRegistration.h @@ -0,0 +1,74 @@ +#ifndef MITKBATCHEDREGISTRATION_H +#define MITKBATCHEDREGISTRATION_H + +// ITK +#include +// MITK +#include +#include "mitkCommon.h" +#include "mitkImage.h" + + +namespace mitk +{ +/** + * @brief The BatchedRegistration class Wrapper to calculate and apply a reference transformation to several images. + * + * Use if several pictures with the same world geometry are to be registered + * to one reference image, the registration is only computed once (for the moving image) and the geometry transformed for the complete + * image batch accordingly. Can handle image types that are usually not supported by registrations filters, e.g. fiber bundles and segmentations: + * these can be registered if a "registerable" image such as B0/T2 from which they are derived is supplied, since the transformation can be calculated + * on those and applied to the derived objects. + */ +class DiffusionCore_EXPORT BatchedRegistration : public itk::LightObject +{ +public: + + typedef vnl_matrix TransformType; + + BatchedRegistration(); + + void SetFixedImage(Image::Pointer &fixedImage); + void SetMovingReferenceImage(mitk::Image::Pointer& movingImage); + + void SetBatch(std::vector imageBatch); + + /** + * @brief GetRegisteredImages returns registered images , + * + * at position 0 the registered moving reference image is supplied followed all registered images from the batch. + */ + std::vector GetRegisteredImages(); + + mitk::Image::Pointer ApplyTransformationToImage(mitk::Image::Pointer& img, const TransformType& transformation) const; + + TransformType GetTransformation(mitk::Image::Pointer fixedImage, mitk::Image::Pointer movingImage); + +protected: + +private: + BatchedRegistration(const Self &); //purposely not implemented + void operator=(const Self &); //purposely not implemented + + bool m_RegisteredImagesValid; + + + mitk::Image::Pointer m_FixedImage; + mitk::Image::Pointer m_MovingReference; + + /** + * @brief m_ImageBatch List of images on which that the reference transformation is applied + * + */ + std::vector m_ImageBatch; + + /** + * @brief m_RegisteredImages List of references to registered images. + * + */ + std::vector m_RegisteredImages; + +}; + +} +#endif // MITKBATCHEDREGISTRATION_H diff --git a/Modules/DiffusionImaging/DiffusionCore/IODataStructures/DiffusionWeightedImages/mitkNrrdDiffusionImageReader.cpp b/Modules/DiffusionImaging/DiffusionCore/IODataStructures/DiffusionWeightedImages/mitkNrrdDiffusionImageReader.cpp index 0e5753d1e6..507f3c183a 100644 --- a/Modules/DiffusionImaging/DiffusionCore/IODataStructures/DiffusionWeightedImages/mitkNrrdDiffusionImageReader.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/IODataStructures/DiffusionWeightedImages/mitkNrrdDiffusionImageReader.cpp @@ -1,533 +1,533 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef __mitkNrrdDiffusionImageReader_cpp #define __mitkNrrdDiffusionImageReader_cpp #include "mitkNrrdDiffusionImageReader.h" #include "itkImageFileReader.h" #include "itkMetaDataObject.h" #include "itkNrrdImageIO.h" #include "itkNiftiImageIO.h" #include #include #include "itksys/SystemTools.hxx" namespace mitk { template void NrrdDiffusionImageReader ::GenerateData() { // Since everything is completely read in GenerateOutputInformation() it is stored // in a cache variable. A timestamp is associated. // If the timestamp of the cache variable is newer than the MTime, we only need to // assign the cache variable to the DataObject. // Otherwise, the tree must be read again from the file and OuputInformation must // be updated! if ( ( ! m_OutputCache ) || ( this->GetMTime( ) > m_CacheTime.GetMTime( ) ) ) { this->GenerateOutputInformation(); itkWarningMacro("Cache regenerated!"); } if (!m_OutputCache) { itkWarningMacro("cache is empty!"); } static_cast(this->GetOutput()) ->SetVectorImage(m_OutputCache->GetVectorImage()); static_cast(this->GetOutput()) ->SetB_Value(m_OutputCache->GetB_Value()); static_cast(this->GetOutput()) ->SetDirections(m_OutputCache->GetDirections()); static_cast(this->GetOutput()) ->SetMeasurementFrame(m_OutputCache->GetMeasurementFrame()); static_cast(this->GetOutput()) ->InitializeFromVectorImage(); } template void NrrdDiffusionImageReader::GenerateOutputInformation() { typename OutputType::Pointer outputForCache = OutputType::New(); if ( m_FileName == "") { throw itk::ImageFileReaderException(__FILE__, __LINE__, "Sorry, the filename to be read is empty!"); } else { try { const std::string& locale = "C"; const std::string& currLocale = setlocale( LC_ALL, NULL ); if ( locale.compare(currLocale)!=0 ) { try { setlocale(LC_ALL, locale.c_str()); } catch(...) { MITK_INFO << "Could not set locale " << locale; } } MITK_INFO << "NrrdDiffusionImageReader: reading image information"; typename ImageType::Pointer img; std::string ext = itksys::SystemTools::GetFilenameLastExtension(m_FileName); ext = itksys::SystemTools::LowerCase(ext); if (ext == ".hdwi" || ext == ".dwi") { typedef itk::ImageFileReader FileReaderType; typename FileReaderType::Pointer reader = FileReaderType::New(); reader->SetFileName(this->m_FileName); itk::NrrdImageIO::Pointer io = itk::NrrdImageIO::New(); reader->SetImageIO(io); reader->Update(); img = reader->GetOutput(); int vecsize = img->GetVectorLength(); std::cout << vecsize << std::endl; } else if(ext == ".fsl" || ext == ".fslgz") { // create temporary file with correct ending for nifti-io - std::string fname3 = m_FileName; + std::string fname3 = "temp_dwi"; fname3 += ext == ".fsl" ? ".nii" : ".nii.gz"; itksys::SystemTools::CopyAFile(m_FileName.c_str(), fname3.c_str()); // create reader and read file typedef itk::Image ImageType4D; itk::NiftiImageIO::Pointer io2 = itk::NiftiImageIO::New(); typedef itk::ImageFileReader FileReaderType; typename FileReaderType::Pointer reader = FileReaderType::New(); reader->SetFileName(fname3); reader->SetImageIO(io2); reader->Update(); typename ImageType4D::Pointer img4 = reader->GetOutput(); // delete temporary file itksys::SystemTools::RemoveFile(fname3.c_str()); // convert 4D file to vector image img = ImageType::New(); typename ImageType::SpacingType spacing; typename ImageType4D::SpacingType spacing4 = img4->GetSpacing(); for(int i=0; i<3; i++) spacing[i] = spacing4[i]; img->SetSpacing( spacing ); // Set the image spacing typename ImageType::PointType origin; typename ImageType4D::PointType origin4 = img4->GetOrigin(); for(int i=0; i<3; i++) origin[i] = origin4[i]; img->SetOrigin( origin ); // Set the image origin typename ImageType::DirectionType direction; typename ImageType4D::DirectionType direction4 = img4->GetDirection(); for(int i=0; i<3; i++) for(int j=0; j<3; j++) direction[i][j] = direction4[i][j]; img->SetDirection( direction ); // Set the image direction typename ImageType::RegionType region; typename ImageType4D::RegionType region4 = img4->GetLargestPossibleRegion(); typename ImageType::RegionType::SizeType size; typename ImageType4D::RegionType::SizeType size4 = region4.GetSize(); for(int i=0; i<3; i++) size[i] = size4[i]; typename ImageType::RegionType::IndexType index; typename ImageType4D::RegionType::IndexType index4 = region4.GetIndex(); for(int i=0; i<3; i++) index[i] = index4[i]; region.SetSize(size); region.SetIndex(index); img->SetRegions( region ); img->SetVectorLength(size4[3]); img->Allocate(); itk::ImageRegionIterator it (img, img->GetLargestPossibleRegion() ); typedef typename ImageType::PixelType VecPixType; for (it = it.Begin(); !it.IsAtEnd(); ++it) { VecPixType vec = it.Get(); typename ImageType::IndexType currentIndex = it.GetIndex(); for(int i=0; i<3; i++) index4[i] = currentIndex[i]; for(unsigned int ind=0; indGetPixel(index4); } it.Set(vec); } } m_DiffusionVectors = GradientDirectionContainerType::New(); m_OriginalDiffusionVectors = GradientDirectionContainerType::New(); if (ext == ".hdwi" || ext == ".dwi") { itk::MetaDataDictionary imgMetaDictionary = img->GetMetaDataDictionary(); std::vector imgMetaKeys = imgMetaDictionary.GetKeys(); std::vector::const_iterator itKey = imgMetaKeys.begin(); std::string metaString; GradientDirectionType vect3d; int numberOfImages = 0; int numberOfGradientImages = 0; bool readb0 = false; bool readFrame = false; double xx, xy, xz, yx, yy, yz, zx, zy, zz; for (; itKey != imgMetaKeys.end(); itKey ++) { double x,y,z; itk::ExposeMetaData (imgMetaDictionary, *itKey, metaString); if (itKey->find("DWMRI_gradient") != std::string::npos) { sscanf(metaString.c_str(), "%lf %lf %lf\n", &x, &y, &z); vect3d[0] = x; vect3d[1] = y; vect3d[2] = z; m_DiffusionVectors->InsertElement( numberOfImages, vect3d ); ++numberOfImages; // If the direction is 0.0, this is a reference image if (vect3d[0] == 0.0 && vect3d[1] == 0.0 && vect3d[2] == 0.0) { continue; } ++numberOfGradientImages;; } else if (itKey->find("DWMRI_b-value") != std::string::npos) { readb0 = true; m_B_Value = atof(metaString.c_str()); } else if (itKey->find("measurement frame") != std::string::npos) { sscanf(metaString.c_str(), " ( %lf , %lf , %lf ) ( %lf , %lf , %lf ) ( %lf , %lf , %lf ) \n", &xx, &xy, &xz, &yx, &yy, &yz, &zx, &zy, &zz); readFrame = true; if (xx>10e-10 || xy>10e-10 || xz>10e-10 || yx>10e-10 || yy>10e-10 || yz>10e-10 || zx>10e-10 || zy>10e-10 || zz>10e-10 ) { m_MeasurementFrame(0,0) = xx; m_MeasurementFrame(0,1) = xy; m_MeasurementFrame(0,2) = xz; m_MeasurementFrame(1,0) = yx; m_MeasurementFrame(1,1) = yy; m_MeasurementFrame(1,2) = yz; m_MeasurementFrame(2,0) = zx; m_MeasurementFrame(2,1) = zy; m_MeasurementFrame(2,2) = zz; } else { m_MeasurementFrame(0,0) = 1; m_MeasurementFrame(0,1) = 0; m_MeasurementFrame(0,2) = 0; m_MeasurementFrame(1,0) = 0; m_MeasurementFrame(1,1) = 1; m_MeasurementFrame(1,2) = 0; m_MeasurementFrame(2,0) = 0; m_MeasurementFrame(2,1) = 0; m_MeasurementFrame(2,2) = 1; } } } if(!readb0) { MITK_INFO << "BValue not specified in header file"; } } else if(ext == ".fsl" || ext == ".fslgz") { std::string line; std::vector bvec_entries; std::string fname = m_FileName; fname += ".bvecs"; std::ifstream myfile (fname.c_str()); if (myfile.is_open()) { while ( myfile.good() ) { getline (myfile,line); char* pch = strtok (const_cast(line.c_str())," "); while (pch != NULL) { bvec_entries.push_back(atof(pch)); pch = strtok (NULL, " "); } } myfile.close(); } else { MITK_INFO << "Unable to open bvecs file"; } std::vector bval_entries; std::string fname2 = m_FileName; fname2 += ".bvals"; std::ifstream myfile2 (fname2.c_str()); if (myfile2.is_open()) { while ( myfile2.good() ) { getline (myfile2,line); char* pch = strtok (const_cast(line.c_str())," "); while (pch != NULL) { bval_entries.push_back(atof(pch)); pch = strtok (NULL, " "); } } myfile2.close(); } else { MITK_INFO << "Unable to open bvals file"; } m_B_Value = -1; unsigned int numb = bval_entries.size(); for(unsigned int i=0; i vec; vec[0] = bvec_entries.at(i); vec[1] = bvec_entries.at(i+numb); vec[2] = bvec_entries.at(i+2*numb); // Adjust the vector length to encode gradient strength float factor = b_val/m_B_Value; if(vec.magnitude() > 0) { vec[0] = sqrt(factor)*vec[0]; vec[1] = sqrt(factor)*vec[1]; vec[2] = sqrt(factor)*vec[2]; } m_DiffusionVectors->InsertElement(i,vec); } for(int i=0; i<3; i++) for(int j=0; j<3; j++) m_MeasurementFrame[i][j] = i==j ? 1 : 0; } outputForCache->SetVectorImage(img); outputForCache->SetB_Value(m_B_Value); outputForCache->SetDirections(m_DiffusionVectors); outputForCache->SetMeasurementFrame(m_MeasurementFrame); // Since we have already read the tree, we can store it in a cache variable // so that it can be assigned to the DataObject in GenerateData(); m_OutputCache = outputForCache; m_CacheTime.Modified(); try { setlocale(LC_ALL, currLocale.c_str()); } catch(...) { MITK_INFO << "Could not reset locale " << currLocale; } } catch(std::exception& e) { MITK_INFO << "Std::Exception while reading file!!"; MITK_INFO << e.what(); throw itk::ImageFileReaderException(__FILE__, __LINE__, e.what()); } catch(...) { MITK_INFO << "Exception while reading file!!"; throw itk::ImageFileReaderException(__FILE__, __LINE__, "Sorry, an error occurred while reading the requested vessel tree file!"); } } } template const char* NrrdDiffusionImageReader ::GetFileName() const { return m_FileName.c_str(); } template void NrrdDiffusionImageReader ::SetFileName(const char* aFileName) { m_FileName = aFileName; } template const char* NrrdDiffusionImageReader ::GetFilePrefix() const { return m_FilePrefix.c_str(); } template void NrrdDiffusionImageReader ::SetFilePrefix(const char* aFilePrefix) { m_FilePrefix = aFilePrefix; } template const char* NrrdDiffusionImageReader ::GetFilePattern() const { return m_FilePattern.c_str(); } template void NrrdDiffusionImageReader ::SetFilePattern(const char* aFilePattern) { m_FilePattern = aFilePattern; } template bool NrrdDiffusionImageReader ::CanReadFile(const std::string filename, const std::string /*filePrefix*/, const std::string /*filePattern*/) { // First check the extension if( filename == "" ) { return false; } std::string ext = itksys::SystemTools::GetFilenameLastExtension(filename); ext = itksys::SystemTools::LowerCase(ext); if (ext == ".hdwi" || ext == ".dwi") { itk::NrrdImageIO::Pointer io = itk::NrrdImageIO::New(); typedef itk::ImageFileReader FileReaderType; typename FileReaderType::Pointer reader = FileReaderType::New(); reader->SetImageIO(io); reader->SetFileName(filename); try { reader->Update(); } catch(itk::ExceptionObject e) { MITK_INFO << e.GetDescription(); } typename ImageType::Pointer img = reader->GetOutput(); itk::MetaDataDictionary imgMetaDictionary = img->GetMetaDataDictionary(); std::vector imgMetaKeys = imgMetaDictionary.GetKeys(); std::vector::const_iterator itKey = imgMetaKeys.begin(); std::string metaString; for (; itKey != imgMetaKeys.end(); itKey ++) { itk::ExposeMetaData (imgMetaDictionary, *itKey, metaString); if (itKey->find("modality") != std::string::npos) { if (metaString.find("DWMRI") != std::string::npos) { return true; } } } } if (ext == ".fsl" || ext == ".fslgz") { // itk::NiftiImageIO::Pointer io2 = itk::NiftiImageIO::New(); // typedef itk::ImageFileReader FileReaderType; // typename FileReaderType::Pointer reader = FileReaderType::New(); // reader->SetImageIO(io2); // reader->SetFileName(filename); // try // { // reader->Update(); // } // catch(itk::ExceptionObject e) // { // MITK_INFO << e.GetDescription(); // } std::string fname = filename; fname += ".bvecs"; std::string fname2 = filename; fname2 += ".bvals"; if( itksys::SystemTools::FileExists(fname.c_str()) && itksys::SystemTools::FileExists(fname2.c_str()) ) { return true; } else { MITK_INFO << ".bvals and .bvals files do not exist properly"; } } return false; } } //namespace MITK #endif diff --git a/Modules/DiffusionImaging/DiffusionCore/IODataStructures/TensorImages/mitkNrrdTensorImageReader.cpp b/Modules/DiffusionImaging/DiffusionCore/IODataStructures/TensorImages/mitkNrrdTensorImageReader.cpp index 6a7a366e84..7ab9f2ec1b 100644 --- a/Modules/DiffusionImaging/DiffusionCore/IODataStructures/TensorImages/mitkNrrdTensorImageReader.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/IODataStructures/TensorImages/mitkNrrdTensorImageReader.cpp @@ -1,326 +1,459 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkNrrdTensorImageReader.h" #include "itkImageFileReader.h" #include "itkImageRegionIterator.h" #include "itkMetaDataObject.h" #include "itkNrrdImageIO.h" - +#include #include "mitkITKImageImport.h" #include "mitkImageDataItem.h" namespace mitk { void NrrdTensorImageReader ::GenerateData() { if ( m_FileName == "") { throw itk::ImageFileReaderException(__FILE__, __LINE__, "Sorry, the filename is empty!"); } else { try { const std::string& locale = "C"; const std::string& currLocale = setlocale( LC_ALL, NULL ); if ( locale.compare(currLocale)!=0 ) { try { setlocale(LC_ALL, locale.c_str()); } catch(...) { MITK_INFO << "Could not set locale " << locale; } } - MITK_INFO << "Loading tensor image ..."; - - typedef itk::VectorImage ImageType; - itk::NrrdImageIO::Pointer io = itk::NrrdImageIO::New(); - typedef itk::ImageFileReader FileReaderType; - FileReaderType::Pointer reader = FileReaderType::New(); - reader->SetImageIO(io); - reader->SetFileName(this->m_FileName); - reader->Update(); - ImageType::Pointer img = reader->GetOutput(); - - typedef itk::Image,3> VecImgType; - VecImgType::Pointer vecImg = VecImgType::New(); - vecImg->SetSpacing( img->GetSpacing() ); // Set the image spacing - vecImg->SetOrigin( img->GetOrigin() ); // Set the image origin - vecImg->SetDirection( img->GetDirection() ); // Set the image direction - vecImg->SetRegions( img->GetLargestPossibleRegion()); - vecImg->Allocate(); - - itk::ImageRegionIterator ot (vecImg, vecImg->GetLargestPossibleRegion() ); - ot = ot.Begin(); - - itk::ImageRegionIterator it (img, img->GetLargestPossibleRegion() ); - it = it.Begin(); - - typedef ImageType::PixelType VarPixType; - typedef VecImgType::PixelType FixPixType; - int numComponents = img->GetNumberOfComponentsPerPixel(); - - itk::MetaDataDictionary imgMetaDictionary = img->GetMetaDataDictionary(); - std::vector imgMetaKeys = imgMetaDictionary.GetKeys(); - std::vector::const_iterator itKey = imgMetaKeys.begin(); - std::string metaString; - - bool readFrame = false; - double xx, xy, xz, yx, yy, yz, zx, zy, zz; - MeasurementFrameType measFrame; - measFrame.SetIdentity(); - MeasurementFrameType measFrameTransp; - measFrameTransp.SetIdentity(); - - for (; itKey != imgMetaKeys.end(); itKey ++) + try { - itk::ExposeMetaData (imgMetaDictionary, *itKey, metaString); - if (itKey->find("measurement frame") != std::string::npos) - { - sscanf(metaString.c_str(), " ( %lf , %lf , %lf ) ( %lf , %lf , %lf ) ( %lf , %lf , %lf ) \n", &xx, &xy, &xz, &yx, &yy, &yz, &zx, &zy, &zz); + MITK_INFO << "Trying to load dti as nifti ..."; + std::string fname3 = "temp_dti.nii"; + itksys::SystemTools::CopyAFile(m_FileName.c_str(), fname3.c_str()); - if (xx>10e-10 || xy>10e-10 || xz>10e-10 || - yx>10e-10 || yy>10e-10 || yz>10e-10 || - zx>10e-10 || zy>10e-10 || zz>10e-10 ) - { - readFrame = true; - - measFrame(0,0) = xx; - measFrame(0,1) = xy; - measFrame(0,2) = xz; - measFrame(1,0) = yx; - measFrame(1,1) = yy; - measFrame(1,2) = yz; - measFrame(2,0) = zx; - measFrame(2,1) = zy; - measFrame(2,2) = zz; - - measFrameTransp = measFrame.GetTranspose(); - } - } - } - - if (numComponents==6) - { - while (!it.IsAtEnd()) - { - // T'=RTR' - VarPixType vec = it.Get(); - FixPixType fixVec(vec.GetDataPointer()); + typedef itk::Image ImageType; + itk::NiftiImageIO::Pointer io = itk::NiftiImageIO::New(); + typedef itk::ImageFileReader FileReaderType; + FileReaderType::Pointer reader = FileReaderType::New(); + reader->SetImageIO(io); + reader->SetFileName(fname3); + reader->Update(); + itksys::SystemTools::RemoveFile(fname3.c_str()); - if(readFrame) - { - itk::DiffusionTensor3D tensor; - tensor.SetElement(0, vec.GetElement(0)); - tensor.SetElement(1, vec.GetElement(1)); - tensor.SetElement(2, vec.GetElement(2)); - tensor.SetElement(3, vec.GetElement(3)); - tensor.SetElement(4, vec.GetElement(4)); - tensor.SetElement(5, vec.GetElement(5)); + ImageType::Pointer img = reader->GetOutput(); + itk::Size<4> size = img->GetLargestPossibleRegion().GetSize(); - tensor = ConvertMatrixTypeToFixedArrayType(tensor.PreMultiply(measFrame)); - tensor = ConvertMatrixTypeToFixedArrayType(tensor.PostMultiply(measFrameTransp)); - fixVec = tensor; - } + itk::ImageRegion< 3 > region; + region.SetSize(0,size[0]); + region.SetSize(1,size[1]); + region.SetSize(2,size[2]); + itk::Vector spacing; + spacing[0] = img->GetSpacing()[0]; + spacing[1] = img->GetSpacing()[1]; + spacing[2] = img->GetSpacing()[2]; + itk::Point origin; + origin[0] = img->GetOrigin()[0]; + origin[1] = img->GetOrigin()[1]; + origin[2] = img->GetOrigin()[2]; + itk::Matrix direction; + direction[0][0] = img->GetDirection()[0][0]; + direction[1][0] = img->GetDirection()[1][0]; + direction[2][0] = img->GetDirection()[2][0]; + direction[0][1] = img->GetDirection()[0][1]; + direction[1][1] = img->GetDirection()[1][1]; + direction[2][1] = img->GetDirection()[2][1]; + direction[0][2] = img->GetDirection()[0][2]; + direction[1][2] = img->GetDirection()[1][2]; + direction[2][2] = img->GetDirection()[2][2]; + + typedef itk::Image,3> VecImgType; + typedef VecImgType::PixelType FixPixType; + VecImgType::Pointer vecImg = VecImgType::New(); + vecImg->SetSpacing( spacing ); + vecImg->SetOrigin( origin ); + vecImg->SetDirection( direction ); + vecImg->SetRegions( region ); + vecImg->Allocate(); + + itk::ImageRegionIterator ot (vecImg, vecImg->GetLargestPossibleRegion() ); + ot = ot.Begin(); - ot.Set(fixVec); - ++ot; - ++it; - } - } - else if(numComponents==9) - { - while (!it.IsAtEnd()) + while (!ot.IsAtEnd()) { - VarPixType vec = it.Get(); itk::DiffusionTensor3D tensor; - tensor.SetElement(0, vec.GetElement(0)); - tensor.SetElement(1, vec.GetElement(1)); - tensor.SetElement(2, vec.GetElement(2)); - tensor.SetElement(3, vec.GetElement(4)); - tensor.SetElement(4, vec.GetElement(5)); - tensor.SetElement(5, vec.GetElement(8)); - - if(readFrame) + ImageType::IndexType idx; + idx[0] = ot.GetIndex()[0]; idx[1] = ot.GetIndex()[1]; idx[2] = ot.GetIndex()[2]; + + if (size[3]==6) + { + for (int te=0; teGetPixel(idx)); + } + } + else if (size[3]==9) { - tensor = ConvertMatrixTypeToFixedArrayType(tensor.PreMultiply(measFrame)); - tensor = ConvertMatrixTypeToFixedArrayType(tensor.PostMultiply(measFrameTransp)); + idx[3] = 0; + tensor.SetElement(0, img->GetPixel(idx)); + idx[3] = 1; + tensor.SetElement(1, img->GetPixel(idx)); + idx[3] = 2; + tensor.SetElement(2, img->GetPixel(idx)); + idx[3] = 4; + tensor.SetElement(3, img->GetPixel(idx)); + idx[3] = 5; + tensor.SetElement(4, img->GetPixel(idx)); + idx[3] = 8; + tensor.SetElement(5, img->GetPixel(idx)); } + else + throw itk::ImageFileReaderException(__FILE__, __LINE__, "Unknown number of komponents for DTI file. Should be 6 or 9!"); FixPixType fixVec(tensor); ot.Set(fixVec); ++ot; - ++it; } + this->GetOutput()->InitializeByItk(vecImg.GetPointer()); + this->GetOutput()->SetVolume(vecImg->GetBufferPointer()); } - else if (numComponents==1) + catch(...) { - typedef itk::Image ImageType; + MITK_INFO << "Trying to load dti as nrrd ..."; + + typedef itk::VectorImage ImageType; itk::NrrdImageIO::Pointer io = itk::NrrdImageIO::New(); typedef itk::ImageFileReader FileReaderType; FileReaderType::Pointer reader = FileReaderType::New(); reader->SetImageIO(io); reader->SetFileName(this->m_FileName); reader->Update(); ImageType::Pointer img = reader->GetOutput(); - itk::Size<4> size = img->GetLargestPossibleRegion().GetSize(); + typedef itk::Image,3> VecImgType; + VecImgType::Pointer vecImg = VecImgType::New(); + vecImg->SetSpacing( img->GetSpacing() ); // Set the image spacing + vecImg->SetOrigin( img->GetOrigin() ); // Set the image origin + vecImg->SetDirection( img->GetDirection() ); // Set the image direction + vecImg->SetRegions( img->GetLargestPossibleRegion()); + vecImg->Allocate(); + + itk::ImageRegionIterator ot (vecImg, vecImg->GetLargestPossibleRegion() ); + ot = ot.Begin(); + + itk::ImageRegionIterator it (img, img->GetLargestPossibleRegion() ); + it = it.Begin(); + + typedef ImageType::PixelType VarPixType; + typedef VecImgType::PixelType FixPixType; + int numComponents = img->GetNumberOfComponentsPerPixel(); + + itk::MetaDataDictionary imgMetaDictionary = img->GetMetaDataDictionary(); + std::vector imgMetaKeys = imgMetaDictionary.GetKeys(); + std::vector::const_iterator itKey = imgMetaKeys.begin(); + std::string metaString; + + bool readFrame = false; + double xx, xy, xz, yx, yy, yz, zx, zy, zz; + MeasurementFrameType measFrame; + measFrame.SetIdentity(); + MeasurementFrameType measFrameTransp; + measFrameTransp.SetIdentity(); + + for (; itKey != imgMetaKeys.end(); itKey ++) + { + itk::ExposeMetaData (imgMetaDictionary, *itKey, metaString); + if (itKey->find("measurement frame") != std::string::npos) + { + sscanf(metaString.c_str(), " ( %lf , %lf , %lf ) ( %lf , %lf , %lf ) ( %lf , %lf , %lf ) \n", &xx, &xy, &xz, &yx, &yy, &yz, &zx, &zy, &zz); + + if (xx>10e-10 || xy>10e-10 || xz>10e-10 || + yx>10e-10 || yy>10e-10 || yz>10e-10 || + zx>10e-10 || zy>10e-10 || zz>10e-10 ) + { + readFrame = true; + + measFrame(0,0) = xx; + measFrame(0,1) = xy; + measFrame(0,2) = xz; + measFrame(1,0) = yx; + measFrame(1,1) = yy; + measFrame(1,2) = yz; + measFrame(2,0) = zx; + measFrame(2,1) = zy; + measFrame(2,2) = zz; + + measFrameTransp = measFrame.GetTranspose(); + } + } + } - while (!ot.IsAtEnd()) + if (numComponents==6) { - itk::DiffusionTensor3D tensor; - ImageType::IndexType idx; - idx[0] = ot.GetIndex()[0]; idx[1] = ot.GetIndex()[1]; idx[2] = ot.GetIndex()[2]; - for (int te=0; teGetPixel(idx)); + // T'=RTR' + VarPixType vec = it.Get(); + FixPixType fixVec(vec.GetDataPointer()); + + if(readFrame) + { + itk::DiffusionTensor3D tensor; + tensor.SetElement(0, vec.GetElement(0)); + tensor.SetElement(1, vec.GetElement(1)); + tensor.SetElement(2, vec.GetElement(2)); + tensor.SetElement(3, vec.GetElement(3)); + tensor.SetElement(4, vec.GetElement(4)); + tensor.SetElement(5, vec.GetElement(5)); + + tensor = ConvertMatrixTypeToFixedArrayType(tensor.PreMultiply(measFrame)); + tensor = ConvertMatrixTypeToFixedArrayType(tensor.PostMultiply(measFrameTransp)); + fixVec = tensor; + } + + ot.Set(fixVec); + ++ot; + ++it; } - if(readFrame) + } + else if(numComponents==9) + { + while (!it.IsAtEnd()) { - tensor = ConvertMatrixTypeToFixedArrayType(tensor.PreMultiply(measFrame)); - tensor = ConvertMatrixTypeToFixedArrayType(tensor.PostMultiply(measFrameTransp)); + VarPixType vec = it.Get(); + itk::DiffusionTensor3D tensor; + tensor.SetElement(0, vec.GetElement(0)); + tensor.SetElement(1, vec.GetElement(1)); + tensor.SetElement(2, vec.GetElement(2)); + tensor.SetElement(3, vec.GetElement(4)); + tensor.SetElement(4, vec.GetElement(5)); + tensor.SetElement(5, vec.GetElement(8)); + + if(readFrame) + { + tensor = ConvertMatrixTypeToFixedArrayType(tensor.PreMultiply(measFrame)); + tensor = ConvertMatrixTypeToFixedArrayType(tensor.PostMultiply(measFrameTransp)); + } + + FixPixType fixVec(tensor); + ot.Set(fixVec); + ++ot; + ++it; } - FixPixType fixVec(tensor); - ot.Set(fixVec); - ++ot; } - } - else - { - throw itk::ImageFileReaderException(__FILE__, __LINE__, "Image has wrong number of pixel components!"); - } + else if (numComponents==1) + { + typedef itk::Image ImageType; + itk::NrrdImageIO::Pointer io = itk::NrrdImageIO::New(); + typedef itk::ImageFileReader FileReaderType; + FileReaderType::Pointer reader = FileReaderType::New(); + reader->SetImageIO(io); + reader->SetFileName(this->m_FileName); + reader->Update(); + ImageType::Pointer img = reader->GetOutput(); + + itk::Size<4> size = img->GetLargestPossibleRegion().GetSize(); - this->GetOutput()->InitializeByItk(vecImg.GetPointer()); - this->GetOutput()->SetVolume(vecImg->GetBufferPointer()); + MITK_INFO << size; + + while (!ot.IsAtEnd()) + { + itk::DiffusionTensor3D tensor; + ImageType::IndexType idx; + idx[0] = ot.GetIndex()[0]; idx[1] = ot.GetIndex()[1]; idx[2] = ot.GetIndex()[2]; + + if (size[3]==6) + { + for (int te=0; teGetPixel(idx)); + } + + // idx[3] = 0; + // tensor.SetElement(0, img->GetPixel(idx)); + // idx[3] = 1; + // tensor.SetElement(1, img->GetPixel(idx)); + // idx[3] = 3; + // tensor.SetElement(2, img->GetPixel(idx)); + // idx[3] = 2; + // tensor.SetElement(3, img->GetPixel(idx)); + // idx[3] = 4; + // tensor.SetElement(4, img->GetPixel(idx)); + // idx[3] = 5; + // tensor.SetElement(5, img->GetPixel(idx)); + } + else if (size[3]==9) + { + idx[3] = 0; + tensor.SetElement(0, img->GetPixel(idx)); + idx[3] = 1; + tensor.SetElement(1, img->GetPixel(idx)); + idx[3] = 2; + tensor.SetElement(2, img->GetPixel(idx)); + idx[3] = 4; + tensor.SetElement(3, img->GetPixel(idx)); + idx[3] = 5; + tensor.SetElement(4, img->GetPixel(idx)); + idx[3] = 8; + tensor.SetElement(5, img->GetPixel(idx)); + } + else + throw itk::ImageFileReaderException(__FILE__, __LINE__, "Unknown number of komponents for DTI file. Should be 6 or 9!"); + + if(readFrame) + { + tensor = ConvertMatrixTypeToFixedArrayType(tensor.PreMultiply(measFrame)); + tensor = ConvertMatrixTypeToFixedArrayType(tensor.PostMultiply(measFrameTransp)); + } + FixPixType fixVec(tensor); + ot.Set(fixVec); + ++ot; + } + } + else + { + throw itk::ImageFileReaderException(__FILE__, __LINE__, "Image has wrong number of pixel components!"); + } + + this->GetOutput()->InitializeByItk(vecImg.GetPointer()); + this->GetOutput()->SetVolume(vecImg->GetBufferPointer()); + + } try { setlocale(LC_ALL, currLocale.c_str()); } catch(...) { MITK_INFO << "Could not reset locale " << currLocale; } } catch(std::exception& e) { throw itk::ImageFileReaderException(__FILE__, __LINE__, e.what()); } catch(...) { throw itk::ImageFileReaderException(__FILE__, __LINE__, "Sorry, an error occurred while reading the requested DTI file!"); } } } void NrrdTensorImageReader::GenerateOutputInformation() { } const char* NrrdTensorImageReader ::GetFileName() const { return m_FileName.c_str(); } void NrrdTensorImageReader ::SetFileName(const char* aFileName) { m_FileName = aFileName; } const char* NrrdTensorImageReader ::GetFilePrefix() const { return m_FilePrefix.c_str(); } void NrrdTensorImageReader ::SetFilePrefix(const char* aFilePrefix) { m_FilePrefix = aFilePrefix; } const char* NrrdTensorImageReader ::GetFilePattern() const { return m_FilePattern.c_str(); } void NrrdTensorImageReader ::SetFilePattern(const char* aFilePattern) { m_FilePattern = aFilePattern; } bool NrrdTensorImageReader ::CanReadFile(const std::string filename, const std::string /*filePrefix*/, const std::string /*filePattern*/) { // First check the extension if( filename == "" ) { return false; } std::string ext = itksys::SystemTools::GetFilenameLastExtension(filename); ext = itksys::SystemTools::LowerCase(ext); if (ext == ".hdti" || ext == ".dti") { return true; } return false; } itk::DiffusionTensor3D NrrdTensorImageReader ::ConvertMatrixTypeToFixedArrayType(const itk::DiffusionTensor3D::Superclass::MatrixType & matrix) { /* | 0 1 2 | * | X 3 4 | * | X X 5 | */ itk::DiffusionTensor3D arr; arr.SetElement(0,matrix(0,0)); arr.SetElement(1,matrix(0,1)); arr.SetElement(2,matrix(0,2)); arr.SetElement(3,matrix(1,3)); arr.SetElement(4,matrix(1,4)); arr.SetElement(5,matrix(2,5)); return arr; } } //namespace MITK diff --git a/Modules/DiffusionImaging/DiffusionCore/MiniApps/QballReconstruction.cpp b/Modules/DiffusionImaging/DiffusionCore/MiniApps/QballReconstruction.cpp index 0fe0498d0b..45cadfb53b 100644 --- a/Modules/DiffusionImaging/DiffusionCore/MiniApps/QballReconstruction.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/MiniApps/QballReconstruction.cpp @@ -1,114 +1,111 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "MiniAppManager.h" #include #include #include #include #include #include #include #include #include #include #include "itkVectorContainer.h" #include "vnl/vnl_vector_fixed.h" #include "itkVectorImage.h" #include "mitkBaseDataIOFactory.h" #include "mitkDiffusionImage.h" #include "mitkBaseData.h" #include "mitkDiffusionCoreObjectFactory.h" #include "mitkCoreObjectFactory.h" #include "mitkCoreExtObjectFactory.h" #include "mitkImageWriter.h" #include "itkAnalyticalDiffusionQballReconstructionImageFilter.h" #include +#include using namespace mitk; /** * Convert files from one ending to the other */ int QballReconstruction(int argc, char* argv[]) { - if ( argc!=5 + if ( argc!=6 ) { std::cout << std::endl; std::cout << "Perform QBall reconstruction on an dwi file" << std::endl; std::cout << std::endl; - std::cout << "usage: " << argv[0] << " " << std::endl; + std::cout << "usage: " << argv[0] << " " << argv[1] << " " << std::endl; std::cout << std::endl; return EXIT_FAILURE; } try { RegisterDiffusionCoreObjectFactory(); MITK_INFO << "Loading image ..."; const std::string s1="", s2=""; - std::vector infile = BaseDataIO::LoadBaseDataFromFile( argv[1], s1, s2, false ); + std::vector infile = BaseDataIO::LoadBaseDataFromFile( argv[2], s1, s2, false ); DiffusionImage::Pointer dwi = dynamic_cast*>(infile.at(0).GetPointer()); typedef itk::AnalyticalDiffusionQballReconstructionImageFilter FilterType; dwi->AverageRedundantGradients(0.001); FilterType::Pointer filter = FilterType::New(); filter->SetGradientImage( dwi->GetDirections(), dwi->GetVectorImage() ); filter->SetBValue(dwi->GetB_Value()); - filter->SetThreshold( boost::lexical_cast(argv[3]) ); - filter->SetLambda(boost::lexical_cast(argv[2])); + filter->SetThreshold( boost::lexical_cast(argv[4]) ); + filter->SetLambda(boost::lexical_cast(argv[3])); filter->SetNormalizationMethod(FilterType::QBAR_SOLID_ANGLE); filter->Update(); mitk::QBallImage::Pointer image = mitk::QBallImage::New(); image->InitializeByItk( filter->GetOutput() ); image->SetVolume( filter->GetOutput()->GetBufferPointer() ); - std::string outfilename = argv[4]; + std::string outfilename = argv[5]; MITK_INFO << "writing image " << outfilename; - mitk::CoreObjectFactory::FileWriterList fileWriters = mitk::CoreObjectFactory::GetInstance()->GetFileWriters(); - for (mitk::CoreObjectFactory::FileWriterList::iterator it = fileWriters.begin() ; it != fileWriters.end() ; ++it) - { - if ( (*it)->CanWriteBaseDataType(image.GetPointer()) ) { - (*it)->SetFileName( outfilename.c_str() ); - (*it)->DoWrite( image.GetPointer() ); - } - } + mitk::NrrdQBallImageWriter::Pointer writer = mitk::NrrdQBallImageWriter::New(); + writer->SetInput(image.GetPointer()); + writer->SetFileName(outfilename.c_str()); + writer->Update(); } catch ( itk::ExceptionObject &err) { MITK_INFO << "Exception: " << err; } catch ( std::exception err) { MITK_INFO << "Exception: " << err.what(); } catch ( ... ) { MITK_INFO << "Exception!"; } return EXIT_SUCCESS; } RegisterDiffusionCoreMiniApp(QballReconstruction); diff --git a/Modules/DiffusionImaging/DiffusionCore/MiniApps/TensorReconstruction.cpp b/Modules/DiffusionImaging/DiffusionCore/MiniApps/TensorReconstruction.cpp index fad1f84050..1f9eea61a3 100644 --- a/Modules/DiffusionImaging/DiffusionCore/MiniApps/TensorReconstruction.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/MiniApps/TensorReconstruction.cpp @@ -1,168 +1,89 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "MiniAppManager.h" -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -#include - -#include "itkVectorContainer.h" -#include "vnl/vnl_vector_fixed.h" -#include "itkVectorImage.h" - #include "mitkBaseDataIOFactory.h" #include "mitkDiffusionImage.h" #include "mitkBaseData.h" #include "mitkDiffusionCoreObjectFactory.h" -#include "mitkCoreObjectFactory.h" -#include "mitkCoreExtObjectFactory.h" -#include "mitkImageWriter.h" - -#include "itkDiffusionTensor3DReconstructionImageFilter.h" -#include "mitkTensorImage.h" +#include +#include +#include +#include +using namespace mitk; /** * Convert files from one ending to the other */ int TensorReconstruction(int argc, char* argv[]) { - - if ( argc!=3 ) - { - std::cout << std::endl; - std::cout << "Perform Tensor estimation on an dwi file" << std::endl; - std::cout << std::endl; - std::cout << "usage: " << argv[0] << " " << std::endl; - std::cout << std::endl; - return EXIT_FAILURE; - } - - mitk::BaseData::Pointer baseData = 0; - - try - { - mitk::CoreObjectFactory::GetInstance(); - - RegisterDiffusionCoreObjectFactory(); - RegisterCoreExtObjectFactory() ; - - std::string filename = argv[1]; - const std::string s1="", s2=""; - std::vector infile = mitk::BaseDataIO::LoadBaseDataFromFile( filename, s1, s2, false ); - if( infile.empty() ) + if ( argc!=4 ) { - MITK_INFO << "File could not be read" ; + std::cout << std::endl; + std::cout << "Perform Tensor estimation on an dwi file" << std::endl; + std::cout << std::endl; + std::cout << "usage: " << argv[0] << " " << argv[1] << " " << std::endl; + std::cout << std::endl; + return EXIT_FAILURE; } - baseData = infile.at(0); - } - catch ( itk::ExceptionObject &err) - { - MITK_INFO << "Exception during read: " << err; - } - catch ( std::exception err) - { - MITK_INFO << "Exception during read: " << err.what(); - } - catch ( ... ) - { - MITK_INFO << "Exception during read!"; - } - - - - - - typedef short DiffusionPixelType; - typedef float TensorPixelType; - - typedef mitk::DiffusionImage DiffusionImageType; - - - std::string outfilename = argv[2]; - - DiffusionImageType::Pointer vols; - - try - { - vols = dynamic_cast(baseData.GetPointer()); - } - catch ( itk::ExceptionObject &err) - { - MITK_INFO << "Exception during Image write: " << err; - } - catch ( std::exception err) - { - MITK_INFO << "Exception during Image write: " << err.what(); - } - catch ( ... ) - { - MITK_INFO << "Exception during Image write"; - } - - if(vols.IsNull()) - { - return EXIT_FAILURE; - } - - - - typedef float TTensorPixelType; - - typedef itk::DiffusionTensor3DReconstructionImageFilter< - DiffusionPixelType, DiffusionPixelType, TTensorPixelType > TensorReconstructionImageFilterType; - TensorReconstructionImageFilterType::Pointer filter = - TensorReconstructionImageFilterType::New(); - filter->SetGradientImage( vols->GetDirections(), vols->GetVectorImage() ); - filter->SetBValue(vols->GetB_Value()); - filter->Update(); - - - mitk::TensorImage::Pointer image = mitk::TensorImage::New(); - image->InitializeByItk( filter->GetOutput() ); - image->SetVolume( filter->GetOutput()->GetBufferPointer() ); - - - // Save tensor image - std::cout << "writing tensor image"; - - std::string tensorName = outfilename + ".dti"; - mitk::CoreObjectFactory::FileWriterList fileWriters = mitk::CoreObjectFactory::GetInstance()->GetFileWriters(); - for (mitk::CoreObjectFactory::FileWriterList::iterator it = fileWriters.begin() ; it != fileWriters.end() ; ++it) - { - if ( (*it)->CanWriteBaseDataType(image.GetPointer()) ) { - MITK_INFO << "writing"; - (*it)->SetFileName( tensorName.c_str() ); - (*it)->DoWrite( image.GetPointer() ); + try + { + RegisterDiffusionCoreObjectFactory(); + + MITK_INFO << "Loading image ..."; + const std::string s1="", s2=""; + std::vector infile = BaseDataIO::LoadBaseDataFromFile( argv[2], s1, s2, false ); + DiffusionImage::Pointer dwi = dynamic_cast*>(infile.at(0).GetPointer()); + + std::string outfilename = argv[3]; + + typedef itk::DiffusionTensor3DReconstructionImageFilter< short, short, float > TensorReconstructionImageFilterType; + TensorReconstructionImageFilterType::Pointer filter = TensorReconstructionImageFilterType::New(); + filter->SetGradientImage( dwi->GetDirections(), dwi->GetVectorImage() ); + filter->SetBValue(dwi->GetB_Value()); + filter->Update(); + + // Save tensor image + MITK_INFO << "writing image " << outfilename; + itk::NrrdImageIO::Pointer io = itk::NrrdImageIO::New(); + io->SetFileType( itk::ImageIOBase::Binary ); + io->UseCompressionOn(); + + itk::ImageFileWriter< itk::Image< itk::DiffusionTensor3D< float >, 3 > >::Pointer writer = itk::ImageFileWriter< itk::Image< itk::DiffusionTensor3D< float >, 3 > >::New(); + writer->SetInput(filter->GetOutput()); + writer->SetFileName(outfilename); + writer->SetImageIO(io); + writer->UseCompressionOn(); + writer->Update(); } - } - - - return EXIT_SUCCESS; + catch ( itk::ExceptionObject &err) + { + MITK_INFO << "Exception: " << err; + } + catch ( std::exception err) + { + MITK_INFO << "Exception: " << err.what(); + } + catch ( ... ) + { + MITK_INFO << "Exception!"; + } + return EXIT_SUCCESS; } RegisterDiffusionCoreMiniApp(TensorReconstruction); diff --git a/Modules/DiffusionImaging/DiffusionCore/files.cmake b/Modules/DiffusionImaging/DiffusionCore/files.cmake index 063f891c42..c504e13ee0 100644 --- a/Modules/DiffusionImaging/DiffusionCore/files.cmake +++ b/Modules/DiffusionImaging/DiffusionCore/files.cmake @@ -1,135 +1,136 @@ set(CPP_FILES # DicomImport DicomImport/mitkDicomDiffusionImageReader.cpp # DicomImport/mitkGroupDiffusionHeadersFilter.cpp DicomImport/mitkDicomDiffusionImageHeaderReader.cpp DicomImport/mitkGEDicomDiffusionImageHeaderReader.cpp DicomImport/mitkPhilipsDicomDiffusionImageHeaderReader.cpp DicomImport/mitkSiemensDicomDiffusionImageHeaderReader.cpp DicomImport/mitkSiemensMosaicDicomDiffusionImageHeaderReader.cpp # DataStructures IODataStructures/mitkDiffusionCoreObjectFactory.cpp # DataStructures -> DWI IODataStructures/DiffusionWeightedImages/mitkDiffusionImageHeaderInformation.cpp IODataStructures/DiffusionWeightedImages/mitkDiffusionImageSource.cpp IODataStructures/DiffusionWeightedImages/mitkNrrdDiffusionImageReader.cpp IODataStructures/DiffusionWeightedImages/mitkNrrdDiffusionImageWriter.cpp IODataStructures/DiffusionWeightedImages/mitkNrrdDiffusionImageIOFactory.cpp IODataStructures/DiffusionWeightedImages/mitkNrrdDiffusionImageWriterFactory.cpp IODataStructures/DiffusionWeightedImages/mitkDiffusionImageSerializer.cpp IODataStructures/DiffusionWeightedImages/mitkImageToDiffusionImageSource.cpp IODataStructures/DiffusionWeightedImages/mitkDiffusionImageCorrectionFilter.cpp # DataStructures -> QBall IODataStructures/QBallImages/mitkQBallImageSource.cpp IODataStructures/QBallImages/mitkNrrdQBallImageReader.cpp IODataStructures/QBallImages/mitkNrrdQBallImageWriter.cpp IODataStructures/QBallImages/mitkNrrdQBallImageIOFactory.cpp IODataStructures/QBallImages/mitkNrrdQBallImageWriterFactory.cpp IODataStructures/QBallImages/mitkQBallImage.cpp IODataStructures/QBallImages/mitkQBallImageSerializer.cpp # DataStructures -> Tensor IODataStructures/TensorImages/mitkTensorImageSource.cpp IODataStructures/TensorImages/mitkNrrdTensorImageReader.cpp IODataStructures/TensorImages/mitkNrrdTensorImageWriter.cpp IODataStructures/TensorImages/mitkNrrdTensorImageIOFactory.cpp IODataStructures/TensorImages/mitkNrrdTensorImageWriterFactory.cpp IODataStructures/TensorImages/mitkTensorImage.cpp IODataStructures/TensorImages/mitkTensorImageSerializer.cpp #IODataStructures/mitkRegistrationObject.cpp # Rendering Rendering/vtkMaskedProgrammableGlyphFilter.cpp Rendering/mitkCompositeMapper.cpp Rendering/mitkVectorImageVtkGlyphMapper3D.cpp Rendering/vtkOdfSource.cxx Rendering/vtkThickPlane.cxx Rendering/mitkOdfNormalizationMethodProperty.cpp Rendering/mitkOdfScaleByProperty.cpp Rendering/mitkPlanarFigureMapper3D.cpp # Algorithms + Algorithms/Registration/mitkBatchedRegistration.cpp Algorithms/mitkPartialVolumeAnalysisHistogramCalculator.cpp Algorithms/mitkPartialVolumeAnalysisClusteringCalculator.cpp Algorithms/itkDwiGradientLengthCorrectionFilter.cpp # Registration Algorithms & Co. Algorithms/Registration/mitkPyramidImageRegistrationMethod.cpp # Function Collection mitkDiffusionFunctionCollection.cpp ) set(H_FILES # function Collection mitkDiffusionFunctionCollection.h # Rendering Rendering/mitkDiffusionImageMapper.h Rendering/mitkOdfVtkMapper2D.h Rendering/mitkPlanarFigureMapper3D.h # Reconstruction Algorithms/Reconstruction/itkDiffusionQballReconstructionImageFilter.h Algorithms/Reconstruction/mitkTeemDiffusionTensor3DReconstructionImageFilter.h Algorithms/Reconstruction/itkAnalyticalDiffusionQballReconstructionImageFilter.h Algorithms/Reconstruction/itkDiffusionMultiShellQballReconstructionImageFilter.h Algorithms/Reconstruction/itkPointShell.h Algorithms/Reconstruction/itkOrientationDistributionFunction.h Algorithms/Reconstruction/itkDiffusionIntravoxelIncoherentMotionReconstructionImageFilter.h Algorithms/Reconstruction/itkMultiShellAdcAverageReconstructionImageFilter.h Algorithms/Reconstruction/itkMultiShellRadialAdcKurtosisImageFilter.h # IO Datastructures IODataStructures/DiffusionWeightedImages/mitkDiffusionImage.h # Algorithms Algorithms/itkDiffusionQballGeneralizedFaImageFilter.h Algorithms/itkDiffusionQballPrepareVisualizationImageFilter.h Algorithms/itkTensorDerivedMeasurementsFilter.h Algorithms/itkBrainMaskExtractionImageFilter.h Algorithms/itkB0ImageExtractionImageFilter.h Algorithms/itkB0ImageExtractionToSeparateImageFilter.h Algorithms/itkTensorImageToDiffusionImageFilter.h Algorithms/itkTensorToL2NormImageFilter.h Algorithms/itkGaussianInterpolateImageFunction.h Algorithms/mitkPartialVolumeAnalysisHistogramCalculator.h Algorithms/mitkPartialVolumeAnalysisClusteringCalculator.h Algorithms/itkDiffusionTensorPrincipalDirectionImageFilter.h Algorithms/itkCartesianToPolarVectorImageFilter.h Algorithms/itkPolarToCartesianVectorImageFilter.h Algorithms/itkDistanceMapFilter.h Algorithms/itkProjectionFilter.h Algorithms/itkResidualImageFilter.h Algorithms/itkExtractChannelFromRgbaImageFilter.h Algorithms/itkTensorReconstructionWithEigenvalueCorrectionFilter.h Algorithms/itkMergeDiffusionImagesFilter.h Algorithms/itkDwiPhantomGenerationFilter.h Algorithms/itkFiniteDiffOdfMaximaExtractionFilter.h Algorithms/itkMrtrixPeakImageConverter.h Algorithms/itkFslPeakImageConverter.h Algorithms/itkShCoefficientImageImporter.h Algorithms/itkOdfMaximaExtractionFilter.h Algorithms/itkResampleDwiImageFilter.h Algorithms/itkDwiGradientLengthCorrectionFilter.h Algorithms/itkAdcImageFilter.h Algorithms/itkSplitDWImageFilter.h Algorithms/Registration/mitkDWIHeadMotionCorrectionFilter.h Algorithms/mitkDiffusionImageToDiffusionImageFilter.h ) set( TOOL_FILES ) diff --git a/Modules/OpenCL/Testing/mitkOclBinaryThresholdImageFilterTest.cpp b/Modules/OpenCL/Testing/mitkOclBinaryThresholdImageFilterTest.cpp index cb57f9babe..f92fc78268 100644 --- a/Modules/OpenCL/Testing/mitkOclBinaryThresholdImageFilterTest.cpp +++ b/Modules/OpenCL/Testing/mitkOclBinaryThresholdImageFilterTest.cpp @@ -1,111 +1,111 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include #include // itk filter for reference computation #include #include #include using namespace mitk; /** This function is testing the class mitk::OclContextManager. */ int mitkOclBinaryThresholdImageFilterTest( int argc, char* argv[] ) { MITK_TEST_BEGIN("mitkOclBinaryThresholdImageFilterTest"); - ServiceReference ref = GetModuleContext()->GetServiceReference(); + us::ServiceReference ref = GetModuleContext()->GetServiceReference(); MITK_TEST_CONDITION_REQUIRED( ref != 0, "Got valid ServiceReference" ); OclResourceService* resources = GetModuleContext()->GetService(ref); MITK_TEST_CONDITION_REQUIRED( resources != NULL, "OpenCL Resource service available." ); cl_context gpuContext = resources->GetContext(); MITK_TEST_CONDITION_REQUIRED( gpuContext != NULL, "Got not-null OpenCL context."); cl_device_id gpuDevice = resources->GetCurrentDevice(); MITK_TEST_CONDITION_REQUIRED( gpuDevice != NULL, "Got not-null OpenCL device."); //Create a random reference image mitk::Image::Pointer inputImage = mitk::ImageGenerator::GenerateRandomImage(119, 204, 52, 1, // dimension 1.0f, 1.0f, 1.0f, // spacing 255, 0); // max, min MITK_TEST_CONDITION_REQUIRED( inputImage.IsNotNull(), "Input (random) mitk::Image object instantiated."); // FIXME: could also be random values int upperThr = 255; int lowerThr = 60; int outsideVal = 0; int insideVal = 100; mitk::OclBinaryThresholdImageFilter* oclFilter = new mitk::OclBinaryThresholdImageFilter; MITK_TEST_CONDITION_REQUIRED( oclFilter != NULL, "Filter was created. "); oclFilter->SetInput( inputImage ); oclFilter->SetUpperThreshold( upperThr ); oclFilter->SetLowerThreshold( lowerThr ); oclFilter->SetOutsideValue( outsideVal ); oclFilter->SetInsideValue( insideVal ); oclFilter->Update(); mitk::Image::Pointer outputImage = mitk::Image::New(); outputImage = oclFilter->GetOutput(); MITK_TEST_CONDITION_REQUIRED( outputImage.IsNotNull(), "Filter returned an not-NULL image. "); // reference computation typedef itk::Image< unsigned char, 3> ImageType; typedef itk::BinaryThresholdImageFilter< ImageType, ImageType > ThresholdFilterType; ImageType::Pointer itkInputImage = ImageType::New(); CastToItkImage( inputImage, itkInputImage ); ThresholdFilterType::Pointer refThrFilter = ThresholdFilterType::New(); refThrFilter->SetInput( itkInputImage ); refThrFilter->SetLowerThreshold( lowerThr ); refThrFilter->SetUpperThreshold( upperThr ); refThrFilter->SetOutsideValue( outsideVal ); refThrFilter->SetInsideValue( insideVal ); typedef itk::SubtractImageFilter< ImageType, ImageType > SubtractFilterType; SubtractFilterType::Pointer subFilt = SubtractFilterType::New(); ImageType::Pointer gpuReferenceImage = ImageType::New(); CastToItkImage( oclFilter->GetOutput() ,gpuReferenceImage ); subFilt->SetInput1( refThrFilter->GetOutput() ); subFilt->SetInput2( gpuReferenceImage ); typedef itk::StatisticsImageFilter< ImageType > StatFilterType; StatFilterType::Pointer stats = StatFilterType::New(); stats->SetInput( subFilt->GetOutput() ); stats->Update(); MITK_TEST_CONDITION( stats->GetMaximum() == 0, "Maximal value in the difference image is 0."); MITK_TEST_CONDITION( stats->GetMinimum() == 0, "Minimal value in the difference image is 0.") MITK_TEST_END(); -} +} \ No newline at end of file diff --git a/Modules/OpenCL/Testing/mitkOclImageTest.cpp b/Modules/OpenCL/Testing/mitkOclImageTest.cpp index 38ae3b1a62..1474300709 100644 --- a/Modules/OpenCL/Testing/mitkOclImageTest.cpp +++ b/Modules/OpenCL/Testing/mitkOclImageTest.cpp @@ -1,94 +1,94 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include using namespace mitk; /** This function is testing the mitk::OclImage class. */ int mitkOclImageTest( int /*argc*/, char* /*argv*/[] ) { MITK_TEST_BEGIN("mitkOclImageTest"); - ServiceReference ref = GetModuleContext()->GetServiceReference(); + us::ServiceReference ref = GetModuleContext()->GetServiceReference(); MITK_TEST_CONDITION_REQUIRED( ref != 0, "Got valid ServiceReference" ); OclResourceService* resources = GetModuleContext()->GetService(ref); MITK_TEST_CONDITION_REQUIRED( resources != NULL, "OpenCL Resource service available." ); cl_context gpuContext = resources->GetContext(); MITK_TEST_CONDITION_REQUIRED( gpuContext != NULL, "Got not-null OpenCL context."); cl_device_id gpuDevice = resources->GetCurrentDevice(); MITK_TEST_CONDITION_REQUIRED( gpuDevice != NULL, "Got not-null OpenCL device."); //Create a random reference image mitk::Image::Pointer reference = mitk::ImageGenerator::GenerateRandomImage(119, 204, 52, 1, // dimension 1.0f, 1.0f, 1.0f, // spacing 1024, 0); // max, min MITK_TEST_CONDITION_REQUIRED( reference.IsNotNull(), "Reference mitk::Image object instantiated."); mitk::OclImage::Pointer first = mitk::OclImage::New(); first->InitializeByMitkImage(reference); MITK_TEST_CONDITION_REQUIRED(first.IsNotNull(), "oclImage object instantiated."); // test if oclImage correct initialized MITK_TEST_CONDITION( first->GetMITKImage() == reference, "oclImage has the correct reference mitk::Image"); MITK_TEST_CONDITION( first->GetDimension() == reference->GetDimension(), "Same dimensionality."); cl_int clErr = 0; cl_command_queue cmdQueue = clCreateCommandQueue( gpuContext, gpuDevice, 0 ,&clErr); MITK_TEST_CONDITION_REQUIRED( clErr == CL_SUCCESS, "A command queue was created."); // Allocate and copy image data to GPU first->TransferDataToGPU(cmdQueue); MITK_TEST_CONDITION( first->IsModified(0), "Modified flag for GPU correctly set."); // check if the created GPU object is valid cl_mem gpuImage = first->GetGPUImage(cmdQueue); MITK_TEST_CONDITION_REQUIRED( gpuImage != NULL, "oclImage returned a valid GPU memory pointer"); size_t returned = 0; cl_image_format imgFmt; clErr = clGetImageInfo( gpuImage, CL_IMAGE_FORMAT, sizeof(cl_image_format), (void*) &imgFmt, &returned ); MITK_TEST_CONDITION( clErr == CL_SUCCESS, "oclImage has created a valid GPU image"); // test for dimensions size_t imagesize = 0; clErr = clGetImageInfo( gpuImage, CL_IMAGE_WIDTH, sizeof(size_t), (void*) &imagesize, &returned ); MITK_TEST_CONDITION( imagesize == static_cast(first->GetDimension(0)), "Image width corresponds" ); clErr = clGetImageInfo( gpuImage, CL_IMAGE_HEIGHT, sizeof(size_t), (void*) &imagesize, &returned ); MITK_TEST_CONDITION( imagesize == static_cast(first->GetDimension(1)), "Image height corresponds" ); clErr = clGetImageInfo( gpuImage, CL_IMAGE_DEPTH, sizeof(size_t), (void*) &imagesize, &returned ); MITK_TEST_CONDITION( imagesize == static_cast(first->GetDimension(2)), "Image depth corresponds" ); // clean up clReleaseCommandQueue( cmdQueue ); MITK_TEST_END(); -} +} \ No newline at end of file diff --git a/Modules/OpenCL/Testing/mitkOclReferenceCountTest.cpp b/Modules/OpenCL/Testing/mitkOclReferenceCountTest.cpp index bed5d0b950..180c76af11 100644 --- a/Modules/OpenCL/Testing/mitkOclReferenceCountTest.cpp +++ b/Modules/OpenCL/Testing/mitkOclReferenceCountTest.cpp @@ -1,92 +1,92 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include #include // itk filter for reference computation #include #include #include using namespace mitk; /** This function is testing the OclFilter class and the OpenCL resource service. To prevent segmentation faults a mutexed reference counter is implemented in the resource service. It tracks the number of opencl program references for the corresponding filter and delete only the opencl programm if the reference count reaches 0. Every new instance of a filter increases the reference count by 1. This test runs successfull if the 2 filters are initialized, run and deleted without any crash. */ int mitkOclReferenceCountTest( int argc, char* argv[] ) { MITK_TEST_BEGIN("mitkOclReferenceCountTest"); // instancate uService - ServiceReference ref = GetModuleContext()->GetServiceReference(); + us::ServiceReference ref = GetModuleContext()->GetServiceReference(); OclResourceService* resources = GetModuleContext()->GetService(ref); cl_context gpuContext = resources->GetContext(); cl_device_id gpuDevice = resources->GetCurrentDevice(); //Create a random reference image mitk::Image::Pointer inputImage = mitk::ImageGenerator::GenerateRandomImage(119, 204, 52, 1, // dimension 1.0f, 1.0f, 1.0f, // spacing 255, 0); // max, min int upperThr = 255; int lowerThr = 60; int outsideVal = 0; int insideVal = 100; mitk::OclBinaryThresholdImageFilter* oclFilter1 = new mitk::OclBinaryThresholdImageFilter; oclFilter1->SetInput( inputImage ); oclFilter1->SetUpperThreshold( upperThr ); oclFilter1->SetLowerThreshold( lowerThr ); oclFilter1->SetOutsideValue( outsideVal ); oclFilter1->SetInsideValue( insideVal ); oclFilter1->Update(); mitk::Image::Pointer outputImage1 = mitk::Image::New(); outputImage1 = oclFilter1->GetOutput(); mitk::OclBinaryThresholdImageFilter* oclFilter2 = new mitk::OclBinaryThresholdImageFilter; oclFilter2->SetInput( inputImage ); oclFilter2->SetUpperThreshold( upperThr ); oclFilter2->SetLowerThreshold( lowerThr ); oclFilter2->SetOutsideValue( outsideVal ); oclFilter2->SetInsideValue( insideVal ); oclFilter2->Update(); mitk::Image::Pointer outputImage2 = mitk::Image::New(); outputImage2 = oclFilter2->GetOutput(); // delete filters delete oclFilter1; delete oclFilter2; // this is only visible if the delete did not cause a segmentation fault // it is always true and successfull if the program reaches this state MITK_TEST_CONDITION_REQUIRED( true, "2 Filters deleted without a crash -> success "); MITK_TEST_END(); -} +} \ No newline at end of file diff --git a/Modules/OpenCL/Testing/mitkOclResourceServiceTest.cpp b/Modules/OpenCL/Testing/mitkOclResourceServiceTest.cpp index b20f4bea4f..87cb8ec36d 100644 --- a/Modules/OpenCL/Testing/mitkOclResourceServiceTest.cpp +++ b/Modules/OpenCL/Testing/mitkOclResourceServiceTest.cpp @@ -1,115 +1,114 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkTestingMacros.h" #include "mitkOclUtils.h" #include #include #include #include "mitkOclResourceService.h" #include "mitkException.h" #include #include using namespace mitk; /** This function is testing the class mitk::OclContextManager. */ int mitkOclResourceServiceTest( int argc, char* argv[] ) { MITK_TEST_BEGIN("mitkOclResourceServiceTest"); - ServiceReference ref = GetModuleContext()->GetServiceReference(); + us::ServiceReference ref = us::GetModuleContext()->GetServiceReference(); MITK_TEST_CONDITION_REQUIRED( ref != NULL, "Resource service available." ); - OclResourceService* resources = GetModuleContext()->GetService(ref); + OclResourceService* resources = us::GetModuleContext()->GetService(ref); MITK_TEST_CONDITION_REQUIRED( resources != NULL, "Resource service available." ); cl_context first = resources->GetContext(); MITK_TEST_CONDITION_REQUIRED(first != NULL, "Got not-null OpenCL context."); - OclResourceService* resources_2 = GetModuleContext()->GetService(ref); + OclResourceService* resources_2 = us::GetModuleContext()->GetService(ref); MITK_TEST_CONDITION_REQUIRED( resources == resources_2, "Same resource reference the second time." ); cl_context second = resources_2->GetContext(); MITK_TEST_CONDITION_REQUIRED( first == second, "Both return same context"); // further tests requires for valid context if( first ) { cl_image_format testFmt; testFmt.image_channel_data_type = CL_FLOAT; testFmt.image_channel_order = CL_RGBA; MITK_TEST_CONDITION( resources->GetIsFormatSupported( &testFmt ), "Checking if format CL_FLOAT / CL_RGBA supported." ); } // create test program const std::string testProgramSource = "__kernel void testKernel( __global uchar* buffer ){ \ const unsigned int globalPosX = get_global_id(0); \ buffer[globalPosX] = buffer[globalPosX] + 1;}"; cl_int err = 0; size_t progSize = testProgramSource.length(); const char* progSource = testProgramSource.c_str(); cl_program testProgram = clCreateProgramWithSource( first, 1, &progSource, &progSize, &err ); MITK_TEST_CONDITION_REQUIRED( err == CL_SUCCESS, "Test program loaded succesfully."); err = clBuildProgram(testProgram, 0, NULL, NULL, NULL, NULL); MITK_TEST_CONDITION_REQUIRED( err == CL_SUCCESS, "Test program built succesfully."); resources->InsertProgram( testProgram, "test_program", true); MITK_TEST_CONDITION( resources->GetProgram("test_program") == testProgram, "Program correctly stored by ResourceService"); // the manger throws exception when accessing non-existant programs MITK_TEST_FOR_EXCEPTION( mitk::Exception, resources->GetProgram("blah"); ); // another test source, this one does not compile const std::string testProgramSource_notCompiling = "__kernel void testKernel( __global uchar* buffer ){ \ const unsigned intt globalPosX = get_global_id(0); }"; progSize = testProgramSource_notCompiling.length(); const char* progSource2 = testProgramSource_notCompiling.c_str(); cl_program notComp_testProgram = clCreateProgramWithSource( first, 1, &progSource2, &progSize, &err ); // the error in the source code has no influence on loading the program MITK_TEST_CONDITION_REQUIRED( err == CL_SUCCESS, "Test program 2 loaded succesfully."); err = clBuildProgram(notComp_testProgram, 0, NULL, NULL, NULL, NULL); MITK_TEST_CONDITION_REQUIRED( err == CL_BUILD_PROGRAM_FAILURE, "Test program 2 failed to build."); std::cout << " --> The (expected) OpenCL Build Error occured : ";// << GetOclErrorString(err); resources->InsertProgram( notComp_testProgram, "test_program_failed", true); MITK_TEST_CONDITION( resources->GetProgram("test_program_failed") == notComp_testProgram, "Program correctly stored by ResourceService"); // calling the InvalidateStorage() will result in removing the _failed test program inserted above resources->InvalidateStorage(); // the second test program should no more exist in the storage, hence we await an exception MITK_TEST_FOR_EXCEPTION( mitk::Exception, resources->GetProgram("test_program_failed"); ); MITK_TEST_END(); } - -US_INITIALIZE_MODULE("OpenCLTestDriver", "", "", "" ) +US_INITIALIZE_MODULE("OpenCLTestDriver", "" ) diff --git a/Modules/OpenCL/mitkOclBinaryThresholdImageFilter.cpp b/Modules/OpenCL/mitkOclBinaryThresholdImageFilter.cpp index 4e7dede7a7..59ec122ff6 100644 --- a/Modules/OpenCL/mitkOclBinaryThresholdImageFilter.cpp +++ b/Modules/OpenCL/mitkOclBinaryThresholdImageFilter.cpp @@ -1,100 +1,100 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkOclBinaryThresholdImageFilter.h" +#include "usServiceReference.h" mitk::OclBinaryThresholdImageFilter::OclBinaryThresholdImageFilter() : m_ckBinaryThreshold( NULL ) { std::string path = "BinaryThresholdFilter.cl"; this->SetSourceFile( path.c_str() ); this->m_FilterID = "BinaryThreshold"; this->m_LowerThreshold = 10; this->m_UpperThreshold = 200; this->m_InsideValue = 100; this->m_OutsideValue = 0; } mitk::OclBinaryThresholdImageFilter::~OclBinaryThresholdImageFilter() { if ( this->m_ckBinaryThreshold ) { clReleaseKernel( m_ckBinaryThreshold ); } } void mitk::OclBinaryThresholdImageFilter::Update() { //Check if context & program available if (!this->Initialize()) { - mitk::ServiceReference ref = GetModuleContext()->GetServiceReference(); + us::ServiceReference ref = GetModuleContext()->GetServiceReference(); OclResourceService* resources = GetModuleContext()->GetService(ref); // clean-up also the resources resources->InvalidateStorage(); mitkThrow() <<"Filter is not initialized. Cannot update."; } else{ // Execute this->Execute(); } } void mitk::OclBinaryThresholdImageFilter::Execute() { cl_int clErr = 0; try { this->InitExec( this->m_ckBinaryThreshold ); } catch( const mitk::Exception& e) { MITK_ERROR << "Catched exception while initializing filter: " << e.what(); return; } // set kernel arguments clErr = clSetKernelArg( this->m_ckBinaryThreshold, 2, sizeof(cl_int), &(this->m_LowerThreshold) ); clErr |= clSetKernelArg( this->m_ckBinaryThreshold, 3, sizeof(cl_int), &(this->m_UpperThreshold) ); clErr |= clSetKernelArg( this->m_ckBinaryThreshold, 4, sizeof(cl_int), &(this->m_OutsideValue) ); clErr |= clSetKernelArg( this->m_ckBinaryThreshold, 5, sizeof(cl_int), &(this->m_InsideValue) ); CHECK_OCL_ERR( clErr ); // execute the filter on a 3D NDRange this->ExecuteKernel( m_ckBinaryThreshold, 3); // signalize the GPU-side data changed m_Output->Modified( GPU_DATA ); - } bool mitk::OclBinaryThresholdImageFilter::Initialize() { bool buildErr = true; cl_int clErr = 0; if ( OclFilter::Initialize() ) { this->m_ckBinaryThreshold = clCreateKernel( this->m_ClProgram, "ckBinaryThreshold", &clErr); buildErr |= CHECK_OCL_ERR( clErr ); } return (Superclass::IsInitialized() && buildErr ); -} +} \ No newline at end of file diff --git a/Modules/OpenCL/mitkOclFilter.cpp b/Modules/OpenCL/mitkOclFilter.cpp index 9e61e137da..c8596d73f9 100644 --- a/Modules/OpenCL/mitkOclFilter.cpp +++ b/Modules/OpenCL/mitkOclFilter.cpp @@ -1,224 +1,227 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ //Ocl #include "mitkOclFilter.h" #include "mitkOclUtils.h" #include "mitkOpenCLActivator.h" //Mitk #include #include #include #include +//usService +#include "usServiceReference.h" + mitk::OclFilter::OclFilter() : m_ClFile(), m_ClSource(NULL), m_ClCompilerFlags(""), m_ClProgram(NULL), m_CommandQue(NULL), m_FilterID("mitkOclFilter"), m_Preambel(" "), m_Initialized(false) { m_ClSourcePath = MITK_ROOT; m_ClSourcePath += "Modules/OpenCL/ShaderSources"; } mitk::OclFilter::OclFilter(const char* filename) : m_ClFile(), m_ClSource(NULL), m_ClCompilerFlags(""), m_ClProgram(NULL), m_CommandQue(NULL), m_FilterID(filename), m_Preambel(" "), m_Initialized(false) { m_ClSourcePath = MITK_ROOT; m_ClSourcePath += "Modules/OpenCL/ShaderSources"; } mitk::OclFilter::~OclFilter() { MITK_DEBUG << "OclFilter Destructor"; // release program if (m_ClProgram) { - mitk::ServiceReference ref = GetModuleContext()->GetServiceReference(); + us::ServiceReference ref = GetModuleContext()->GetServiceReference(); OclResourceService* resources = GetModuleContext()->GetService(ref); // remove program from storage resources->RemoveProgram(m_FilterID); } } bool mitk::OclFilter::ExecuteKernel( cl_kernel kernel, unsigned int workSizeDim ) { cl_int clErr = 0; clErr = clEnqueueNDRangeKernel( this->m_CommandQue, kernel, workSizeDim, NULL, this->m_GlobalWorkSize, m_LocalWorkSize, 0, NULL, NULL); CHECK_OCL_ERR( clErr ); return ( clErr == CL_SUCCESS ); } bool mitk::OclFilter::Initialize() { - mitk::ServiceReference ref = GetModuleContext()->GetServiceReference(); + us::ServiceReference ref = GetModuleContext()->GetServiceReference(); OclResourceService* resources = GetModuleContext()->GetService(ref); m_CommandQue = resources->GetCommandQueue(); cl_int clErr = 0; m_Initialized = CHECK_OCL_ERR(clErr); if ((m_ClSource==NULL) && (m_ClFile.empty())) { MITK_ERROR<<"No OpenCL Source FILE specified"; return false; } if (m_ClProgram == NULL) { try { this->m_ClProgram = resources->GetProgram( this->m_FilterID ); } catch(const mitk::Exception& e) { MITK_INFO << "Program not stored in resource manager, compiling."; this->CompileSource(); } } return m_Initialized; } void mitk::OclFilter::SetSourceFile(const char* filename) { MITK_DEBUG("ocl.filter") << "Setting source [" << filename <<" ]"; mitk::StandardFileLocations::GetInstance()->AddDirectoryForSearch( m_ClSourcePath.c_str(), true); // search for file m_ClFile = mitk::StandardFileLocations::GetInstance()->FindFile( filename); } void mitk::OclFilter::CompileSource() { if (m_ClFile.empty() && m_ClSource == NULL) { MITK_ERROR("ocl.filter") << "No shader source file was set"; return; } // help variables size_t szKernelLength; int clErr = 0; //get a valid opencl context - mitk::ServiceReference ref = GetModuleContext()->GetServiceReference(); + us::ServiceReference ref = GetModuleContext()->GetServiceReference(); OclResourceService* resources = GetModuleContext()->GetService(ref); cl_context gpuContext = resources->GetContext(); // load the program source from file m_ClSource = oclLoadProgramSource( m_ClFile.c_str(), this->m_Preambel, &szKernelLength); if (m_ClSource != NULL) { m_ClProgram = clCreateProgramWithSource(gpuContext, 1, (const char**)&m_ClSource, &szKernelLength, &clErr); CHECK_OCL_ERR(clErr); // build the source code MITK_DEBUG << "Building Program Source"; std::string compilerOptions = ""; compilerOptions.append(m_ClCompilerFlags); // activate the include compiler flag compilerOptions.append(" -I"); // set the path of the current gpu source dir as opencl // include folder compilerOptions.append(m_ClSourcePath.c_str()); MITK_DEBUG("ocl.filter") << "cl compiler flags: " << compilerOptions.c_str(); clErr = clBuildProgram(m_ClProgram, 0, NULL, compilerOptions.c_str(), NULL, NULL); CHECK_OCL_ERR(clErr); // if OpenCL Source build failed if (clErr != CL_SUCCESS) { MITK_ERROR("ocl.filter") << "Failed to build source"; oclLogBuildInfo(m_ClProgram, resources->GetCurrentDevice() ); oclLogBinary(m_ClProgram, resources->GetCurrentDevice() ); m_Initialized = false; } // store the succesfully build program into the program storage provided by the resource service resources->InsertProgram(m_ClProgram, m_FilterID, true); } else { MITK_ERROR("ocl.filter") << "Could not load from source"; m_Initialized = false; } } void mitk::OclFilter::SetWorkingSize(unsigned int locx, unsigned int dimx, unsigned int locy, unsigned int dimy, unsigned int locz, unsigned int dimz) { // set the local work size this->m_LocalWorkSize[0] = locx; this->m_LocalWorkSize[1] = locy; this->m_LocalWorkSize[2] = locz; this->m_GlobalWorkSize[0] = dimx; this->m_GlobalWorkSize[1] = dimy; this->m_GlobalWorkSize[2] = dimz; // estimate the global work size this->m_GlobalWorkSize[0] = iDivUp( dimx, this->m_LocalWorkSize[0]) * this->m_LocalWorkSize[0]; if ( dimy > 1) this->m_GlobalWorkSize[1] = iDivUp( dimy, this->m_LocalWorkSize[1]) * this->m_LocalWorkSize[1]; if( dimz > 1 ) this->m_GlobalWorkSize[2] = iDivUp( dimz, this->m_LocalWorkSize[2]) * this->m_LocalWorkSize[2]; } void mitk::OclFilter::SetSourcePreambel(const char* preambel) { this->m_Preambel = preambel; } void mitk::OclFilter::SetSourcePath(const char* path) { m_ClSourcePath = path; } void mitk::OclFilter::SetCompilerFlags(const char* flags) { m_ClCompilerFlags = flags; } bool mitk::OclFilter::IsInitialized() { return m_Initialized; -} +} \ No newline at end of file diff --git a/Modules/OpenCL/mitkOclImage.cpp b/Modules/OpenCL/mitkOclImage.cpp index 7ad3b08c65..230c92334f 100644 --- a/Modules/OpenCL/mitkOclImage.cpp +++ b/Modules/OpenCL/mitkOclImage.cpp @@ -1,355 +1,350 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkOclImage.h" #include "mitkImageDataItem.h" #include "mitkCommon.h" #include "mitkLogMacros.h" #include "mitkOclUtils.h" #include #include mitk::OclImage::OclImage() : m_gpuImage(NULL), m_context(NULL), m_bufferSize(0), m_gpuModified(false), m_cpuModified(false), m_Image(NULL), m_dim(0), m_Dims(NULL), m_BpE(1), m_formatSupported(false) { } mitk::OclImage::~OclImage() { MITK_INFO << "OclImage Destructor"; //release GMEM Image buffer if (m_gpuImage) clReleaseMemObject(m_gpuImage); } cl_mem mitk::OclImage::CreateGPUImage(unsigned int _wi, unsigned int _he, unsigned int _de, unsigned int _bpp) { MITK_INFO << "CreateGPUImage call with: BPP=" << _bpp; this->m_Dims = new unsigned int[MAX_DIMS]; m_Dims[0] = _wi; m_Dims[1] = _he; m_Dims[2] = _de; for (unsigned int i=3; iGetServiceReference(); + us::ServiceReference ref = GetModuleContext()->GetServiceReference(); OclResourceService* resources = GetModuleContext()->GetService(ref); cl_context gpuContext = resources->GetContext(); int clErr; m_gpuImage = clCreateBuffer( gpuContext, CL_MEM_READ_WRITE, m_bufferSize * m_BpE, NULL, &clErr); CHECK_OCL_ERR(clErr); return m_gpuImage; } void mitk::OclImage::InitializeByMitkImage(mitk::Image::Pointer _image) { this->m_Image = _image; this->m_cpuModified = true; this->m_gpuModified = false; this->m_gpuImage = NULL; // compute the size of the GMEM buffer this->m_dim = this->m_Image->GetDimension(); this->m_Dims = this->m_Image->GetDimensions(); MITK_INFO << "Image: " << this->m_Dims[0] <<"x"<< this->m_Dims[1] <<"x"<< this->m_Dims[2]; // get the dimensions this->m_bufferSize = 1; for (unsigned int i=0; im_dim; i++) { this->m_bufferSize *= this->m_Dims[i]; } // multiply by sizeof(PixelType) this->m_BpE = ( this->m_Image->GetPixelType().GetBpe() / 8); } bool mitk::OclImage::IsModified(int _type) { if (_type) return m_cpuModified; else return m_gpuModified; } void mitk::OclImage::Modified(int _type) { // defines... GPU: 0, CPU: 1 m_cpuModified = _type; m_gpuModified = !_type; } int mitk::OclImage::TransferDataToGPU(cl_command_queue gpuComQueue) { cl_int clErr = 0; // check whether an image present if (!m_Image->IsInitialized()){ MITK_ERROR("ocl.Image") << "(mitk) Image not initialized!\n"; return -1; } // there is a need for copy only if RAM-Data newer then GMEM data if (m_cpuModified) { //check the buffer if(m_gpuImage == NULL) { clErr = this->AllocateGPUImage(); } if (m_Image->IsInitialized() && (clErr == CL_SUCCESS)) { const size_t origin[3] = {0, 0, 0}; const size_t region[3] = {m_Dims[0], m_Dims[1], m_Dims[2]}; if( this->m_formatSupported ) { mitk::ImageReadAccessor accessor(m_Image); clErr = clEnqueueWriteImage( gpuComQueue, m_gpuImage, CL_TRUE, origin, region, 0, 0, accessor.GetData(), 0, NULL, NULL); } else { MITK_ERROR << "Selected image format currently not supported..."; } CHECK_OCL_ERR(clErr); } m_gpuModified = true; } return clErr; } cl_int mitk::OclImage::AllocateGPUImage() { cl_int clErr = 0; - mitk::ServiceReference ref = GetModuleContext()->GetServiceReference(); + us::ServiceReference ref = GetModuleContext()->GetServiceReference(); OclResourceService* resources = GetModuleContext()->GetService(ref); cl_context gpuContext = resources->GetContext(); // initialize both proposed and supported format variables to same value this->m_proposedFormat = this->ConvertPixelTypeToOCLFormat(); this->m_supportedFormat = this->m_proposedFormat; // test the current format for HW support this->m_formatSupported = resources->GetIsFormatSupported( &(this->m_supportedFormat) ); // create an transfer kernel object in case the proposed format is not supported if( !(this->m_formatSupported) ) { MITK_ERROR << "Original format not supported on the installed graphics card."; return -1; } // create new buffer if( this->m_dim > 2) { //Create a 3D Image m_gpuImage = clCreateImage3D(gpuContext, CL_MEM_READ_ONLY, &m_supportedFormat, *(m_Dims), *(m_Dims+1), *(m_Dims+2), 0, 0, NULL, &clErr); } else { //Create a 2D Image m_gpuImage = clCreateImage2D(gpuContext, CL_MEM_READ_ONLY, &m_supportedFormat, *(m_Dims), *(m_Dims+1), 0, NULL, &clErr); } CHECK_OCL_ERR(clErr); return clErr; } cl_mem mitk::OclImage::GetGPUImage(cl_command_queue gpuComQueue) { // clGetMemObjectInfo() cl_mem_object_type memInfo; cl_int clErr = 0; // query image object info only if already initialized if( this->m_gpuImage ) { clErr = clGetMemObjectInfo(this->m_gpuImage, CL_MEM_TYPE, sizeof(cl_mem_object_type), &memInfo, NULL ); CHECK_OCL_ERR(clErr); } MITK_INFO << "Querying info for object, recieving: " << memInfo; // test if m_gpuImage CL_MEM_IMAGE_2/3D // if not, copy buffer to image if (memInfo == CL_MEM_OBJECT_BUFFER) { MITK_WARN << " Passed oclImage is a buffer-object, creating image"; //hold a copy of the buffer gmem pointer cl_mem tempBuffer = this->m_gpuImage; const size_t origin[3] = {0, 0, 0}; size_t region[3] = {this->m_Dims[0], this->m_Dims[1], 1}; clErr = this->AllocateGPUImage(); this->m_dim = 3; //copy last data to the image data clErr = clEnqueueCopyBufferToImage( gpuComQueue, tempBuffer, m_gpuImage, 0, origin, region, 0, NULL, NULL); CHECK_OCL_ERR(clErr); //release pointer clReleaseMemObject(tempBuffer); - } return m_gpuImage; - } void mitk::OclImage::SetPixelType(const cl_image_format *_image) { this->m_proposedFormat.image_channel_data_type = _image->image_channel_data_type; this->m_proposedFormat.image_channel_order = _image->image_channel_order; } void* mitk::OclImage::TransferDataToCPU(cl_command_queue gpuComQueue) { cl_int clErr = 0; // if image created on GPU, needs to create mitk::Image if( m_Image.IsNull() ){ MITK_INFO << "Image not initialized, creating new one."; m_Image = mitk::Image::New(); } // check buffersize/image size char* data = new char[m_bufferSize * m_BpE]; // debug info oclPrintMemObjectInfo( m_gpuImage ); clErr = clEnqueueReadBuffer( gpuComQueue, m_gpuImage, CL_FALSE, 0, m_bufferSize * m_BpE, data ,0, NULL, NULL); CHECK_OCL_ERR(clErr); clFlush( gpuComQueue ); // the cpu data is same as gpu this->m_gpuModified = false; return (void*) data; - } cl_image_format mitk::OclImage::ConvertPixelTypeToOCLFormat() { cl_image_format texFormat; //single channel Gray-Valued Images texFormat.image_channel_order = CL_R; MITK_INFO << "Class own value: " << this->m_BpE; switch ( this->m_BpE ) { case 1: texFormat.image_channel_data_type = CL_UNSIGNED_INT8; MITK_INFO<< "PixelType: UCHAR => CLFormat: [CL_UNORM_INT8, CL_R]"; break; case 2: texFormat.image_channel_data_type = CL_SIGNED_INT16; // texFormat.image_channel_order = CL_R; MITK_INFO<< "PixelType: SHORT => CLFormat: [CL_SIGNED_INT16, CL_R]"; break; case 4: texFormat.image_channel_data_type = CL_FLOAT; MITK_INFO<< "Choosing CL_FLOAT"; break; default: texFormat.image_channel_data_type = CL_UNORM_INT8; texFormat.image_channel_order = CL_RG; MITK_INFO<< "Choosing (default) short: 2-Channel UCHAR"; break; } return texFormat; } int mitk::OclImage::GetDimension(int idx) const { if (this->m_dim > idx) { return m_Dims[idx]; } else { MITK_WARN << "Trying to access non-existing dimension."; return 1; } } void mitk::OclImage::SetDimensions(unsigned int* Dims) { m_Dims = Dims; } void mitk::OclImage::SetDimension(unsigned short dim) { m_dim = dim; } float mitk::OclImage::GetSpacing(int idx) { if (this->m_dim > idx) { const float* imSpacing = m_Image->GetSlicedGeometry()->GetFloatSpacing(); return imSpacing[idx]; } else { MITK_WARN << "Trying to access non-existing dimension."; return 1; } } void mitk::OclImage::InitializeMITKImage() { this->m_Image = mitk::Image::New(); } void mitk::OclImage::GetOffset(float* _imOffset) const { - itk::Vector result2; result2.Fill(0.0f); result2 = this->m_Image->GetGeometry()->GetIndexToWorldTransform()->GetOffset(); _imOffset[0] = result2[0]; _imOffset[1] = result2[1]; _imOffset[2] = result2[2]; - -} +} \ No newline at end of file diff --git a/Modules/OpenCL/mitkOclResourceServiceImpl_p.h b/Modules/OpenCL/mitkOclResourceServiceImpl_p.h index 72015fcf2f..98b17e0ec1 100644 --- a/Modules/OpenCL/mitkOclResourceServiceImpl_p.h +++ b/Modules/OpenCL/mitkOclResourceServiceImpl_p.h @@ -1,184 +1,186 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef __mitkOclResourceServiceImpl_h #define __mitkOclResourceServiceImpl_h #include //Micro Services #include #include #include #include //ocl #include "mitkOclResourceService.h" #include "mitkOclUtils.h" #include "mitkOclImageFormats.h" #include +US_USE_NAMESPACE + //todo add docu! /** @struct OclContextCollection * @brief An capsulation of all OpenCL context related variables needed for the OclResourceService implementation * * The struct gets created on first call to GetContext in the OclResourceService and attepts to initialize all * relevant parts, i.e. the context itself, the device and the command queue */ struct OclContextCollection{ public: OclContextCollection() : m_Context(NULL), m_Devices(NULL), m_CreateContextFailed(false) { cl_int clErr = 0; size_t szParmDataBytes; cl_platform_id cpPlatform; cl_device_id m_cdDevice; try{ clErr = oclGetPlatformID( &cpPlatform); CHECK_OCL_ERR( clErr ); clErr = clGetDeviceIDs( cpPlatform, CL_DEVICE_TYPE_GPU, 1, &m_cdDevice, NULL); CHECK_OCL_ERR( clErr ); this->m_Context = clCreateContext( 0, 1, &m_cdDevice, NULL, NULL, &clErr); m_CreateContextFailed = (clErr != CL_SUCCESS); // get the info size clErr = clGetContextInfo(m_Context, CL_CONTEXT_DEVICES, 0,NULL, &szParmDataBytes ); this->m_Devices = (cl_device_id*) malloc(szParmDataBytes); // get device info clErr = clGetContextInfo(m_Context, CL_CONTEXT_DEVICES, szParmDataBytes, m_Devices, NULL); CHECK_OCL_ERR( clErr ); // create command queue m_CommandQueue = clCreateCommandQueue(m_Context, m_Devices[0], 0, &clErr); CHECK_OCL_ERR( clErr ); this->PrintContextInfo( ); // collect available image formats for current context this->m_ImageFormats = mitk::OclImageFormats::New(); this->m_ImageFormats->SetGPUContext(m_Context); } catch( std::exception& e) { MITK_ERROR("OpenCL.ResourceService") << "Exception while creating context: \n" << e.what(); } } ~OclContextCollection() { // if devices were allocated, delete if(m_Devices) { // TODO: Available first in OpenCL 1.2 : query the device for CL_PLATFORM_VERSION // through clGetPlatformInfo // clReleaseDevice(m_Devices[0]); delete [] m_Devices; } // if context was created release it if( m_Context ) clReleaseContext( this->m_Context ); } bool CanProvideContext() const { return ( m_Context != NULL && !m_CreateContextFailed ); } void PrintContextInfo() const { if( m_Devices ) { oclPrintDeviceInfo( m_Devices[0] ); } } /** The context */ cl_context m_Context; /** Available OpenCL devices */ cl_device_id* m_Devices; /** Class for handling (un)supported GPU image formats **/ mitk::OclImageFormats::Pointer m_ImageFormats; /** The command queue*/ cl_command_queue m_CommandQueue; bool m_CreateContextFailed; }; class OclResourceServiceImpl - : public US_BASECLASS_NAME, public OclResourceService + : public OclResourceService { private: // define programmdata private class struct ProgramData { int counter; cl_program program; itk::FastMutexLock::Pointer mutex; ProgramData() :counter(1), program(NULL) {} }; typedef std::map< std::string, ProgramData > ProgramMapType; //typedef std::map< std::string, std::pair< int, cl_program> > ProgramMapType; mutable OclContextCollection* m_ContextCollection; /** Map containing all available (allready compiled) OpenCL Programs */ ProgramMapType m_ProgramStorage; /** mutex for manipulating the program storage */ itk::FastMutexLock::Pointer m_ProgramStorageMutex; public: OclResourceServiceImpl(); ~OclResourceServiceImpl(); cl_context GetContext() const; cl_command_queue GetCommandQueue() const; cl_device_id GetCurrentDevice() const; bool GetIsFormatSupported(cl_image_format *); void PrintContextInfo() const; void InsertProgram(cl_program _program_in, std::string name, bool forceOverride=true); cl_program GetProgram(const std::string&name); void InvalidateStorage(); void RemoveProgram(const std::string&name); unsigned int GetMaximumImageSize(unsigned int dimension, cl_mem_object_type _imagetype); }; #endif // __mitkOclResourceServiceImpl_h diff --git a/Modules/OpenCL/mitkOpenCLActivator.cpp b/Modules/OpenCL/mitkOpenCLActivator.cpp index 29e2efb2c0..5018bb678c 100644 --- a/Modules/OpenCL/mitkOpenCLActivator.cpp +++ b/Modules/OpenCL/mitkOpenCLActivator.cpp @@ -1,33 +1,33 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkOpenCLActivator.h" -void OpenCLActivator::Load(mitk::ModuleContext *context) +void OpenCLActivator::Load(us::ModuleContext *context) { // generate context m_ResourceService.reset(new OclResourceServiceImpl); - mitk::ServiceProperties props; + us::ServiceProperties props; context->RegisterService(m_ResourceService.get(), props); } -void OpenCLActivator::Unload(mitk::ModuleContext *) +void OpenCLActivator::Unload(us::ModuleContext *) { m_ResourceService.release(); } -US_EXPORT_MODULE_ACTIVATOR(MitkOcl, OpenCLActivator ) +US_EXPORT_MODULE_ACTIVATOR(MitkOcl, OpenCLActivator ) \ No newline at end of file diff --git a/Modules/OpenCL/mitkOpenCLActivator.h b/Modules/OpenCL/mitkOpenCLActivator.h index c3132404d0..35308ce002 100644 --- a/Modules/OpenCL/mitkOpenCLActivator.h +++ b/Modules/OpenCL/mitkOpenCLActivator.h @@ -1,54 +1,54 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef __mitkOpenCLActivator_h #define __mitkOpenCLActivator_h #include "mitkOclResourceServiceImpl_p.h" #include #include #include #include #include #include #include /** * @class OpenCLActivator * * @brief Custom activator for the OpenCL Module in order to register * and provide the OclResourceService */ -class US_ABI_LOCAL OpenCLActivator : public mitk::ModuleActivator +class US_ABI_LOCAL OpenCLActivator : public us::ModuleActivator { private: std::auto_ptr m_ResourceService; public: /** @brief Load module context */ - void Load(mitk::ModuleContext *context); + void Load(us::ModuleContext *context); /** @brief Unload module context */ - void Unload(mitk::ModuleContext* ); + void Unload(us::ModuleContext* ); }; #endif // __mitkOpenCLActivator_h diff --git a/Modules/ToFProcessing/mitkToFDistanceImageToSurfaceFilter.cpp b/Modules/ToFProcessing/mitkToFDistanceImageToSurfaceFilter.cpp index 140342ec4a..5eff6f4042 100644 --- a/Modules/ToFProcessing/mitkToFDistanceImageToSurfaceFilter.cpp +++ b/Modules/ToFProcessing/mitkToFDistanceImageToSurfaceFilter.cpp @@ -1,344 +1,345 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include #include "mitkImageReadAccessor.h" #include #include #include #include #include #include #include #include #include #include mitk::ToFDistanceImageToSurfaceFilter::ToFDistanceImageToSurfaceFilter() : m_IplScalarImage(NULL), m_CameraIntrinsics(), m_TextureImageWidth(0), m_TextureImageHeight(0), m_InterPixelDistance(), m_TextureIndex(0), m_GenerateTriangularMesh(true), m_TriangulationThreshold(-1.0) { m_InterPixelDistance.Fill(0.045); m_CameraIntrinsics = mitk::CameraIntrinsics::New(); m_CameraIntrinsics->SetFocalLength(273.138946533,273.485900879); m_CameraIntrinsics->SetPrincipalPoint(107.867935181,98.3807373047); m_CameraIntrinsics->SetDistorsionCoeffs(-0.486690014601f,0.553943634033f,0.00222016777843f,-0.00300851115026f); m_ReconstructionMode = WithInterPixelDistance; } mitk::ToFDistanceImageToSurfaceFilter::~ToFDistanceImageToSurfaceFilter() { } void mitk::ToFDistanceImageToSurfaceFilter::SetInput( Image* distanceImage, mitk::CameraIntrinsics::Pointer cameraIntrinsics ) { this->SetCameraIntrinsics(cameraIntrinsics); this->SetInput(0,distanceImage); } void mitk::ToFDistanceImageToSurfaceFilter::SetInput( unsigned int idx, Image* distanceImage, mitk::CameraIntrinsics::Pointer cameraIntrinsics ) { this->SetCameraIntrinsics(cameraIntrinsics); this->SetInput(idx,distanceImage); } void mitk::ToFDistanceImageToSurfaceFilter::SetInput( mitk::Image* distanceImage ) { this->SetInput(0,distanceImage); } void mitk::ToFDistanceImageToSurfaceFilter::SetInput( unsigned int idx, mitk::Image* distanceImage ) { if ((distanceImage == NULL) && (idx == this->GetNumberOfInputs() - 1)) // if the last input is set to NULL, reduce the number of inputs by one this->SetNumberOfInputs(this->GetNumberOfInputs() - 1); else this->ProcessObject::SetNthInput(idx, distanceImage); // Process object is not const-correct so the const_cast is required here this->CreateOutputsForAllInputs(); } mitk::Image* mitk::ToFDistanceImageToSurfaceFilter::GetInput() { return this->GetInput(0); } mitk::Image* mitk::ToFDistanceImageToSurfaceFilter::GetInput( unsigned int idx ) { if (this->GetNumberOfInputs() < 1) { mitkThrow() << "No input given for ToFDistanceImageToSurfaceFilter"; } return static_cast< mitk::Image*>(this->ProcessObject::GetInput(idx)); } void mitk::ToFDistanceImageToSurfaceFilter::GenerateData() { mitk::Surface::Pointer output = this->GetOutput(); assert(output); mitk::Image::Pointer input = this->GetInput(); assert(input); // mesh points int xDimension = input->GetDimension(0); int yDimension = input->GetDimension(1); unsigned int size = xDimension*yDimension; //size of the image-array std::vector isPointValid; isPointValid.resize(size); vtkSmartPointer points = vtkSmartPointer::New(); points->SetDataTypeToDouble(); vtkSmartPointer polys = vtkSmartPointer::New(); vtkSmartPointer vertices = vtkSmartPointer::New(); vtkSmartPointer scalarArray = vtkSmartPointer::New(); vtkSmartPointer textureCoords = vtkSmartPointer::New(); textureCoords->SetNumberOfComponents(2); textureCoords->Allocate(size); //Make a vtkIdList to save the ID's of the polyData corresponding to the image //pixel ID's. See below for more documentation. m_VertexIdList = vtkSmartPointer::New(); //Allocate the object once else it would automatically allocate new memory //for every vertex and perform a copy which is expensive. m_VertexIdList->Allocate(size); m_VertexIdList->SetNumberOfIds(size); for(unsigned int i = 0; i < size; ++i) { m_VertexIdList->SetId(i, 0); } float* scalarFloatData = NULL; if (this->m_IplScalarImage) // if scalar image is defined use it for texturing { scalarFloatData = (float*)this->m_IplScalarImage->imageData; } else if (this->GetInput(m_TextureIndex)) // otherwise use intensity image (input(2)) { ImageReadAccessor inputAcc(this->GetInput(m_TextureIndex)); scalarFloatData = (float*)inputAcc.GetData(); } ImageReadAccessor inputAcc(input, input->GetSliceData(0,0,0)); float* inputFloatData = (float*)inputAcc.GetData(); //calculate world coordinates mitk::ToFProcessingCommon::ToFPoint2D focalLengthInPixelUnits; mitk::ToFProcessingCommon::ToFScalarType focalLengthInMm; if((m_ReconstructionMode == WithOutInterPixelDistance) || (m_ReconstructionMode == Kinect)) { focalLengthInPixelUnits[0] = m_CameraIntrinsics->GetFocalLengthX(); focalLengthInPixelUnits[1] = m_CameraIntrinsics->GetFocalLengthY(); } else if( m_ReconstructionMode == WithInterPixelDistance) { //convert focallength from pixel to mm focalLengthInMm = (m_CameraIntrinsics->GetFocalLengthX()*m_InterPixelDistance[0]+m_CameraIntrinsics->GetFocalLengthY()*m_InterPixelDistance[1])/2.0; } mitk::ToFProcessingCommon::ToFPoint2D principalPoint; principalPoint[0] = m_CameraIntrinsics->GetPrincipalPointX(); principalPoint[1] = m_CameraIntrinsics->GetPrincipalPointY(); mitk::Point3D origin = input->GetGeometry()->GetOrigin(); for (int j=0; jInsertPoint(pixelID, cartesianCoordinates.GetDataPointer()). //If we use points->InsertNextPoint(...) instead, the ID's do not //correspond to the image pixel ID's. Thus, we have to save them //in the vertexIdList. m_VertexIdList->SetId(pixelID, points->InsertNextPoint(cartesianCoordinates.GetDataPointer())); if (m_GenerateTriangularMesh) { if((i >= 1) && (j >= 1)) { //This little piece of art explains the ID's: // // P(x_1y_1)---P(xy_1) // | | // | | // | | // P(x_1y)-----P(xy) // //We can only start triangulation if we are at vertex (1,1), //because we need the other 3 vertices near this one. //To go one pixel line back in the image array, we have to //subtract 1x xDimension. vtkIdType xy = pixelID; vtkIdType x_1y = pixelID-1; vtkIdType xy_1 = pixelID-xDimension; vtkIdType x_1y_1 = xy_1-1; //Find the corresponding vertex ID's in the saved vertexIdList: vtkIdType xyV = m_VertexIdList->GetId(xy); vtkIdType x_1yV = m_VertexIdList->GetId(x_1y); vtkIdType xy_1V = m_VertexIdList->GetId(xy_1); vtkIdType x_1y_1V = m_VertexIdList->GetId(x_1y_1); - if (isPointValid[xy]&&isPointValid[x_1y]&&isPointValid[x_1y_1]&&isPointValid[xy_1]) // check if points of cell are valid { double pointXY[3], pointX_1Y[3], pointXY_1[3], pointX_1Y_1[3]; points->GetPoint(xyV, pointXY); points->GetPoint(x_1yV, pointX_1Y); points->GetPoint(xy_1V, pointXY_1); points->GetPoint(x_1y_1V, pointX_1Y_1); - if( (m_TriangulationThreshold == -1.0) || ((vtkMath::Distance2BetweenPoints(pointXY, pointX_1Y) <= m_TriangulationThreshold) - && (vtkMath::Distance2BetweenPoints(pointXY, pointXY_1) <= m_TriangulationThreshold) - && (vtkMath::Distance2BetweenPoints(pointX_1Y, pointX_1Y_1) <= m_TriangulationThreshold) - && (vtkMath::Distance2BetweenPoints(pointXY_1, pointX_1Y_1) <= m_TriangulationThreshold))) + if( (mitk::Equal(m_TriangulationThreshold, 0.0)) || ((vtkMath::Distance2BetweenPoints(pointXY, pointX_1Y) <= m_TriangulationThreshold) + && (vtkMath::Distance2BetweenPoints(pointXY, pointXY_1) <= m_TriangulationThreshold) + && (vtkMath::Distance2BetweenPoints(pointX_1Y, pointX_1Y_1) <= m_TriangulationThreshold) + && (vtkMath::Distance2BetweenPoints(pointXY_1, pointX_1Y_1) <= m_TriangulationThreshold))) { polys->InsertNextCell(3); polys->InsertCellPoint(x_1yV); polys->InsertCellPoint(xyV); polys->InsertCellPoint(x_1y_1V); polys->InsertNextCell(3); polys->InsertCellPoint(x_1y_1V); polys->InsertCellPoint(xyV); polys->InsertCellPoint(xy_1V); } else { //We dont want triangulation, but we want to keep the vertex vertices->InsertNextCell(1); vertices->InsertCellPoint(xyV); } } + + //Scalar values are necessary for mapping colors/texture onto the surface + if (scalarFloatData) + { + scalarArray->InsertTuple1(m_VertexIdList->GetId(pixelID), scalarFloatData[pixelID]); + } + //These Texture Coordinates will map color pixel and vertices 1:1 (e.g. for Kinect). + float xNorm = (((float)i)/xDimension);// correct video texture scale for kinect + float yNorm = ((float)j)/yDimension; //don't flip. we don't need to flip. + textureCoords->InsertTuple2(m_VertexIdList->GetId(pixelID), xNorm, yNorm); } - else - { - vertices->InsertNextCell(1); - vertices->InsertCellPoint(m_VertexIdList->GetId(pixelID)); - } - //Scalar values are necessary for mapping colors/texture onto the surface - if (scalarFloatData) - { - scalarArray->InsertTuple1(m_VertexIdList->GetId(pixelID), scalarFloatData[pixelID]); - } - //These Texture Coordinates will map color pixel and vertices 1:1 (e.g. for Kinect). - float xNorm = (((float)i)/xDimension);// correct video texture scale for kinect - float yNorm = ((float)j)/yDimension; //don't flip. we don't need to flip. - textureCoords->InsertTuple2(m_VertexIdList->GetId(pixelID), xNorm, yNorm); + } + else + { + //We dont want triangulation, we only want vertices + vertices->InsertNextCell(1); + vertices->InsertCellPoint(m_VertexIdList->GetId(pixelID)); } } } + } - vtkSmartPointer mesh = vtkSmartPointer::New(); - mesh->SetPoints(points); - mesh->SetPolys(polys); - mesh->SetVerts(vertices); - //Pass the scalars to the polydata (if they were set). - if (scalarArray->GetNumberOfTuples()>0) - { - mesh->GetPointData()->SetScalars(scalarArray); - } - //Pass the TextureCoords to the polydata anyway (to save them). - mesh->GetPointData()->SetTCoords(textureCoords); - output->SetVtkPolyData(mesh); + vtkSmartPointer mesh = vtkSmartPointer::New(); + mesh->SetPoints(points); + mesh->SetPolys(polys); + mesh->SetVerts(vertices); + //Pass the scalars to the polydata (if they were set). + if (scalarArray->GetNumberOfTuples()>0) + { + mesh->GetPointData()->SetScalars(scalarArray); } + //Pass the TextureCoords to the polydata anyway (to save them). + mesh->GetPointData()->SetTCoords(textureCoords); + output->SetVtkPolyData(mesh); } void mitk::ToFDistanceImageToSurfaceFilter::CreateOutputsForAllInputs() { this->SetNumberOfOutputs(this->GetNumberOfInputs()); // create outputs for all inputs for (unsigned int idx = 0; idx < this->GetNumberOfOutputs(); ++idx) if (this->GetOutput(idx) == NULL) { DataObjectPointer newOutput = this->MakeOutput(idx); this->SetNthOutput(idx, newOutput); } this->Modified(); } void mitk::ToFDistanceImageToSurfaceFilter::GenerateOutputInformation() { this->GetOutput(); itkDebugMacro(<<"GenerateOutputInformation()"); } void mitk::ToFDistanceImageToSurfaceFilter::SetScalarImage(IplImage* iplScalarImage) { this->m_IplScalarImage = iplScalarImage; this->Modified(); } IplImage* mitk::ToFDistanceImageToSurfaceFilter::GetScalarImage() { return this->m_IplScalarImage; } void mitk::ToFDistanceImageToSurfaceFilter::SetTextureImageWidth(int width) { this->m_TextureImageWidth = width; } void mitk::ToFDistanceImageToSurfaceFilter::SetTextureImageHeight(int height) { this->m_TextureImageHeight = height; } void mitk::ToFDistanceImageToSurfaceFilter::SetTriangulationThreshold(double triangulationThreshold) { //vtkMath::Distance2BetweenPoints returns the squared distance between two points and //hence we square m_TriangulationThreshold in order to save run-time. this->m_TriangulationThreshold = triangulationThreshold*triangulationThreshold; } diff --git a/Modules/ToFUI/Qmitk/QmitkToFConnectionWidget.cpp b/Modules/ToFUI/Qmitk/QmitkToFConnectionWidget.cpp index 1c54f3269c..6fd0be11bc 100644 --- a/Modules/ToFUI/Qmitk/QmitkToFConnectionWidget.cpp +++ b/Modules/ToFUI/Qmitk/QmitkToFConnectionWidget.cpp @@ -1,381 +1,381 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ //#define _USE_MATH_DEFINES #include //QT headers #include #include #include //mitk headers #include "mitkToFConfig.h" #include "mitkCameraIntrinsics.h" #include "mitkCameraIntrinsicsProperty.h" //itk headers #include //Setting the View_ID const std::string QmitkToFConnectionWidget::VIEW_ID = "org.mitk.views.qmitktofconnectionwidget2"; //Constructor of QmitkToFConnectionWidget QmitkToFConnectionWidget::QmitkToFConnectionWidget(QWidget* parent, Qt::WindowFlags f): QWidget(parent, f) , m_Controls(NULL) , m_IntegrationTime(0) , m_ModulationFrequency(0) , m_SelectedCameraName("") { this->m_ToFImageGrabber = mitk::ToFImageGrabber::New(); //Calling CreateQtPartControl CreateQtPartControl(this); } //Destructor of QmitkToFConnectionWidget QmitkToFConnectionWidget::~QmitkToFConnectionWidget() { //MitkServiceListWidget must not be deinizialized here. Qmitk methods destroy their children automatically before self-destruction } void QmitkToFConnectionWidget::CreateQtPartControl(QWidget *parent) //Definition of CreateQtPartControll-Methode in QmitkToFConnectionWidget; Input= Pointer { if (!m_Controls) //Define if not alreaddy exists { // create GUI widgets m_Controls = new Ui::QmitkToFConnectionWidgetControls2; m_Controls->setupUi(parent); //and hide them on startup this->HideAllParameterWidgets(); // initzializing MitkServiceListWidget here std::string empty= ""; m_Controls->m_DeviceList->Initialize("ToFDeviceName", empty);// the empty could just be any kind of filter this->CreateConnections(); } } //Creating the SIGNAL-SLOT-Connectuions void QmitkToFConnectionWidget::CreateConnections() { if ( m_Controls ) { //ConnectCameraButton as a trigger for OnConnectCamera() connect( (QObject*)(m_Controls->m_ConnectCameraButton), SIGNAL(clicked()),(QObject*) this, SLOT(OnConnectCamera()) ); //QmitkServiceListWidget::ServiceSelectionChanged as a Signal for the OnSlectCamera() slot - connect( m_Controls->m_DeviceList, SIGNAL(ServiceSelectionChanged(mitk::ServiceReference)), this, SLOT(OnSelectCamera())); + connect( m_Controls->m_DeviceList, SIGNAL(ServiceSelectionChanged(us::ServiceReferenceU)), this, SLOT(OnSelectCamera())); /*Creating an other Datanode structur for Kinect is done here: As soon as a Kinect is connected, the KinectParameterWidget is enabled, which can be used to trigger the KinectAcqusitionModeChanged-Method, to create a working Data-Node-structure*/ connect( m_Controls->m_KinectParameterWidget, SIGNAL(AcquisitionModeChanged()), this, SIGNAL(KinectAcquisitionModeChanged()) ); } } mitk::ToFImageGrabber::Pointer QmitkToFConnectionWidget::GetToFImageGrabber() { return m_ToFImageGrabber; } //The OnSelectCamer-Method is in charge of activating the appropiate ParameterWidgets void QmitkToFConnectionWidget::OnSelectCamera() { //Here we are getting our decvie through the QmitkServiceListWidget-Instance m_DeviceList through the GetSelectedService-Method mitk::ToFCameraDevice* device = m_Controls->m_DeviceList->GetSelectedService(); //getting the selectedCamera through a static Method used to transform the device->GetNameOfClass QString selectedCamera = QString::fromStdString(device->GetNameOfClass()); this->HideAllParameterWidgets(); //reactivating the Widgets on slecting a device if (selectedCamera.contains("PMD")) //Check if selectedCamera string contains ".." for each device { this->m_Controls->m_PMDParameterWidget->show(); //and activate the correct widget } else if (selectedCamera.contains("MESA")) { this->m_Controls->m_MESAParameterWidget->show(); } else if (selectedCamera.contains("Kinect")) { this->m_Controls->m_KinectParameterWidget->show(); } m_Controls->m_ConnectCameraButton->setEnabled(true); //ConnectCameraButton gets enabled m_SelectedCameraName = selectedCamera; emit (selectedCamera); } //This Methods hides all Widgets (later each widget is activated on its own) void QmitkToFConnectionWidget::HideAllParameterWidgets() { this->m_Controls->m_PMDParameterWidget->hide(); this->m_Controls->m_MESAParameterWidget->hide(); this->m_Controls->m_KinectParameterWidget->hide(); } //OnConnectCamera-Method; represents one of the main parts of ToFConnectionWidget2. void QmitkToFConnectionWidget::OnConnectCamera() { //After connecting a device if (m_Controls->m_ConnectCameraButton->text()=="Connect") { //Getting the device- and the slectedCamera-variables using the ServiceListWidget as we did it in the CameraSelect-Method mitk::ToFCameraDevice* device = m_Controls->m_DeviceList->GetSelectedService(); if (device) { QString tmpFileName(""); QString fileFilter(""); QString selectedCamera = QString::fromStdString(device->GetNameOfClass()); emit ToFCameraSelected(selectedCamera); //Feeding it with the Info from ServiceListWidget this->m_ToFImageGrabber->SetCameraDevice(device); // Calling Alex FixForKinect, if the Kinect is selected if (selectedCamera.contains("Kinect") ) { MITK_INFO<< "Kinect is connected here"; //If the particular property is selected, the suitable data-node will be generated this->m_ToFImageGrabber->SetBoolProperty("RGB", m_Controls->m_KinectParameterWidget->IsAcquisitionModeRGB());//-------------------------------------------------------- this->m_ToFImageGrabber->SetBoolProperty("IR", m_Controls->m_KinectParameterWidget->IsAcquisitionModeIR()); } //Activation of "PlayerMode". If the selectedCamera String contains "Player", we start the Player Mode if (selectedCamera.contains("Player")) { //IF PMD-Player selected if (selectedCamera.contains("PMD")) { fileFilter.append("PMD Files (*.pmd)"); //And seting the corresponding fileFilter } else { fileFilter.append("NRRD Images (*.nrrd);;PIC Images - deprecated (*.pic)"); } //open a QFileDialog to chose the corresponding file from the disc tmpFileName = QFileDialog::getOpenFileName(NULL, "Play Image From...", "", fileFilter); //If no fileName is returned by the Dialog,Button and Widget have to return to default(disconnected) + Opening a MessageBox if (tmpFileName.isEmpty()) { m_Controls->m_ConnectCameraButton->setChecked(false); m_Controls->m_ConnectCameraButton->setEnabled(true); //re-enabling the ConnectCameraButton m_Controls->m_DeviceList->setEnabled(true); //Reactivating ServiceListWidget this->OnSelectCamera(); //Calling the OnSelctCamera-Method -> Hides all Widget and just activates the needed ones QMessageBox::information( this, "Template functionality", "Please select a valid image before starting some action."); return; } if(selectedCamera.contains("PMDPlayer")) //If PMD-Player is selected, set ToFImageGrabberProperty correspondingly { this->m_ToFImageGrabber->SetStringProperty("PMDFileName", tmpFileName.toStdString().c_str() ); } else //Default action { std::string msg = ""; try { //get 3 corresponding file names std::string dir = itksys::SystemTools::GetFilenamePath( tmpFileName.toStdString() ); std::string baseFilename = itksys::SystemTools::GetFilenameWithoutLastExtension( tmpFileName.toStdString() ); std::string extension = itksys::SystemTools::GetFilenameLastExtension( tmpFileName.toStdString() ); //"Incorrect format"-warning while using .nrrd or .pic files if (extension != ".pic" && extension != ".nrrd") { msg = msg + "Invalid file format, please select a \".nrrd\"-file"; throw std::logic_error(msg.c_str()); } //Checking for npos. If available, check for the Amplitude-, Intensity- and RGBImage int found = baseFilename.rfind("_DistanceImage"); //Defining "found" variable+checking if baseFilname contains "_DistanceImage". If not, found == npos(0) - if (found == std::string::npos) //If found =0 + if (found == static_cast(std::string::npos)) //If found =0 { found = baseFilename.rfind("_AmplitudeImage"); //If "_AmplitudeImage" is found, the found variable is 1-> the next if statment is false } - if (found == std::string::npos) + if (found == static_cast(std::string::npos)) { found = baseFilename.rfind("_IntensityImage"); //found = true if baseFilename cotains "_IntesityImage" } - if (found == std::string::npos) + if (found == static_cast(std::string::npos)) { found = baseFilename.rfind("_RGBImage"); } - if (found == std::string::npos) //If none of the Nodes is found, display an error + if (found == static_cast(std::string::npos)) //If none of the Nodes is found, display an error { msg = msg + "Input file name must end with \"_DistanceImage\", \"_AmplitudeImage\", \"_IntensityImage\" or \"_RGBImage\"!"; throw std::logic_error(msg.c_str()); } std::string baseFilenamePrefix = baseFilename.substr(0,found);//Set the baseFilenamePrefix as a substring from baseFilname //Set corresponding FileNames std::string distanceImageFileName = dir + "/" + baseFilenamePrefix + "_DistanceImage" + extension; //Set the name as: directory+FilenamePrefix+""+extension std::string amplitudeImageFileName = dir + "/" + baseFilenamePrefix + "_AmplitudeImage" + extension; std::string intensityImageFileName = dir + "/" + baseFilenamePrefix + "_IntensityImage" + extension; std::string rgbImageFileName = dir + "/" + baseFilenamePrefix + "_RGBImage" + extension; if (!itksys::SystemTools::FileExists(distanceImageFileName.c_str(), true)) { this->m_ToFImageGrabber->SetStringProperty("DistanceImageFileName", ""); } else { this->m_ToFImageGrabber->SetStringProperty("DistanceImageFileName", distanceImageFileName.c_str()); } if (!itksys::SystemTools::FileExists(amplitudeImageFileName.c_str(), true)) { } else { this->m_ToFImageGrabber->SetStringProperty("AmplitudeImageFileName", amplitudeImageFileName.c_str()); } if (!itksys::SystemTools::FileExists(intensityImageFileName.c_str(), true)) { this->m_ToFImageGrabber->SetStringProperty("IntensityImageFileName", ""); } else { this->m_ToFImageGrabber->SetStringProperty("IntensityImageFileName", intensityImageFileName.c_str()); } if (!itksys::SystemTools::FileExists(rgbImageFileName.c_str(), true)) { this->m_ToFImageGrabber->SetStringProperty("RGBImageFileName", ""); } else { this->m_ToFImageGrabber->SetStringProperty("RGBImageFileName", rgbImageFileName.c_str()); } } catch (std::exception &e) { MITK_ERROR << e.what(); QMessageBox::critical( this, "Error", e.what() ); m_Controls->m_ConnectCameraButton->setChecked(false); m_Controls->m_ConnectCameraButton->setEnabled(true); m_Controls->m_DeviceList->setEnabled(true); this->OnSelectCamera(); return; } } } //End "PlayerMode" //Reset the ConnectCameraButton to disconnected m_Controls->m_ConnectCameraButton->setText("Disconnect"); //if a connection could be established try { if (this->m_ToFImageGrabber->ConnectCamera()) { this->m_Controls->m_PMDParameterWidget->SetToFImageGrabber(this->m_ToFImageGrabber); this->m_Controls->m_MESAParameterWidget->SetToFImageGrabber(this->m_ToFImageGrabber); this->m_Controls->m_KinectParameterWidget->SetToFImageGrabber(this->m_ToFImageGrabber); //Activating the respective widgets if (selectedCamera.contains("PMD")) { this->m_Controls->m_PMDParameterWidget->ActivateAllParameters(); } else if (selectedCamera.contains("MESA")) { this->m_Controls->m_MESAParameterWidget->ActivateAllParameters(); } else if (selectedCamera.contains("Kinect")) { this->m_Controls->m_KinectParameterWidget->ActivateAllParameters(); } else { this->HideAllParameterWidgets(); } // send connect signal to the caller functionality emit ToFCameraConnected(); } else //##### TODO: Remove this else part once all controllers are throwing exceptions //if they cannot to any device! { //Throw an error if the Connection failed and reset the Widgets <- better catch an exception! QMessageBox::critical( this, "Error", "Connection failed. Check if you have installed the latest driver for your system." ); m_Controls->m_ConnectCameraButton->setChecked(false); m_Controls->m_ConnectCameraButton->setEnabled(true); m_Controls->m_ConnectCameraButton->setText("Connect"); m_Controls->m_DeviceList->setEnabled(true); //Reactivating ServiceListWidget this->OnSelectCamera(); return; } }catch(std::exception &e) { //catch exceptions of camera which cannot connect give a better reason QMessageBox::critical( this, "Connection failed.", e.what() ); m_Controls->m_ConnectCameraButton->setChecked(false); m_Controls->m_ConnectCameraButton->setEnabled(true); m_Controls->m_ConnectCameraButton->setText("Connect"); m_Controls->m_DeviceList->setEnabled(true); //Reactivating ServiceListWidget this->OnSelectCamera(); return; } m_Controls->m_ConnectCameraButton->setEnabled(true); // ask wether camera parameters (intrinsics, ...) should be loaded if (QMessageBox::question(this,"Camera parameters","Do you want to specify your own camera intrinsics?",QMessageBox::Yes,QMessageBox::No)==QMessageBox::Yes) { QString fileName = QFileDialog::getOpenFileName(this,"Open camera intrinsics","/","*.xml"); mitk::CameraIntrinsics::Pointer cameraIntrinsics = mitk::CameraIntrinsics::New(); cameraIntrinsics->FromXMLFile(fileName.toStdString()); this->m_ToFImageGrabber->SetProperty("CameraIntrinsics",mitk::CameraIntrinsicsProperty::New(cameraIntrinsics)); } ////Reset the status of some GUI-Elements m_Controls->m_DeviceList->setEnabled(false); //Deactivating the Instance of QmitkServiceListWidget //repaint the widget this->repaint(); } else { QMessageBox::information(this,"Camera connection","No camera selected, please select a range camera"); m_Controls->m_ConnectCameraButton->setChecked(false); } } else if (m_Controls->m_ConnectCameraButton->text()=="Disconnect") { this->m_ToFImageGrabber->StopCamera(); this->m_ToFImageGrabber->DisconnectCamera(); m_Controls->m_ConnectCameraButton->setText("Connect"); m_Controls->m_DeviceList->setEnabled(true); //Reactivating ServiceListWidget this->OnSelectCamera(); // send disconnect signal to the caller functionality emit ToFCameraDisconnected(); } } void QmitkToFConnectionWidget::ConnectCamera() { this->m_Controls->m_ConnectCameraButton->animateClick(); } diff --git a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkMeasurementView.cpp b/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkMeasurementView.cpp index d14aa0957d..d5a374f65b 100644 --- a/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkMeasurementView.cpp +++ b/Plugins/org.mitk.gui.qt.measurementtoolbox/src/internal/QmitkMeasurementView.cpp @@ -1,761 +1,822 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #define MEASUREMENT_DEBUG MITK_DEBUG("QmitkMeasurementView") << __LINE__ << ": " #include "QmitkMeasurementView.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "usModuleRegistry.h" struct QmitkPlanarFigureData { QmitkPlanarFigureData() : m_Figure(0), m_EndPlacementObserverTag(0), m_SelectObserverTag(0), m_StartInteractionObserverTag(0), m_EndInteractionObserverTag(0) { } mitk::PlanarFigure* m_Figure; unsigned int m_EndPlacementObserverTag; unsigned int m_SelectObserverTag; unsigned int m_StartInteractionObserverTag; unsigned int m_EndInteractionObserverTag; }; struct QmitkMeasurementViewData { QmitkMeasurementViewData() : m_LineCounter(0), m_PathCounter(0), m_AngleCounter(0), m_FourPointAngleCounter(0), m_EllipseCounter(0), m_RectangleCounter(0), m_PolygonCounter(0), m_UnintializedPlanarFigure(false) { } // internal vars unsigned int m_LineCounter; unsigned int m_PathCounter; unsigned int m_AngleCounter; unsigned int m_FourPointAngleCounter; unsigned int m_EllipseCounter; unsigned int m_RectangleCounter; unsigned int m_PolygonCounter; QList m_CurrentSelection; std::map m_DataNodeToPlanarFigureData; mitk::WeakPointer m_SelectedImageNode; bool m_UnintializedPlanarFigure; // WIDGETS QWidget* m_Parent; QLabel* m_SelectedImageLabel; QAction* m_DrawLine; QAction* m_DrawPath; QAction* m_DrawAngle; QAction* m_DrawFourPointAngle; QAction* m_DrawEllipse; QAction* m_DrawRectangle; QAction* m_DrawPolygon; QToolBar* m_DrawActionsToolBar; QActionGroup* m_DrawActionsGroup; QTextBrowser* m_SelectedPlanarFiguresText; QPushButton* m_CopyToClipboard; QGridLayout* m_Layout; }; const std::string QmitkMeasurementView::VIEW_ID = "org.mitk.views.measurement"; QmitkMeasurementView::QmitkMeasurementView() -: d( new QmitkMeasurementViewData ) + : d( new QmitkMeasurementViewData ) { } QmitkMeasurementView::~QmitkMeasurementView() { this->RemoveAllInteractors(); delete d; } void QmitkMeasurementView::CreateQtPartControl(QWidget* parent) { d->m_Parent = parent; // image label QLabel* selectedImageLabel = new QLabel("Reference Image: "); d->m_SelectedImageLabel = new QLabel; d->m_SelectedImageLabel->setStyleSheet("font-weight: bold;"); d->m_DrawActionsToolBar = new QToolBar; d->m_DrawActionsGroup = new QActionGroup(this); d->m_DrawActionsGroup->setExclusive(true); //# add actions MEASUREMENT_DEBUG << "Draw Line"; - QAction* currentAction = d->m_DrawActionsToolBar->addAction(QIcon( - ":/measurement/line.png"), "Draw Line"); + QAction* currentAction = d->m_DrawActionsToolBar->addAction(QIcon(":/measurement/line.png"), "Draw Line"); currentAction->setCheckable(true); d->m_DrawLine = currentAction; d->m_DrawActionsToolBar->addAction(currentAction); d->m_DrawActionsGroup->addAction(currentAction); MEASUREMENT_DEBUG << "Draw Path"; - currentAction = d->m_DrawActionsToolBar->addAction(QIcon( - ":/measurement/path.png"), "Draw Path"); + currentAction = d->m_DrawActionsToolBar->addAction(QIcon(":/measurement/path.png"), "Draw Path"); currentAction->setCheckable(true); d->m_DrawPath = currentAction; d->m_DrawActionsToolBar->addAction(currentAction); d->m_DrawActionsGroup->addAction(currentAction); MEASUREMENT_DEBUG << "Draw Angle"; - currentAction = d->m_DrawActionsToolBar->addAction(QIcon( - ":/measurement/angle.png"), "Draw Angle"); + currentAction = d->m_DrawActionsToolBar->addAction(QIcon(":/measurement/angle.png"), "Draw Angle"); currentAction->setCheckable(true); d->m_DrawAngle = currentAction; d->m_DrawActionsToolBar->addAction(currentAction); d->m_DrawActionsGroup->addAction(currentAction); MEASUREMENT_DEBUG << "Draw Four Point Angle"; - currentAction = d->m_DrawActionsToolBar->addAction(QIcon( - ":/measurement/four-point-angle.png"), "Draw Four Point Angle"); + currentAction = d->m_DrawActionsToolBar->addAction(QIcon(":/measurement/four-point-angle.png"), "Draw Four Point Angle"); currentAction->setCheckable(true); d->m_DrawFourPointAngle = currentAction; d->m_DrawActionsToolBar->addAction(currentAction); d->m_DrawActionsGroup->addAction(currentAction); MEASUREMENT_DEBUG << "Draw Circle"; - currentAction = d->m_DrawActionsToolBar->addAction(QIcon( - ":/measurement/circle.png"), "Draw Circle"); + currentAction = d->m_DrawActionsToolBar->addAction(QIcon(":/measurement/circle.png"), "Draw Circle"); currentAction->setCheckable(true); d->m_DrawEllipse = currentAction; d->m_DrawActionsToolBar->addAction(currentAction); d->m_DrawActionsGroup->addAction(currentAction); MEASUREMENT_DEBUG << "Draw Rectangle"; - currentAction = d->m_DrawActionsToolBar->addAction(QIcon( - ":/measurement/rectangle.png"), "Draw Rectangle"); + currentAction = d->m_DrawActionsToolBar->addAction(QIcon(":/measurement/rectangle.png"), "Draw Rectangle"); currentAction->setCheckable(true); d->m_DrawRectangle = currentAction; d->m_DrawActionsToolBar->addAction(currentAction); d->m_DrawActionsGroup->addAction(currentAction); MEASUREMENT_DEBUG << "Draw Polygon"; - currentAction = d->m_DrawActionsToolBar->addAction(QIcon( - ":/measurement/polygon.png"), "Draw Polygon"); + currentAction = d->m_DrawActionsToolBar->addAction(QIcon(":/measurement/polygon.png"), "Draw Polygon"); currentAction->setCheckable(true); d->m_DrawPolygon = currentAction; d->m_DrawActionsToolBar->addAction(currentAction); d->m_DrawActionsGroup->addAction(currentAction); // planar figure details text d->m_SelectedPlanarFiguresText = new QTextBrowser; // copy to clipboard button d->m_CopyToClipboard = new QPushButton("Copy to Clipboard"); d->m_Layout = new QGridLayout; d->m_Layout->addWidget(selectedImageLabel, 0, 0, 1, 1); d->m_Layout->addWidget(d->m_SelectedImageLabel, 0, 1, 1, 1); d->m_Layout->addWidget(d->m_DrawActionsToolBar, 1, 0, 1, 2); d->m_Layout->addWidget(d->m_SelectedPlanarFiguresText, 2, 0, 1, 2); d->m_Layout->addWidget(d->m_CopyToClipboard, 3, 0, 1, 2); d->m_Parent->setLayout(d->m_Layout); // create connections this->CreateConnections(); // readd interactors and observers this->AddAllInteractors(); } void QmitkMeasurementView::CreateConnections() { - QObject::connect( d->m_DrawLine, SIGNAL( triggered(bool) ) - , this, SLOT( ActionDrawLineTriggered(bool) ) ); - QObject::connect( d->m_DrawPath, SIGNAL( triggered(bool) ) - , this, SLOT( ActionDrawPathTriggered(bool) ) ); - QObject::connect( d->m_DrawAngle, SIGNAL( triggered(bool) ) - , this, SLOT( ActionDrawAngleTriggered(bool) ) ); - QObject::connect( d->m_DrawFourPointAngle, SIGNAL( triggered(bool) ) - , this, SLOT( ActionDrawFourPointAngleTriggered(bool) ) ); - QObject::connect( d->m_DrawEllipse, SIGNAL( triggered(bool) ) - , this, SLOT( ActionDrawEllipseTriggered(bool) ) ); - QObject::connect( d->m_DrawRectangle, SIGNAL( triggered(bool) ) - , this, SLOT( ActionDrawRectangleTriggered(bool) ) ); - QObject::connect( d->m_DrawPolygon, SIGNAL( triggered(bool) ) - , this, SLOT( ActionDrawPolygonTriggered(bool) ) ); - QObject::connect( d->m_CopyToClipboard, SIGNAL( clicked(bool) ) - , this, SLOT( CopyToClipboard(bool) ) ); + QObject::connect( d->m_DrawLine, SIGNAL( triggered(bool) ), this, SLOT( ActionDrawLineTriggered(bool) ) ); + QObject::connect( d->m_DrawPath, SIGNAL( triggered(bool) ), this, SLOT( ActionDrawPathTriggered(bool) ) ); + QObject::connect( d->m_DrawAngle, SIGNAL( triggered(bool) ), this, SLOT( ActionDrawAngleTriggered(bool) ) ); + QObject::connect( d->m_DrawFourPointAngle, SIGNAL( triggered(bool) ), this, SLOT( ActionDrawFourPointAngleTriggered(bool) ) ); + QObject::connect( d->m_DrawEllipse, SIGNAL( triggered(bool) ), this, SLOT( ActionDrawEllipseTriggered(bool) ) ); + QObject::connect( d->m_DrawRectangle, SIGNAL( triggered(bool) ), this, SLOT( ActionDrawRectangleTriggered(bool) ) ); + QObject::connect( d->m_DrawPolygon, SIGNAL( triggered(bool) ), this, SLOT( ActionDrawPolygonTriggered(bool) ) ); + QObject::connect( d->m_CopyToClipboard, SIGNAL( clicked(bool) ), this, SLOT( CopyToClipboard(bool) ) ); } void QmitkMeasurementView::NodeAdded( const mitk::DataNode* node ) { // add observer for selection in renderwindow mitk::PlanarFigure* figure = dynamic_cast(node->GetData()); bool isPositionMarker (false); node->GetBoolProperty("isContourMarker", isPositionMarker); if( figure && !isPositionMarker ) { MEASUREMENT_DEBUG << "figure added. will add interactor if needed."; mitk::PlanarFigureInteractor::Pointer figureInteractor = dynamic_cast(node->GetDataInteractor().GetPointer() ); mitk::DataNode* nonConstNode = const_cast( node ); if(figureInteractor.IsNull()) { figureInteractor = mitk::PlanarFigureInteractor::New(); us::Module* planarFigureModule = us::ModuleRegistry::GetModule( "PlanarFigure" ); figureInteractor->LoadStateMachine("PlanarFigureInteraction.xml", planarFigureModule ); figureInteractor->SetEventConfig( "PlanarFigureConfig.xml", planarFigureModule ); figureInteractor->SetDataNode( nonConstNode ); -// nonConstNode->SetBoolProperty( "planarfigure.isextendable", true ); + // nonConstNode->SetBoolProperty( "planarfigure.isextendable", true ); } else { // just to be sure that the interactor is not added twice - // mitk::GlobalInteraction::GetInstance()->RemoveInteractor(figureInteractor); + // mitk::GlobalInteraction::GetInstance()->RemoveInteractor(figureInteractor); } MEASUREMENT_DEBUG << "adding interactor to globalinteraction"; - // mitk::GlobalInteraction::GetInstance()->AddInteractor(figureInteractor); + // mitk::GlobalInteraction::GetInstance()->AddInteractor(figureInteractor); MEASUREMENT_DEBUG << "will now add observers for planarfigure"; QmitkPlanarFigureData data; data.m_Figure = figure; // add observer for event when figure has been placed typedef itk::SimpleMemberCommand< QmitkMeasurementView > SimpleCommandType; SimpleCommandType::Pointer initializationCommand = SimpleCommandType::New(); initializationCommand->SetCallbackFunction( this, &QmitkMeasurementView::PlanarFigureInitialized ); data.m_EndPlacementObserverTag = figure->AddObserver( mitk::EndPlacementPlanarFigureEvent(), initializationCommand ); // add observer for event when figure is picked (selected) typedef itk::MemberCommand< QmitkMeasurementView > MemberCommandType; MemberCommandType::Pointer selectCommand = MemberCommandType::New(); selectCommand->SetCallbackFunction( this, &QmitkMeasurementView::PlanarFigureSelected ); data.m_SelectObserverTag = figure->AddObserver( mitk::SelectPlanarFigureEvent(), selectCommand ); // add observer for event when interaction with figure starts SimpleCommandType::Pointer startInteractionCommand = SimpleCommandType::New(); startInteractionCommand->SetCallbackFunction( this, &QmitkMeasurementView::DisableCrosshairNavigation); data.m_StartInteractionObserverTag = figure->AddObserver( mitk::StartInteractionPlanarFigureEvent(), startInteractionCommand ); // add observer for event when interaction with figure starts SimpleCommandType::Pointer endInteractionCommand = SimpleCommandType::New(); endInteractionCommand->SetCallbackFunction( this, &QmitkMeasurementView::EnableCrosshairNavigation); data.m_EndInteractionObserverTag = figure->AddObserver( mitk::EndInteractionPlanarFigureEvent(), endInteractionCommand ); // adding to the map of tracked planarfigures d->m_DataNodeToPlanarFigureData[nonConstNode] = data; } this->CheckForTopMostVisibleImage(); } void QmitkMeasurementView::NodeChanged(const mitk::DataNode* node) { // DETERMINE IF WE HAVE TO RENEW OUR DETAILS TEXT (ANY NODE CHANGED IN OUR SELECTION?) bool renewText = false; for( int i=0; i < d->m_CurrentSelection.size(); ++i ) { if( node == d->m_CurrentSelection.at(i) ) { renewText = true; break; } } if(renewText) { MEASUREMENT_DEBUG << "Selected nodes changed. Refreshing text."; this->UpdateMeasurementText(); } this->CheckForTopMostVisibleImage(); } void QmitkMeasurementView::CheckForTopMostVisibleImage(mitk::DataNode* _NodeToNeglect) { d->m_SelectedImageNode = this->DetectTopMostVisibleImage().GetPointer(); if( d->m_SelectedImageNode.GetPointer() == _NodeToNeglect ) d->m_SelectedImageNode = 0; if( d->m_SelectedImageNode.IsNotNull() && d->m_UnintializedPlanarFigure == false ) { MEASUREMENT_DEBUG << "Reference image found"; d->m_SelectedImageLabel->setText( QString::fromStdString( d->m_SelectedImageNode->GetName() ) ); d->m_DrawActionsToolBar->setEnabled(true); MEASUREMENT_DEBUG << "Updating Measurement text"; } else { MEASUREMENT_DEBUG << "No reference image available. Will disable actions for creating new planarfigures"; if( d->m_UnintializedPlanarFigure == false ) d->m_SelectedImageLabel->setText( "No visible image available." ); d->m_DrawActionsToolBar->setEnabled(false); } } void QmitkMeasurementView::NodeRemoved(const mitk::DataNode* node) { MEASUREMENT_DEBUG << "node removed from data storage"; mitk::DataNode* nonConstNode = const_cast(node); std::map::iterator it = d->m_DataNodeToPlanarFigureData.find(nonConstNode); bool isFigureFinished = false; bool isPlaced = false; if( it != d->m_DataNodeToPlanarFigureData.end() ) { QmitkPlanarFigureData& data = it->second; // remove observers data.m_Figure->RemoveObserver( data.m_EndPlacementObserverTag ); data.m_Figure->RemoveObserver( data.m_SelectObserverTag ); data.m_Figure->RemoveObserver( data.m_StartInteractionObserverTag ); data.m_Figure->RemoveObserver( data.m_EndInteractionObserverTag ); MEASUREMENT_DEBUG << "removing from the list of tracked planar figures"; isFigureFinished = data.m_Figure->GetPropertyList()->GetBoolProperty("initiallyplaced",isPlaced); if (!isFigureFinished) { // if the property does not yet exist or is false, drop the datanode PlanarFigureInitialized(); // normally called when a figure is finished, to reset all buttons } d->m_DataNodeToPlanarFigureData.erase( it ); } mitk::TNodePredicateDataType::Pointer isPlanarFigure = mitk::TNodePredicateDataType::New(); mitk::DataStorage::SetOfObjects::ConstPointer nodes = - GetDataStorage()->GetDerivations(node,isPlanarFigure); + GetDataStorage()->GetDerivations(node,isPlanarFigure); for (unsigned int x = 0; x < nodes->size(); x++) { mitk::PlanarFigure* planarFigure = dynamic_cast (nodes->at(x)->GetData()); if (planarFigure != NULL) { isFigureFinished = planarFigure->GetPropertyList()->GetBoolProperty("initiallyplaced",isPlaced); if (!isFigureFinished) { // if the property does not yet exist or is false, drop the datanode GetDataStorage()->Remove(nodes->at(x)); if( !d->m_DataNodeToPlanarFigureData.empty() ) { std::map::iterator it2 = - d->m_DataNodeToPlanarFigureData.find(nodes->at(x)); + d->m_DataNodeToPlanarFigureData.find(nodes->at(x)); //check if returned it2 valid if( it2 != d->m_DataNodeToPlanarFigureData.end() ) { d->m_DataNodeToPlanarFigureData.erase( it2 );// removing planar figure from tracked figure list PlanarFigureInitialized(); // normally called when a figure is finished, to reset all buttons EnableCrosshairNavigation(); } } } } } this->CheckForTopMostVisibleImage(nonConstNode); } void QmitkMeasurementView::PlanarFigureSelected( itk::Object* object, const itk::EventObject& ) { MEASUREMENT_DEBUG << "planar figure " << object << " selected"; std::map::iterator it = d->m_DataNodeToPlanarFigureData.begin(); d->m_CurrentSelection.clear(); while( it != d->m_DataNodeToPlanarFigureData.end()) { mitk::DataNode* node = it->first; QmitkPlanarFigureData& data = it->second; if( data.m_Figure == object ) { MITK_DEBUG << "selected node found. enabling selection"; node->SetSelected(true); d->m_CurrentSelection.push_back( node ); } else { node->SetSelected(false); } ++it; } this->UpdateMeasurementText(); this->RequestRenderWindowUpdate(); } void QmitkMeasurementView::PlanarFigureInitialized() { MEASUREMENT_DEBUG << "planar figure initialized"; d->m_UnintializedPlanarFigure = false; d->m_DrawActionsToolBar->setEnabled(true); d->m_DrawLine->setChecked(false); d->m_DrawPath->setChecked(false); d->m_DrawAngle->setChecked(false); d->m_DrawFourPointAngle->setChecked(false); d->m_DrawEllipse->setChecked(false); d->m_DrawRectangle->setChecked(false); d->m_DrawPolygon->setChecked(false); } void QmitkMeasurementView::SetFocus() { d->m_SelectedImageLabel->setFocus(); } void QmitkMeasurementView::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*part*/, const QList &nodes) { MEASUREMENT_DEBUG << "Determine the top most visible image"; MEASUREMENT_DEBUG << "The PlanarFigure interactor will take the currently visible PlaneGeometry from the slice navigation controller"; this->CheckForTopMostVisibleImage(); MEASUREMENT_DEBUG << "refreshing selection and detailed text"; d->m_CurrentSelection = nodes; this->UpdateMeasurementText(); for( int i=d->m_CurrentSelection.size()-1; i>= 0; --i) { mitk::DataNode* node = d->m_CurrentSelection.at(i); mitk::PlanarFigure* _PlanarFigure = dynamic_cast (node->GetData()); // the last selected planar figure - if( _PlanarFigure ) + + if (_PlanarFigure && _PlanarFigure->GetGeometry2D()) { - mitk::ILinkedRenderWindowPart* linkedRenderWindow = - dynamic_cast(this->GetRenderWindowPart()); - if( linkedRenderWindow ) + + QmitkRenderWindow* selectedRenderWindow = 0; + bool PlanarFigureInitializedWindow = false; + + mitk::ILinkedRenderWindowPart* linkedRenderWindow = dynamic_cast(this->GetRenderWindowPart()); + if(! linkedRenderWindow ) { - mitk::Point3D centerP = _PlanarFigure->GetGeometry()->GetOrigin(); - linkedRenderWindow->GetQmitkRenderWindow("axial")->GetSliceNavigationController()->SelectSliceByPoint(centerP); + return; + } + + QmitkRenderWindow* RenderWindow1 = linkedRenderWindow->GetQmitkRenderWindow( "axial") ; + QmitkRenderWindow* RenderWindow2 = linkedRenderWindow->GetQmitkRenderWindow( "sagittal") ; + QmitkRenderWindow* RenderWindow3 = linkedRenderWindow->GetQmitkRenderWindow( "coronal") ; + QmitkRenderWindow* RenderWindow4 = linkedRenderWindow->GetQmitkRenderWindow( "3d") ; + + if (node->GetBoolProperty("PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, RenderWindow1->GetRenderer())) + { + selectedRenderWindow = RenderWindow1; + } + + if (!selectedRenderWindow && node->GetBoolProperty("PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, RenderWindow2->GetRenderer())) + { + selectedRenderWindow = RenderWindow2; + } + + if (!selectedRenderWindow && node->GetBoolProperty("PlanarFigureInitializedWindow", PlanarFigureInitializedWindow,RenderWindow3->GetRenderer())) + { + selectedRenderWindow = RenderWindow3; + } + + if (!selectedRenderWindow && node->GetBoolProperty("PlanarFigureInitializedWindow", PlanarFigureInitializedWindow, RenderWindow4->GetRenderer())) + { + selectedRenderWindow = RenderWindow4; + } + + const mitk::PlaneGeometry* _PlaneGeometry = dynamic_cast (_PlanarFigure->GetGeometry2D()); + + mitk::VnlVector normal = _PlaneGeometry->GetNormalVnl(); + + mitk::Geometry2D::ConstPointer worldGeometry1 = RenderWindow1->GetRenderer()->GetCurrentWorldGeometry2D(); + mitk::PlaneGeometry::ConstPointer _Plane1 = dynamic_cast( worldGeometry1.GetPointer() ); + mitk::VnlVector normal1 = _Plane1->GetNormalVnl(); + + mitk::Geometry2D::ConstPointer worldGeometry2 = RenderWindow2->GetRenderer()->GetCurrentWorldGeometry2D(); + mitk::PlaneGeometry::ConstPointer _Plane2 = dynamic_cast( worldGeometry2.GetPointer() ); + mitk::VnlVector normal2 = _Plane2->GetNormalVnl(); + + mitk::Geometry2D::ConstPointer worldGeometry3 = RenderWindow3->GetRenderer()->GetCurrentWorldGeometry2D(); + mitk::PlaneGeometry::ConstPointer _Plane3 = dynamic_cast( worldGeometry3.GetPointer() ); + mitk::VnlVector normal3 = _Plane3->GetNormalVnl(); + + normal[0] = fabs(normal[0]); normal[1] = fabs(normal[1]); normal[2] = fabs(normal[2]); + normal1[0] = fabs(normal1[0]); normal1[1] = fabs(normal1[1]); normal1[2] = fabs(normal1[2]); + normal2[0] = fabs(normal2[0]); normal2[1] = fabs(normal2[1]); normal2[2] = fabs(normal2[2]); + normal3[0] = fabs(normal3[0]); normal3[1] = fabs(normal3[1]); normal3[2] = fabs(normal3[2]); + + double ang1 = angle(normal, normal1); + double ang2 = angle(normal, normal2); + double ang3 = angle(normal, normal3); + + if(ang1 < ang2 && ang1 < ang3) + { + selectedRenderWindow = RenderWindow1; + } + else + { + if(ang2 < ang3) + { + selectedRenderWindow = RenderWindow2; + } + else + { + selectedRenderWindow = RenderWindow3; + } + } + + // re-orient view + if (selectedRenderWindow) + { + const mitk::Point3D& centerP = _PlaneGeometry->GetOrigin(); + selectedRenderWindow->GetSliceNavigationController()->ReorientSlices(centerP, _PlaneGeometry->GetNormal()); } - break; } + break; } this->RequestRenderWindowUpdate(); } void QmitkMeasurementView::ActionDrawLineTriggered(bool checked) { Q_UNUSED(checked) mitk::PlanarLine::Pointer figure = mitk::PlanarLine::New(); QString qString = QString("Line%1").arg(++d->m_LineCounter); this->AddFigureToDataStorage(figure, qString); MEASUREMENT_DEBUG << "PlanarLine initialized..."; } void QmitkMeasurementView::ActionDrawPathTriggered(bool checked) { Q_UNUSED(checked) mitk::PlanarPolygon::Pointer figure = mitk::PlanarPolygon::New(); figure->ClosedOff(); QString qString = QString("Path%1").arg(++d->m_PathCounter); mitk::DataNode::Pointer node = this->AddFigureToDataStorage(figure, qString); mitk::BoolProperty::Pointer closedProperty = mitk::BoolProperty::New( false ); node->SetProperty("ClosedPlanarPolygon", closedProperty); node->SetProperty("planarfigure.isextendable",mitk::BoolProperty::New(true)); MEASUREMENT_DEBUG << "PlanarPath initialized..."; } void QmitkMeasurementView::ActionDrawAngleTriggered(bool checked) { Q_UNUSED(checked) mitk::PlanarAngle::Pointer figure = mitk::PlanarAngle::New(); QString qString = QString("Angle%1").arg(++d->m_AngleCounter); this->AddFigureToDataStorage(figure, qString); MEASUREMENT_DEBUG << "PlanarAngle initialized..."; } void QmitkMeasurementView::ActionDrawFourPointAngleTriggered(bool checked) { Q_UNUSED(checked) mitk::PlanarFourPointAngle::Pointer figure = - mitk::PlanarFourPointAngle::New(); + mitk::PlanarFourPointAngle::New(); QString qString = QString("Four Point Angle%1").arg(++d->m_FourPointAngleCounter); this->AddFigureToDataStorage(figure, qString); MEASUREMENT_DEBUG << "PlanarFourPointAngle initialized..."; } void QmitkMeasurementView::ActionDrawEllipseTriggered(bool checked) { Q_UNUSED(checked) mitk::PlanarCircle::Pointer figure = mitk::PlanarCircle::New(); QString qString = QString("Circle%1").arg(++d->m_EllipseCounter); this->AddFigureToDataStorage(figure, qString); MEASUREMENT_DEBUG << "PlanarCircle initialized..."; } void QmitkMeasurementView::ActionDrawRectangleTriggered(bool checked) { Q_UNUSED(checked) mitk::PlanarRectangle::Pointer figure = mitk::PlanarRectangle::New(); QString qString = QString("Rectangle%1").arg(++d->m_RectangleCounter); this->AddFigureToDataStorage(figure, qString); MEASUREMENT_DEBUG << "PlanarRectangle initialized..."; } void QmitkMeasurementView::ActionDrawPolygonTriggered(bool checked) { Q_UNUSED(checked) mitk::PlanarPolygon::Pointer figure = mitk::PlanarPolygon::New(); figure->ClosedOn(); QString qString = QString("Polygon%1").arg(++d->m_PolygonCounter); mitk::DataNode::Pointer node = this->AddFigureToDataStorage(figure, qString); node->SetProperty("planarfigure.isextendable",mitk::BoolProperty::New(true)); MEASUREMENT_DEBUG << "PlanarPolygon initialized..."; } void QmitkMeasurementView::CopyToClipboard( bool checked ) { Q_UNUSED(checked) MEASUREMENT_DEBUG << "Copying current Text to clipboard..."; QString clipboardText = d->m_SelectedPlanarFiguresText->toPlainText(); QApplication::clipboard()->setText(clipboardText, QClipboard::Clipboard); } mitk::DataNode::Pointer QmitkMeasurementView::AddFigureToDataStorage( - mitk::PlanarFigure* figure, const QString& name) + mitk::PlanarFigure* figure, const QString& name) { // add as MEASUREMENT_DEBUG << "Adding new figure to datastorage..."; if( d->m_SelectedImageNode.IsNull() ) { MITK_ERROR << "No reference image available"; return 0; } mitk::DataNode::Pointer newNode = mitk::DataNode::New(); newNode->SetName(name.toStdString()); newNode->SetData(figure); // set as selected newNode->SetSelected( true ); this->GetDataStorage()->Add(newNode, d->m_SelectedImageNode); // set all others in selection as deselected for( int i=0; im_CurrentSelection.size(); ++i) d->m_CurrentSelection.at(i)->SetSelected(false); d->m_CurrentSelection.clear(); d->m_CurrentSelection.push_back( newNode ); this->UpdateMeasurementText(); this->DisableCrosshairNavigation(); d->m_DrawActionsToolBar->setEnabled(false); d->m_UnintializedPlanarFigure = true; return newNode; } void QmitkMeasurementView::UpdateMeasurementText() { d->m_SelectedPlanarFiguresText->clear(); QString infoText; QString plainInfoText; int j = 1; mitk::PlanarFigure* _PlanarFigure = 0; mitk::PlanarAngle* planarAngle = 0; mitk::PlanarFourPointAngle* planarFourPointAngle = 0; mitk::DataNode::Pointer node = 0; for (int i=0; im_CurrentSelection.size(); ++i, ++j) { plainInfoText.clear(); node = d->m_CurrentSelection.at(i); _PlanarFigure = dynamic_cast (node->GetData()); if( !_PlanarFigure ) continue; if(j>1) infoText.append("
"); infoText.append(QString("%1
").arg(QString::fromStdString( - node->GetName()))); + node->GetName()))); plainInfoText.append(QString("%1").arg(QString::fromStdString( - node->GetName()))); + node->GetName()))); planarAngle = dynamic_cast (_PlanarFigure); if(!planarAngle) { planarFourPointAngle = dynamic_cast (_PlanarFigure); } double featureQuantity = 0.0; for (unsigned int k = 0; k < _PlanarFigure->GetNumberOfFeatures(); ++k) { if ( !_PlanarFigure->IsFeatureActive( k ) ) continue; featureQuantity = _PlanarFigure->GetQuantity(k); if ((planarAngle && k == planarAngle->FEATURE_ID_ANGLE) - || (planarFourPointAngle && k == planarFourPointAngle->FEATURE_ID_ANGLE)) + || (planarFourPointAngle && k == planarFourPointAngle->FEATURE_ID_ANGLE)) featureQuantity = featureQuantity * 180 / vnl_math::pi; infoText.append( - QString("%1: %2 %3") .arg(QString( - _PlanarFigure->GetFeatureName(k))) .arg(featureQuantity, 0, 'f', - 2) .arg(QString(_PlanarFigure->GetFeatureUnit(k)))); + QString("%1: %2 %3") .arg(QString( + _PlanarFigure->GetFeatureName(k))) .arg(featureQuantity, 0, 'f', + 2) .arg(QString(_PlanarFigure->GetFeatureUnit(k)))); plainInfoText.append( - QString("\n%1: %2 %3") .arg(QString(_PlanarFigure->GetFeatureName(k))) .arg( - featureQuantity, 0, 'f', 2) .arg(QString( - _PlanarFigure->GetFeatureUnit(k)))); + QString("\n%1: %2 %3") .arg(QString(_PlanarFigure->GetFeatureName(k))) .arg( + featureQuantity, 0, 'f', 2) .arg(QString( + _PlanarFigure->GetFeatureUnit(k)))); if(k+1 != _PlanarFigure->GetNumberOfFeatures()) infoText.append("
"); } if (j != d->m_CurrentSelection.size()) infoText.append("
"); } d->m_SelectedPlanarFiguresText->setHtml(infoText); } void QmitkMeasurementView::AddAllInteractors() { MEASUREMENT_DEBUG << "Adding interactors to all planar figures"; mitk::DataStorage::SetOfObjects::ConstPointer _NodeSet = this->GetDataStorage()->GetAll(); const mitk::DataNode* node = 0; for(mitk::DataStorage::SetOfObjects::ConstIterator it=_NodeSet->Begin(); it!=_NodeSet->End() - ; it++) + ; it++) { node = const_cast(it->Value().GetPointer()); this->NodeAdded( node ); } } void QmitkMeasurementView::RemoveAllInteractors() { MEASUREMENT_DEBUG << "Removing interactors and observers from all planar figures"; mitk::DataStorage::SetOfObjects::ConstPointer _NodeSet = this->GetDataStorage()->GetAll(); const mitk::DataNode* node = 0; for(mitk::DataStorage::SetOfObjects::ConstIterator it=_NodeSet->Begin(); it!=_NodeSet->End() - ; it++) + ; it++) { node = const_cast(it->Value().GetPointer()); this->NodeRemoved( node ); } } mitk::DataNode::Pointer QmitkMeasurementView::DetectTopMostVisibleImage() { // get all images from the data storage which are not a segmentation mitk::TNodePredicateDataType::Pointer isImage = mitk::TNodePredicateDataType::New(); mitk::NodePredicateProperty::Pointer isBinary = mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(true)); mitk::NodePredicateNot::Pointer isNotBinary = mitk::NodePredicateNot::New( isBinary ); mitk::NodePredicateAnd::Pointer isNormalImage = mitk::NodePredicateAnd::New( isImage, isNotBinary ); mitk::DataStorage::SetOfObjects::ConstPointer Images = this->GetDataStorage()->GetSubset( isNormalImage ); mitk::DataNode::Pointer currentNode; int maxLayer = itk::NumericTraits::min(); // iterate over selection for (mitk::DataStorage::SetOfObjects::ConstIterator sofIt = Images->Begin(); sofIt != Images->End(); ++sofIt) { mitk::DataNode::Pointer node = sofIt->Value(); if ( node.IsNull() ) continue; if (node->IsVisible(NULL) == false) continue; // we also do not want to assign planar figures to helper objects ( even if they are of type image ) if (node->GetProperty("helper object")) continue; int layer = 0; node->GetIntProperty("layer", layer); if ( layer < maxLayer ) { continue; } else { maxLayer = layer; currentNode = node; } } return currentNode; } void QmitkMeasurementView::EnableCrosshairNavigation() { MEASUREMENT_DEBUG << "EnableCrosshairNavigation"; // enable the crosshair navigation if (mitk::ILinkedRenderWindowPart* linkedRenderWindow = dynamic_cast(this->GetRenderWindowPart())) { MEASUREMENT_DEBUG << "enabling linked navigation"; linkedRenderWindow->EnableLinkedNavigation(true); linkedRenderWindow->EnableSlicingPlanes(true); } } void QmitkMeasurementView::DisableCrosshairNavigation() { MEASUREMENT_DEBUG << "DisableCrosshairNavigation"; // disable the crosshair navigation during the drawing if (mitk::ILinkedRenderWindowPart* linkedRenderWindow = dynamic_cast(this->GetRenderWindowPart())) { MEASUREMENT_DEBUG << "disabling linked navigation"; linkedRenderWindow->EnableLinkedNavigation(false); linkedRenderWindow->EnableSlicingPlanes(false); } } diff --git a/Plugins/org.mitk.gui.qt.tofutil/src/internal/QmitkToFUtilView.cpp b/Plugins/org.mitk.gui.qt.tofutil/src/internal/QmitkToFUtilView.cpp index cb6228f053..93a022b94d 100644 --- a/Plugins/org.mitk.gui.qt.tofutil/src/internal/QmitkToFUtilView.cpp +++ b/Plugins/org.mitk.gui.qt.tofutil/src/internal/QmitkToFUtilView.cpp @@ -1,681 +1,683 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ // Blueberry #include #include #include // Qmitk #include "QmitkToFUtilView.h" #include #include // Qt #include #include //QT headers #include #include #include // MITK #include #include #include #include #include #include #include #include #include //itk headers #include // VTK #include // ITK #include #include const std::string QmitkToFUtilView::VIEW_ID = "org.mitk.views.tofutil"; //Constructor QmitkToFUtilView::QmitkToFUtilView() : QmitkAbstractView() , m_Controls(NULL), m_MultiWidget( NULL ) , m_MitkDistanceImage(NULL), m_MitkAmplitudeImage(NULL), m_MitkIntensityImage(NULL), m_Surface(NULL) , m_DistanceImageNode(NULL), m_AmplitudeImageNode(NULL), m_IntensityImageNode(NULL), m_RGBImageNode(NULL), m_SurfaceNode(NULL) , m_ToFImageRecorder(NULL), m_ToFImageGrabber(NULL), m_ToFDistanceImageToSurfaceFilter(NULL), m_ToFCompositeFilter(NULL) , m_2DDisplayCount(0) , m_RealTimeClock(NULL) , m_StepsForFramerate(100) , m_2DTimeBefore(0.0) , m_2DTimeAfter(0.0) , m_CameraIntrinsics(NULL) { this->m_Frametimer = new QTimer(this); this->m_ToFDistanceImageToSurfaceFilter = mitk::ToFDistanceImageToSurfaceFilter::New(); this->m_ToFCompositeFilter = mitk::ToFCompositeFilter::New(); this->m_ToFImageRecorder = mitk::ToFImageRecorder::New(); this->m_ToFSurfaceVtkMapper3D = mitk::ToFSurfaceVtkMapper3D::New(); } //Destructor, specifically calling OnToFCameraStopped() and OnToFCammeraDiconnected() QmitkToFUtilView::~QmitkToFUtilView() { OnToFCameraStopped(); OnToFCameraDisconnected(); } //Createing the PartControl Signal-Slot principal void QmitkToFUtilView::CreateQtPartControl( QWidget *parent ) { // build up qt view, unless already done if ( !m_Controls ) { // create GUI widgets from the Qt Designer's .ui file m_Controls = new Ui::QmitkToFUtilViewControls; m_Controls->setupUi( parent ); //Looking for Input and Defining reaction connect(m_Frametimer, SIGNAL(timeout()), this, SLOT(OnUpdateCamera())); connect( (QObject*)(m_Controls->m_ToFConnectionWidget), SIGNAL(KinectAcquisitionModeChanged()), this, SLOT(OnKinectAcquisitionModeChanged()) ); // Todo in Widget2 connect( (QObject*)(m_Controls->m_ToFConnectionWidget), SIGNAL(ToFCameraConnected()), this, SLOT(OnToFCameraConnected()) ); connect( (QObject*)(m_Controls->m_ToFConnectionWidget), SIGNAL(ToFCameraDisconnected()), this, SLOT(OnToFCameraDisconnected()) ); connect( (QObject*)(m_Controls->m_ToFConnectionWidget), SIGNAL(ToFCameraSelected(const QString)), this, SLOT(OnToFCameraSelected(const QString)) ); connect( (QObject*)(m_Controls->m_ToFRecorderWidget), SIGNAL(ToFCameraStarted()), this, SLOT(OnToFCameraStarted()) ); connect( (QObject*)(m_Controls->m_ToFRecorderWidget), SIGNAL(ToFCameraStopped()), this, SLOT(OnToFCameraStopped()) ); connect( (QObject*)(m_Controls->m_ToFRecorderWidget), SIGNAL(RecordingStarted()), this, SLOT(OnToFCameraStopped()) ); connect( (QObject*)(m_Controls->m_ToFRecorderWidget), SIGNAL(RecordingStopped()), this, SLOT(OnToFCameraStarted()) ); connect( (QObject*)(m_Controls->m_SurfaceCheckBox), SIGNAL(toggled(bool)), this, SLOT(OnSurfaceCheckboxChecked(bool)) ); connect( (QObject*)(m_Controls->m_TextureCheckBox), SIGNAL(toggled(bool)), this, SLOT(OnTextureCheckBoxChecked(bool)) ); connect( (QObject*)(m_Controls->m_KinectTextureCheckBox), SIGNAL(toggled(bool)), this, SLOT(OnKinectRGBTextureCheckBoxChecked(bool)) ); } } //SetFocus-Method -> actually seting Focus to the Recorder void QmitkToFUtilView::SetFocus() { m_Controls->m_ToFRecorderWidget->setFocus(); } //Activated-Method->Generating RenderWindow void QmitkToFUtilView::Activated() { //get the current RenderWindowPart or open a new one if there is none if(this->GetRenderWindowPart(OPEN)) { mitk::ILinkedRenderWindowPart* linkedRenderWindowPart = dynamic_cast(this->GetRenderWindowPart()); if(linkedRenderWindowPart == 0) { MITK_ERROR << "No linked StdMultiWidget avaiable!!!"; } else { linkedRenderWindowPart->EnableSlicingPlanes(false); } GetRenderWindowPart()->GetQmitkRenderWindow("axial")->GetSliceNavigationController()->SetDefaultViewDirection(mitk::SliceNavigationController::Axial); GetRenderWindowPart()->GetQmitkRenderWindow("axial")->GetSliceNavigationController()->SliceLockedOn(); GetRenderWindowPart()->GetQmitkRenderWindow("sagittal")->GetSliceNavigationController()->SetDefaultViewDirection(mitk::SliceNavigationController::Axial); GetRenderWindowPart()->GetQmitkRenderWindow("sagittal")->GetSliceNavigationController()->SliceLockedOn(); GetRenderWindowPart()->GetQmitkRenderWindow("coronal")->GetSliceNavigationController()->SetDefaultViewDirection(mitk::SliceNavigationController::Axial); GetRenderWindowPart()->GetQmitkRenderWindow("coronal")->GetSliceNavigationController()->SliceLockedOn(); this->GetRenderWindowPart()->GetRenderingManager()->InitializeViews(); this->UseToFVisibilitySettings(true); if (this->m_ToFCompositeFilter) { m_Controls->m_ToFCompositeFilterWidget->SetToFCompositeFilter(this->m_ToFCompositeFilter); } if (this->GetDataStorage()) { m_Controls->m_ToFCompositeFilterWidget->SetDataStorage(this->GetDataStorage()); } if (this->m_ToFImageGrabber.IsNull()) { m_Controls->m_ToFRecorderWidget->setEnabled(false); m_Controls->m_ToFVisualisationSettingsWidget->setEnabled(false); m_Controls->m_ToFCompositeFilterWidget->setEnabled(false); m_Controls->tofMeasurementWidget->setEnabled(false); m_Controls->SurfacePropertiesBox->setEnabled(false); } } } //ZomnnieView-Method -> Resetting GUI to default. Why not just QmitkToFUtilView()?! void QmitkToFUtilView::ActivatedZombieView(berry::IWorkbenchPartReference::Pointer /*zombieView*/) { ResetGUIToDefault(); } void QmitkToFUtilView::Deactivated() { } void QmitkToFUtilView::Visible() { } //Reset of the ToFUtilView void QmitkToFUtilView::Hidden() { ResetGUIToDefault(); } void QmitkToFUtilView::OnToFCameraConnected() { MITK_DEBUG <<"OnToFCameraConnected"; this->m_2DDisplayCount = 0; this->m_ToFImageGrabber = m_Controls->m_ToFConnectionWidget->GetToFImageGrabber(); // initialize surface generation this->m_ToFDistanceImageToSurfaceFilter = mitk::ToFDistanceImageToSurfaceFilter::New(); this->m_ToFSurfaceVtkMapper3D = mitk::ToFSurfaceVtkMapper3D::New(); // initialize ToFImageRecorder and ToFRecorderWidget this->m_ToFImageRecorder = mitk::ToFImageRecorder::New(); this->m_ToFImageRecorder->SetCameraDevice(this->m_ToFImageGrabber->GetCameraDevice()); m_Controls->m_ToFRecorderWidget->SetParameter(this->m_ToFImageGrabber, this->m_ToFImageRecorder); m_Controls->m_ToFRecorderWidget->setEnabled(true); m_Controls->m_ToFRecorderWidget->ResetGUIToInitial(); m_Controls->m_ToFVisualisationSettingsWidget->setEnabled(false); // initialize ToFCompositeFilterWidget this->m_ToFCompositeFilter = mitk::ToFCompositeFilter::New(); if (this->m_ToFCompositeFilter) { m_Controls->m_ToFCompositeFilterWidget->SetToFCompositeFilter(this->m_ToFCompositeFilter); } if (this->GetDataStorage()) { m_Controls->m_ToFCompositeFilterWidget->SetDataStorage(this->GetDataStorage()); } // initialize measurement widget m_Controls->tofMeasurementWidget->InitializeWidget(this->GetRenderWindowPart()->GetQmitkRenderWindows(),this->GetDataStorage(), this->m_ToFDistanceImageToSurfaceFilter->GetCameraIntrinsics()); this->m_RealTimeClock = mitk::RealTimeClock::New(); this->m_2DTimeBefore = this->m_RealTimeClock->GetCurrentStamp(); this->RequestRenderWindowUpdate(); } void QmitkToFUtilView::ResetGUIToDefault() { if(this->GetRenderWindowPart()) { mitk::ILinkedRenderWindowPart* linkedRenderWindowPart = dynamic_cast(this->GetRenderWindowPart()); if(linkedRenderWindowPart == 0) { MITK_ERROR << "No linked StdMultiWidget avaiable!!!"; } else { linkedRenderWindowPart->EnableSlicingPlanes(true); } GetRenderWindowPart()->GetQmitkRenderWindow("axial")->GetSliceNavigationController()->SetDefaultViewDirection(mitk::SliceNavigationController::Axial); GetRenderWindowPart()->GetQmitkRenderWindow("axial")->GetSliceNavigationController()->SliceLockedOff(); GetRenderWindowPart()->GetQmitkRenderWindow("sagittal")->GetSliceNavigationController()->SetDefaultViewDirection(mitk::SliceNavigationController::Sagittal); GetRenderWindowPart()->GetQmitkRenderWindow("sagittal")->GetSliceNavigationController()->SliceLockedOff(); GetRenderWindowPart()->GetQmitkRenderWindow("coronal")->GetSliceNavigationController()->SetDefaultViewDirection(mitk::SliceNavigationController::Frontal); GetRenderWindowPart()->GetQmitkRenderWindow("coronal")->GetSliceNavigationController()->SliceLockedOff(); this->UseToFVisibilitySettings(false); //global reinit this->GetRenderWindowPart()->GetRenderingManager()->InitializeViews(); this->RequestRenderWindowUpdate(); } } void QmitkToFUtilView::OnToFCameraDisconnected() { m_Controls->m_ToFRecorderWidget->OnStop(); m_Controls->m_ToFRecorderWidget->setEnabled(false); m_Controls->m_ToFVisualisationSettingsWidget->setEnabled(false); m_Controls->tofMeasurementWidget->setEnabled(false); m_Controls->SurfacePropertiesBox->setEnabled(false); //clean up measurement widget m_Controls->tofMeasurementWidget->CleanUpWidget(); } void QmitkToFUtilView::OnKinectAcquisitionModeChanged() { if (m_ToFCompositeFilter.IsNotNull()&&m_ToFImageGrabber.IsNotNull()) { if (m_SelectedCamera.contains("Kinect")) { if (m_ToFImageGrabber->GetBoolProperty("RGB")) { this->m_RGBImageNode = ReplaceNodeData("RGB image",this->m_ToFImageGrabber->GetOutput(3)); this->m_ToFDistanceImageToSurfaceFilter->SetInput(3,this->m_ToFImageGrabber->GetOutput(3)); } else if (m_ToFImageGrabber->GetBoolProperty("IR")) { this->m_MitkAmplitudeImage = m_ToFCompositeFilter->GetOutput(1); this->m_AmplitudeImageNode = ReplaceNodeData("Amplitude image",m_MitkAmplitudeImage); } } this->UseToFVisibilitySettings(true); } } void QmitkToFUtilView::OnToFCameraStarted() { if (m_ToFImageGrabber.IsNotNull()) { // initialize camera intrinsics if (this->m_ToFImageGrabber->GetProperty("CameraIntrinsics")) { m_CameraIntrinsics = dynamic_cast(this->m_ToFImageGrabber->GetProperty("CameraIntrinsics"))->GetValue(); MITK_INFO << m_CameraIntrinsics->ToString(); } else { m_CameraIntrinsics = NULL; MITK_ERROR << "No camera intrinsics were found!"; } // set camera intrinsics if ( m_CameraIntrinsics.IsNotNull() ) { this->m_ToFDistanceImageToSurfaceFilter->SetCameraIntrinsics(m_CameraIntrinsics); } // initial update of image grabber this->m_ToFImageGrabber->Update(); this->m_ToFCompositeFilter->SetInput(0,this->m_ToFImageGrabber->GetOutput(0)); this->m_ToFCompositeFilter->SetInput(1,this->m_ToFImageGrabber->GetOutput(1)); this->m_ToFCompositeFilter->SetInput(2,this->m_ToFImageGrabber->GetOutput(2)); // initial update of composite filter this->m_ToFCompositeFilter->Update(); this->m_MitkDistanceImage = m_ToFCompositeFilter->GetOutput(); this->m_DistanceImageNode = ReplaceNodeData("Distance image",m_MitkDistanceImage); std::string rgbFileName; m_ToFImageGrabber->GetCameraDevice()->GetStringProperty("RGBImageFileName",rgbFileName); bool hasRGBImage = false; m_ToFImageGrabber->GetCameraDevice()->GetBoolProperty("HasRGBImage",hasRGBImage); bool hasIntensityImage = false; m_ToFImageGrabber->GetCameraDevice()->GetBoolProperty("HasIntensityImage",hasIntensityImage); bool hasAmplitudeImage = false; m_ToFImageGrabber->GetCameraDevice()->GetBoolProperty("HasAmplitudeImage",hasAmplitudeImage); bool KinectReconstructionMode = false; m_ToFImageGrabber->GetCameraDevice()->GetBoolProperty("KinectReconstructionMode",KinectReconstructionMode); if(KinectReconstructionMode) { //set the reconstruction mode for kinect this->m_ToFDistanceImageToSurfaceFilter->SetReconstructionMode(mitk::ToFDistanceImageToSurfaceFilter::Kinect); } if (m_CameraIntrinsics.IsNotNull()) { m_ToFDistanceImageToSurfaceFilter->SetCameraIntrinsics(m_CameraIntrinsics); } if(hasRGBImage || (rgbFileName!="")) { if(m_ToFImageGrabber->GetBoolProperty("IR")) { this->m_MitkAmplitudeImage = m_ToFCompositeFilter->GetOutput(1); } else { this->m_RGBImageNode = ReplaceNodeData("RGB image",this->m_ToFImageGrabber->GetOutput(3)); } } else { this->m_RGBImageNode = NULL; } if(hasAmplitudeImage) { this->m_MitkAmplitudeImage = m_ToFCompositeFilter->GetOutput(1); this->m_AmplitudeImageNode = ReplaceNodeData("Amplitude image",m_MitkAmplitudeImage); } if(hasIntensityImage) { this->m_MitkIntensityImage = m_ToFCompositeFilter->GetOutput(2); this->m_IntensityImageNode = ReplaceNodeData("Intensity image",m_MitkIntensityImage); } // if ((rgbFileName!="") || hasRGBImage) // { // } // else // { // } // this->m_AmplitudeImageNode = ReplaceNodeData("Amplitude image",m_MitkAmplitudeImage); // this->m_IntensityImageNode = ReplaceNodeData("Intensity image",m_MitkIntensityImage); this->m_ToFDistanceImageToSurfaceFilter->SetInput(0,m_MitkDistanceImage); this->m_ToFDistanceImageToSurfaceFilter->SetInput(1,m_MitkAmplitudeImage); this->m_ToFDistanceImageToSurfaceFilter->SetInput(2,m_MitkIntensityImage); this->m_Surface = this->m_ToFDistanceImageToSurfaceFilter->GetOutput(0); this->m_SurfaceNode = ReplaceNodeData("Surface",m_Surface); this->UseToFVisibilitySettings(true); m_Controls->m_ToFCompositeFilterWidget->UpdateFilterParameter(); // initialize visualization widget m_Controls->m_ToFVisualisationSettingsWidget->Initialize(this->m_DistanceImageNode, this->m_AmplitudeImageNode, this->m_IntensityImageNode); // set distance image to measurement widget m_Controls->tofMeasurementWidget->SetDistanceImage(m_MitkDistanceImage); this->m_Frametimer->start(0); m_Controls->m_ToFVisualisationSettingsWidget->setEnabled(true); m_Controls->m_ToFCompositeFilterWidget->setEnabled(true); m_Controls->tofMeasurementWidget->setEnabled(true); m_Controls->SurfacePropertiesBox->setEnabled(true); if (m_Controls->m_TextureCheckBox->isChecked()) { OnTextureCheckBoxChecked(true); } if (m_Controls->m_KinectTextureCheckBox->isChecked()) { OnKinectRGBTextureCheckBoxChecked(true); } } m_Controls->m_TextureCheckBox->setEnabled(true); } void QmitkToFUtilView::OnToFCameraStopped() { m_Controls->m_ToFVisualisationSettingsWidget->setEnabled(false); m_Controls->m_ToFCompositeFilterWidget->setEnabled(false); m_Controls->SurfacePropertiesBox->setEnabled(false); this->m_Frametimer->stop(); } void QmitkToFUtilView::OnToFCameraSelected(const QString selected) { m_SelectedCamera = selected; if (selected.contains("O3D")) { MITK_INFO<<"Surface representation currently not available for CamBoard and O3. Intrinsic parameters missing."; this->m_Controls->m_SurfaceCheckBox->setEnabled(false); this->m_Controls->m_TextureCheckBox->setEnabled(false); this->m_Controls->m_KinectTextureCheckBox->setEnabled(false); this->m_Controls->m_SurfaceCheckBox->setChecked(false); this->m_Controls->m_TextureCheckBox->setChecked(false); this->m_Controls->m_KinectTextureCheckBox->setChecked(false); } else { this->m_Controls->m_SurfaceCheckBox->setEnabled(true); this->m_Controls->m_TextureCheckBox->setEnabled(true); this->m_Controls->m_KinectTextureCheckBox->setEnabled(true); } } void QmitkToFUtilView::OnSurfaceCheckboxChecked(bool checked) { if(checked) { //initialize the surface once MITK_DEBUG << "OnSurfaceCheckboxChecked true"; this->m_SurfaceNode->SetData(this->m_Surface); this->m_SurfaceNode->SetMapper(mitk::BaseRenderer::Standard3D, m_ToFSurfaceVtkMapper3D); + this->m_ToFDistanceImageToSurfaceFilter->SetTriangulationThreshold( this->m_Controls->m_TriangulationThreshold->value() ); + //we need to initialize (reinit) the surface, to make it fit into the renderwindow this->GetRenderWindowPart()->GetRenderingManager()->InitializeViews( this->m_Surface->GetTimeSlicedGeometry(), mitk::RenderingManager::REQUEST_UPDATE_3DWINDOWS, true); // correctly place the vtk camera for appropriate surface rendering vtkCamera* camera3d = GetRenderWindowPart()->GetQmitkRenderWindow("3d")->GetRenderer()->GetVtkRenderer()->GetActiveCamera(); //1m distance to camera should be a nice default value for most cameras camera3d->SetPosition(0,0,0); camera3d->SetViewUp(0,-1,0); camera3d->SetFocalPoint(0,0,1); if (this->m_CameraIntrinsics.IsNotNull()) { // compute view angle from camera intrinsics camera3d->SetViewAngle(mitk::ToFProcessingCommon::CalculateViewAngle(m_CameraIntrinsics,m_ToFImageGrabber->GetCaptureWidth())); } else { camera3d->SetViewAngle(45); } camera3d->SetClippingRange(1, 10000); } } void QmitkToFUtilView::OnUpdateCamera() { //##### Code for surface ##### if (m_Controls->m_SurfaceCheckBox->isChecked()) { // update surface m_ToFDistanceImageToSurfaceFilter->SetTextureIndex(m_Controls->m_ToFVisualisationSettingsWidget->GetSelectedImageIndex()); //if the user wants to see the texture, it has to be updated for every frame if(m_Controls->m_KinectTextureCheckBox->isChecked() && (m_SelectedCamera.contains("Kinect")) && (m_ToFImageGrabber->GetBoolProperty("RGB"))) { //remove the vtkScalarsToColors object, if there was one. this->m_ToFSurfaceVtkMapper3D->SetVtkScalarsToColors(NULL); //set RGB-iamge as texture this->m_ToFSurfaceVtkMapper3D->SetTexture((this->m_ToFImageGrabber->GetOutput(3)->GetVtkImageData())); } else { //we have to delete the texture, if there was one. this->m_ToFSurfaceVtkMapper3D->SetTexture(NULL); //get the colortransferfunction from the visualization widget this->m_ToFSurfaceVtkMapper3D->SetVtkScalarsToColors(m_Controls->m_ToFVisualisationSettingsWidget->GetSelectedColorTransferFunction()); } //update pipeline this->m_Surface->Update(); } //##### End code for surface ##### else { // update pipeline this->m_MitkDistanceImage->Update(); } this->RequestRenderWindowUpdate(); this->m_2DDisplayCount++; if ((this->m_2DDisplayCount % this->m_StepsForFramerate) == 0) { this->m_2DTimeAfter = this->m_RealTimeClock->GetCurrentStamp() - this->m_2DTimeBefore; MITK_INFO << " 2D-Display-framerate (fps): " << this->m_StepsForFramerate / (this->m_2DTimeAfter/1000); this->m_2DTimeBefore = this->m_RealTimeClock->GetCurrentStamp(); } } void QmitkToFUtilView::OnTextureCheckBoxChecked(bool checked) { if(m_SurfaceNode.IsNotNull()) { if (checked) { this->m_SurfaceNode->SetBoolProperty("scalar visibility", true); } else { this->m_SurfaceNode->SetBoolProperty("scalar visibility", false); } } } void QmitkToFUtilView::OnKinectRGBTextureCheckBoxChecked(bool checked) { if((m_SelectedCamera.contains("Kinect")) && (m_ToFImageGrabber->GetBoolProperty("RGB"))) { if (checked) { //define the dimensions of the texture this->m_ToFDistanceImageToSurfaceFilter->SetTextureImageWidth(this->m_ToFImageGrabber->GetOutput(3)->GetDimension(0)); this->m_ToFDistanceImageToSurfaceFilter->SetTextureImageHeight(this->m_ToFImageGrabber->GetOutput(3)->GetDimension(1)); } } } void QmitkToFUtilView::OnChangeCoronalWindowOutput(int index) { this->OnToFCameraStopped(); if(index == 0) { if(this->m_IntensityImageNode.IsNotNull()) this->m_IntensityImageNode->SetVisibility(false); if(this->m_RGBImageNode.IsNotNull()) this->m_RGBImageNode->SetVisibility(true); } else if(index == 1) { if(this->m_IntensityImageNode.IsNotNull()) this->m_IntensityImageNode->SetVisibility(true); if(this->m_RGBImageNode.IsNotNull()) this->m_RGBImageNode->SetVisibility(false); } this->RequestRenderWindowUpdate(); this->OnToFCameraStarted(); } mitk::DataNode::Pointer QmitkToFUtilView::ReplaceNodeData( std::string nodeName, mitk::BaseData* data ) { mitk::DataNode::Pointer node = this->GetDataStorage()->GetNamedNode(nodeName); if (node.IsNull()) { node = mitk::DataNode::New(); node->SetData(data); node->SetName(nodeName); node->SetBoolProperty("binary",false); this->GetDataStorage()->Add(node); } else { node->SetData(data); } return node; } void QmitkToFUtilView::UseToFVisibilitySettings(bool useToF) { //We need this property for every node. mitk::RenderingModeProperty::Pointer renderingModePropertyForTransferFunction = mitk::RenderingModeProperty::New(mitk::RenderingModeProperty::COLORTRANSFERFUNCTION_COLOR); // set node properties if (m_DistanceImageNode.IsNotNull()) { this->m_DistanceImageNode->SetProperty( "visible" , mitk::BoolProperty::New( true )); this->m_DistanceImageNode->SetVisibility( !useToF, mitk::BaseRenderer::GetInstance(GetRenderWindowPart()->GetQmitkRenderWindow("sagittal")->GetRenderWindow() ) ); this->m_DistanceImageNode->SetVisibility( !useToF, mitk::BaseRenderer::GetInstance(GetRenderWindowPart()->GetQmitkRenderWindow("coronal")->GetRenderWindow() ) ); this->m_DistanceImageNode->SetVisibility( !useToF, mitk::BaseRenderer::GetInstance(GetRenderWindowPart()->GetQmitkRenderWindow("3d")->GetRenderWindow() ) ); this->m_DistanceImageNode->SetProperty("Image Rendering.Mode", renderingModePropertyForTransferFunction); } if (m_AmplitudeImageNode.IsNotNull()) { if ((m_SelectedCamera.contains("Kinect"))&&(m_ToFImageGrabber->GetBoolProperty("RGB"))) { this->m_AmplitudeImageNode->SetProperty( "visible" , mitk::BoolProperty::New( false )); } else { this->m_AmplitudeImageNode->SetProperty( "visible" , mitk::BoolProperty::New( true )); } this->m_AmplitudeImageNode->SetVisibility( !useToF, mitk::BaseRenderer::GetInstance(GetRenderWindowPart()->GetQmitkRenderWindow("axial")->GetRenderWindow() ) ); this->m_AmplitudeImageNode->SetVisibility( !useToF, mitk::BaseRenderer::GetInstance(GetRenderWindowPart()->GetQmitkRenderWindow("coronal")->GetRenderWindow() ) ); this->m_AmplitudeImageNode->SetVisibility( !useToF, mitk::BaseRenderer::GetInstance(GetRenderWindowPart()->GetQmitkRenderWindow("3d")->GetRenderWindow() ) ); this->m_AmplitudeImageNode->SetProperty("Image Rendering.Mode", renderingModePropertyForTransferFunction); } if (m_IntensityImageNode.IsNotNull()) { if (m_SelectedCamera.contains("Kinect")) { this->m_IntensityImageNode->SetProperty( "visible" , mitk::BoolProperty::New( false )); } else { this->m_IntensityImageNode->SetProperty( "visible" , mitk::BoolProperty::New( true )); this->m_IntensityImageNode->SetVisibility( !useToF, mitk::BaseRenderer::GetInstance(GetRenderWindowPart()->GetQmitkRenderWindow("axial")->GetRenderWindow() ) ); this->m_IntensityImageNode->SetVisibility( !useToF, mitk::BaseRenderer::GetInstance(GetRenderWindowPart()->GetQmitkRenderWindow("sagittal")->GetRenderWindow() ) ); this->m_IntensityImageNode->SetVisibility( !useToF, mitk::BaseRenderer::GetInstance(GetRenderWindowPart()->GetQmitkRenderWindow("3d")->GetRenderWindow() ) ); this->m_IntensityImageNode->SetProperty("Image Rendering.Mode", renderingModePropertyForTransferFunction); } } if ((m_RGBImageNode.IsNotNull())) { if ((m_SelectedCamera.contains("Kinect"))&&(m_ToFImageGrabber->GetBoolProperty("IR"))) { this->m_RGBImageNode->SetProperty( "visible" , mitk::BoolProperty::New( false )); } else { this->m_RGBImageNode->SetProperty( "visible" , mitk::BoolProperty::New( true )); this->m_RGBImageNode->SetVisibility( !useToF, mitk::BaseRenderer::GetInstance(GetRenderWindowPart()->GetQmitkRenderWindow("axial")->GetRenderWindow() ) ); this->m_RGBImageNode->SetVisibility( !useToF, mitk::BaseRenderer::GetInstance(GetRenderWindowPart()->GetQmitkRenderWindow("sagittal")->GetRenderWindow() ) ); this->m_RGBImageNode->SetVisibility( !useToF, mitk::BaseRenderer::GetInstance(GetRenderWindowPart()->GetQmitkRenderWindow("3d")->GetRenderWindow() ) ); } } // initialize images if (m_MitkDistanceImage.IsNotNull()) { this->GetRenderWindowPart()->GetRenderingManager()->InitializeViews( this->m_MitkDistanceImage->GetTimeSlicedGeometry(), mitk::RenderingManager::REQUEST_UPDATE_2DWINDOWS, true); } if(this->m_SurfaceNode.IsNotNull()) { QHash renderWindowHashMap = this->GetRenderWindowPart()->GetQmitkRenderWindows(); QHashIterator i(renderWindowHashMap); while (i.hasNext()){ i.next(); this->m_SurfaceNode->SetVisibility( false, mitk::BaseRenderer::GetInstance(i.value()->GetRenderWindow()) ); } this->m_SurfaceNode->SetVisibility( true, mitk::BaseRenderer::GetInstance(GetRenderWindowPart()->GetQmitkRenderWindow("3d")->GetRenderWindow() ) ); } //disable/enable gradient background this->GetRenderWindowPart()->EnableDecorations(!useToF, QStringList(QString("background"))); if((this->m_RGBImageNode.IsNotNull())) { bool RGBImageHasDifferentResolution = false; m_ToFImageGrabber->GetCameraDevice()->GetBoolProperty("RGBImageHasDifferentResolution",RGBImageHasDifferentResolution); if(RGBImageHasDifferentResolution) { //update the display geometry by using the RBG image node. Only for renderwindow coronal mitk::RenderingManager::GetInstance()->InitializeView( GetRenderWindowPart()->GetQmitkRenderWindow("coronal")->GetRenderWindow(), this->m_RGBImageNode->GetData()->GetGeometry() ); } } } diff --git a/Plugins/org.mitk.gui.qt.tofutil/src/internal/QmitkToFUtilViewControls.ui b/Plugins/org.mitk.gui.qt.tofutil/src/internal/QmitkToFUtilViewControls.ui index fa7d74512a..0d4ba9e5c7 100644 --- a/Plugins/org.mitk.gui.qt.tofutil/src/internal/QmitkToFUtilViewControls.ui +++ b/Plugins/org.mitk.gui.qt.tofutil/src/internal/QmitkToFUtilViewControls.ui @@ -1,154 +1,171 @@ QmitkToFUtilViewControls 0 0 466 452 0 0 QmitkTemplate Qt::Vertical 20 311 true Surface false Surface true Kinect RGB Texture false Texture + + + + If this value is >0.0, a triangulation will only be applied for vertices within this threshold distance (in mm). + + + + + + + If this value is >0.0, a triangulation will only be applied for vertices within this threshold distance (in mm). + + + Triangulation Threshold + + + 0 0 0 0 true 0 0 QmitkToFRecorderWidget QWidget
QmitkToFRecorderWidget.h
1
QmitkToFVisualisationSettingsWidget QWidget
QmitkToFVisualisationSettingsWidget.h
1
QmitkToFCompositeFilterWidget QWidget
QmitkToFCompositeFilterWidget.h
1
QmitkToFPointSetWidget QWidget
QmitkToFPointSetWidget.h
1
QmitkToFConnectionWidget QWidget
QmitkToFConnectionWidget.h
1