diff --git a/CMakeExternals/CTK.cmake b/CMakeExternals/CTK.cmake index 73ed4b9f3b..48a8a05fc4 100644 --- a/CMakeExternals/CTK.cmake +++ b/CMakeExternals/CTK.cmake @@ -1,120 +1,120 @@ #----------------------------------------------------------------------------- # CTK #----------------------------------------------------------------------------- if(MITK_USE_CTK) # Sanity checks if(DEFINED CTK_DIR AND NOT EXISTS ${CTK_DIR}) message(FATAL_ERROR "CTK_DIR variable is defined but corresponds to non-existing directory") endif() set(proj CTK) set(proj_DEPENDENCIES ) set(CTK_DEPENDS ${proj}) if(NOT DEFINED CTK_DIR) - set(revision_tag d8cd14e7) + set(revision_tag abca3189) #IF(${proj}_REVISION_TAG) # SET(revision_tag ${${proj}_REVISION_TAG}) #ENDIF() set(ctk_optional_cache_args ) if(MITK_USE_Python) if(NOT MITK_USE_SYSTEM_PYTHON) list(APPEND proj_DEPENDENCIES Python) endif() list(APPEND ctk_optional_cache_args -DCTK_LIB_Scripting/Python/Widgets:BOOL=ON -DCTK_ENABLE_Python_Wrapping:BOOL=ON -DCTK_APP_ctkSimplePythonShell:BOOL=ON -DPYTHON_EXECUTABLE:FILEPATH=${PYTHON_EXECUTABLE} -DPYTHON_INCLUDE_DIR:PATH=${PYTHON_INCLUDE_DIR} -DPYTHON_INCLUDE_DIR2:PATH=${PYTHON_INCLUDE_DIR2} -DPYTHON_LIBRARY:FILEPATH=${PYTHON_LIBRARY} ) else() list(APPEND ctk_optional_cache_args -DCTK_LIB_Scripting/Python/Widgets:BOOL=OFF -DCTK_ENABLE_Python_Wrapping:BOOL=OFF -DCTK_APP_ctkSimplePythonShell:BOOL=OFF ) endif() if(MITK_USE_DCMTK) list(APPEND ctk_optional_cache_args -DDCMTK_DIR:PATH=${DCMTK_DIR} -DDCMTK_CMAKE_DEBUG_POSTFIX:STRING=d ) list(APPEND proj_DEPENDENCIES DCMTK) else() list(APPEND ctk_optional_cache_args -DDCMTK_URL:STRING=${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/CTK_DCMTK_085525e6.tar.gz ) endif() if(CTEST_USE_LAUNCHERS) list(APPEND ctk_optional_cache_args "-DCMAKE_PROJECT_${proj}_INCLUDE:FILEPATH=${CMAKE_ROOT}/Modules/CTestUseLaunchers.cmake" ) endif() set (ctk_qt_args -DCTK_QT_VERSION:STRING=${DESIRED_QT_VERSION}) if (DESIRED_QT_VERSION MATCHES "4") list(APPEND ctk_qt_args -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}) endif() FOREACH(type RUNTIME ARCHIVE LIBRARY) IF(DEFINED CTK_PLUGIN_${type}_OUTPUT_DIRECTORY) LIST(APPEND mitk_optional_cache_args -DCTK_PLUGIN_${type}_OUTPUT_DIRECTORY:PATH=${CTK_PLUGIN_${type}_OUTPUT_DIRECTORY}) ENDIF() ENDFOREACH() ExternalProject_Add(${proj} LIST_SEPARATOR ${sep} URL ${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/CTK_${revision_tag}.tar.gz - URL_MD5 2f1255494de6ae19aae3d4dc5f2ea6de + URL_MD5 3a3470976debc29e9c9d5aaae12eae1c UPDATE_COMMAND "" INSTALL_COMMAND "" CMAKE_GENERATOR ${gen} CMAKE_ARGS ${ep_common_args} ${ctk_optional_cache_args} ${ctk_qt_args} # The CTK PluginFramework cannot cope with # a non-empty CMAKE_DEBUG_POSTFIX for the plugin # libraries yet. -DCMAKE_DEBUG_POSTFIX:STRING= -DGit_EXECUTABLE:FILEPATH=${GIT_EXECUTABLE} -DGIT_EXECUTABLE:FILEPATH=${GIT_EXECUTABLE} -DCTK_LIB_CommandLineModules/Backend/LocalProcess:BOOL=ON -DCTK_LIB_CommandLineModules/Frontend/QtGui:BOOL=ON -DCTK_LIB_PluginFramework:BOOL=ON -DCTK_LIB_DICOM/Widgets:BOOL=ON -DCTK_LIB_XNAT/Core:BOOL=ON -DCTK_PLUGIN_org.commontk.eventadmin:BOOL=ON -DCTK_PLUGIN_org.commontk.configadmin:BOOL=ON -DCTK_USE_GIT_PROTOCOL:BOOL=OFF -DDCMTK_URL:STRING=${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/CTK_DCMTK_085525e6.tar.gz -DqRestAPI_URL:STRING=${MITK_THIRDPARTY_DOWNLOAD_PREFIX_URL}/qRestAPI_5f3a03b1.tar.gz CMAKE_CACHE_ARGS ${ep_common_cache_args} CMAKE_CACHE_DEFAULT_ARGS ${ep_common_cache_default_args} DEPENDS ${proj_DEPENDENCIES} ) ExternalProject_Get_Property(${proj} binary_dir) set(CTK_DIR ${binary_dir}) #set(CTK_DIR ${ep_prefix}) #mitkFunctionInstallExternalCMakeProject(${proj}) else() mitkMacroEmptyExternalProject(${proj} "${proj_DEPENDENCIES}") endif() endif() diff --git a/Modules/Segmentation/SegmentationUtilities/MorphologicalOperations/mitkMorphologicalOperations.cpp b/Modules/Segmentation/SegmentationUtilities/MorphologicalOperations/mitkMorphologicalOperations.cpp index 7c3950e752..002544b05c 100644 --- a/Modules/Segmentation/SegmentationUtilities/MorphologicalOperations/mitkMorphologicalOperations.cpp +++ b/Modules/Segmentation/SegmentationUtilities/MorphologicalOperations/mitkMorphologicalOperations.cpp @@ -1,372 +1,359 @@ /*=================================================================== 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 "mitkMorphologicalOperations.h" #include #include #include #include #include #include #include #include #include #include #include void mitk::MorphologicalOperations::Closing(mitk::Image::Pointer& image, int factor, mitk::MorphologicalOperations::StructuralElementType structuralElement) { - MITK_INFO << "Start Closing..."; + MITK_INFO << "Start Closing..."; - int timeSteps = static_cast(image->GetTimeSteps()); + int timeSteps = static_cast(image->GetTimeSteps()); - if (timeSteps > 1) - { - mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New(); - timeSelector->SetInput(image); + if (timeSteps > 1) + { + mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New(); + timeSelector->SetInput(image); - for (int t = 0; t < timeSteps; ++t) - { - MITK_INFO << " Processing time step " << t; + for (int t = 0; t < timeSteps; ++t) + { + MITK_INFO << " Processing time step " << t; - timeSelector->SetTimeNr(t); - timeSelector->Update(); + timeSelector->SetTimeNr(t); + timeSelector->Update(); - mitk::Image::Pointer img3D = timeSelector->GetOutput(); - img3D->DisconnectPipeline(); + mitk::Image::Pointer img3D = timeSelector->GetOutput(); + img3D->DisconnectPipeline(); - AccessFixedPixelTypeByItk_3(img3D, itkClosing, (unsigned char), img3D, factor, structuralElement); + AccessFixedPixelTypeByItk_3(img3D, itkClosing, (unsigned char), img3D, factor, structuralElement); - mitk::ImageReadAccessor accessor(img3D); - image->SetVolume(accessor.GetData(), t); - } - } - else - { - AccessFixedPixelTypeByItk_3(image, itkClosing, (unsigned char), image, factor, structuralElement); - } + mitk::ImageReadAccessor accessor(img3D); + image->SetVolume(accessor.GetData(), t); + } + } + else + { + AccessFixedPixelTypeByItk_3(image, itkClosing, (unsigned char), image, factor, structuralElement); + } - MITK_INFO << "Finished Closing"; + MITK_INFO << "Finished Closing"; } void mitk::MorphologicalOperations::Erode(mitk::Image::Pointer& image, int factor, mitk::MorphologicalOperations::StructuralElementType structuralElement) { - MITK_INFO << "Start Erode..."; + MITK_INFO << "Start Erode..."; - int timeSteps = static_cast(image->GetTimeSteps()); + int timeSteps = static_cast(image->GetTimeSteps()); - if (timeSteps > 1) - { - mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New(); - timeSelector->SetInput(image); + if (timeSteps > 1) + { + mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New(); + timeSelector->SetInput(image); - for (int t = 0; t < timeSteps; ++t) - { - MITK_INFO << " Processing time step " << t; + for (int t = 0; t < timeSteps; ++t) + { + MITK_INFO << " Processing time step " << t; - timeSelector->SetTimeNr(t); - timeSelector->Update(); + timeSelector->SetTimeNr(t); + timeSelector->Update(); - mitk::Image::Pointer img3D = timeSelector->GetOutput(); - img3D->DisconnectPipeline(); + mitk::Image::Pointer img3D = timeSelector->GetOutput(); + img3D->DisconnectPipeline(); - AccessFixedPixelTypeByItk_3(img3D, itkErode, (unsigned char), img3D, factor, structuralElement); + AccessFixedPixelTypeByItk_3(img3D, itkErode, (unsigned char), img3D, factor, structuralElement); - mitk::ImageReadAccessor accessor(img3D); - image->SetVolume(accessor.GetData(), t); - } - } - else - { - AccessFixedPixelTypeByItk_3(image, itkErode, (unsigned char), image, factor, structuralElement); - } + mitk::ImageReadAccessor accessor(img3D); + image->SetVolume(accessor.GetData(), t); + } + } + else + { + AccessFixedPixelTypeByItk_3(image, itkErode, (unsigned char), image, factor, structuralElement); + } - MITK_INFO << "Finished Erode"; + MITK_INFO << "Finished Erode"; } void mitk::MorphologicalOperations::Dilate(mitk::Image::Pointer& image, int factor, mitk::MorphologicalOperations::StructuralElementType structuralElement) { - MITK_INFO << "Start Dilate..."; + MITK_INFO << "Start Dilate..."; - int timeSteps = static_cast(image->GetTimeSteps()); + int timeSteps = static_cast(image->GetTimeSteps()); - if (timeSteps > 1) - { - mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New(); - timeSelector->SetInput(image); + if (timeSteps > 1) + { + mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New(); + timeSelector->SetInput(image); - for (int t = 0; t < timeSteps; ++t) - { - MITK_INFO << " Processing time step " << t; + for (int t = 0; t < timeSteps; ++t) + { + MITK_INFO << " Processing time step " << t; - timeSelector->SetTimeNr(t); - timeSelector->Update(); + timeSelector->SetTimeNr(t); + timeSelector->Update(); - mitk::Image::Pointer img3D = timeSelector->GetOutput(); - img3D->DisconnectPipeline(); + mitk::Image::Pointer img3D = timeSelector->GetOutput(); + img3D->DisconnectPipeline(); - AccessFixedPixelTypeByItk_3(img3D, itkDilate, (unsigned char), img3D, factor, structuralElement); + AccessFixedPixelTypeByItk_3(img3D, itkDilate, (unsigned char), img3D, factor, structuralElement); - mitk::ImageReadAccessor accessor(img3D); - image->SetVolume(accessor.GetData(), t); - } - } - else - { - AccessFixedPixelTypeByItk_3(image, itkDilate, (unsigned char), image, factor, structuralElement); - } + mitk::ImageReadAccessor accessor(img3D); + image->SetVolume(accessor.GetData(), t); + } + } + else + { + AccessFixedPixelTypeByItk_3(image, itkDilate, (unsigned char), image, factor, structuralElement); + } - MITK_INFO << "Finished Dilate"; + MITK_INFO << "Finished Dilate"; } void mitk::MorphologicalOperations::Opening(mitk::Image::Pointer& image, int factor, mitk::MorphologicalOperations::StructuralElementType structuralElement) { - MITK_INFO << "Start Opening..."; + MITK_INFO << "Start Opening..."; - int timeSteps = static_cast(image->GetTimeSteps()); + int timeSteps = static_cast(image->GetTimeSteps()); - if (timeSteps > 1) - { - mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New(); - timeSelector->SetInput(image); + if (timeSteps > 1) + { + mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New(); + timeSelector->SetInput(image); - for (int t = 0; t < timeSteps; ++t) - { - MITK_INFO << " Processing time step " << t; + for (int t = 0; t < timeSteps; ++t) + { + MITK_INFO << " Processing time step " << t; - timeSelector->SetTimeNr(t); - timeSelector->Update(); + timeSelector->SetTimeNr(t); + timeSelector->Update(); - mitk::Image::Pointer img3D = timeSelector->GetOutput(); - img3D->DisconnectPipeline(); + mitk::Image::Pointer img3D = timeSelector->GetOutput(); + img3D->DisconnectPipeline(); - AccessFixedPixelTypeByItk_3(img3D, itkOpening, (unsigned char), img3D, factor, structuralElement); + AccessFixedPixelTypeByItk_3(img3D, itkOpening, (unsigned char), img3D, factor, structuralElement); - mitk::ImageReadAccessor accessor(img3D); - image->SetVolume(accessor.GetData(), t); - } - } - else - { - AccessFixedPixelTypeByItk_3(image, itkOpening, (unsigned char), image, factor, structuralElement); - } + mitk::ImageReadAccessor accessor(img3D); + image->SetVolume(accessor.GetData(), t); + } + } + else + { + AccessFixedPixelTypeByItk_3(image, itkOpening, (unsigned char), image, factor, structuralElement); + } - MITK_INFO << "Finished Opening"; + MITK_INFO << "Finished Opening"; } void mitk::MorphologicalOperations::FillHoles(mitk::Image::Pointer &image) { - MITK_INFO << "Start FillHole..."; + MITK_INFO << "Start FillHole..."; - int timeSteps = static_cast(image->GetTimeSteps()); + int timeSteps = static_cast(image->GetTimeSteps()); - if (timeSteps > 1) - { - mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New(); - timeSelector->SetInput(image); + if (timeSteps > 1) + { + mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New(); + timeSelector->SetInput(image); - for (int t = 0; t < timeSteps; ++t) - { - MITK_INFO << " Processing time step " << t; + for (int t = 0; t < timeSteps; ++t) + { + MITK_INFO << " Processing time step " << t; - timeSelector->SetTimeNr(t); - timeSelector->Update(); + timeSelector->SetTimeNr(t); + timeSelector->Update(); - mitk::Image::Pointer img3D = timeSelector->GetOutput(); - img3D->DisconnectPipeline(); + mitk::Image::Pointer img3D = timeSelector->GetOutput(); + img3D->DisconnectPipeline(); - AccessFixedPixelTypeByItk_1(img3D, itkFillHoles, (unsigned char), img3D); + AccessFixedPixelTypeByItk_1(img3D, itkFillHoles, (unsigned char), img3D); - mitk::ImageReadAccessor accessor(img3D); - image->SetVolume(accessor.GetData(), t); - } - } - else - { - AccessFixedPixelTypeByItk_1(image, itkFillHoles, (unsigned char), image); - } + mitk::ImageReadAccessor accessor(img3D); + image->SetVolume(accessor.GetData(), t); + } + } + else + { + AccessFixedPixelTypeByItk_1(image, itkFillHoles, (unsigned char), image); + } - MITK_INFO << "Finished FillHole"; + MITK_INFO << "Finished FillHole"; } template -void mitk::MorphologicalOperations::itkClosing(itk::Image* sourceImage, mitk::Image::Pointer& resultImage, int factor, mitk::MorphologicalOperations::StructuralElementType structuralElement) +void mitk::MorphologicalOperations::itkClosing(itk::Image* sourceImage, mitk::Image::Pointer& resultImage, int factor, mitk::MorphologicalOperations::StructuralElementType structuralElementFlags) { - typedef itk::Image ImageType; - typedef itk::BinaryBallStructuringElement BallType; - typedef itk::BinaryCrossStructuringElement CrossType; - typedef typename itk::BinaryMorphologicalClosingImageFilter BallClosingFilterType; - typedef typename itk::BinaryMorphologicalClosingImageFilter CrossClosingFilterType; - - if (structuralElement == Ball) - { - BallType ball; - ball.SetRadius(factor); - ball.CreateStructuringElement(); - - typename BallClosingFilterType::Pointer closingFilter = BallClosingFilterType::New(); - closingFilter->SetKernel(ball); - closingFilter->SetInput(sourceImage); - closingFilter->SetForegroundValue(1); - closingFilter->UpdateLargestPossibleRegion(); - - mitk::CastToMitkImage(closingFilter->GetOutput(), resultImage); - } - else - { - CrossType cross; - cross.CreateStructuringElement(); - - typename CrossClosingFilterType::Pointer closingFilter = CrossClosingFilterType::New(); - closingFilter->SetKernel(cross); - closingFilter->SetInput(sourceImage); - closingFilter->SetForegroundValue(1); - closingFilter->UpdateLargestPossibleRegion(); - - mitk::CastToMitkImage(closingFilter->GetOutput(), resultImage); - } + typedef itk::Image ImageType; + typedef itk::BinaryBallStructuringElement BallType; + typedef itk::BinaryCrossStructuringElement CrossType; + typedef typename itk::BinaryMorphologicalClosingImageFilter BallClosingFilterType; + typedef typename itk::BinaryMorphologicalClosingImageFilter CrossClosingFilterType; + + if (structuralElementFlags & (Ball_Axial | Ball_Coronal | Ball_Sagital)) + { + BallType ball = CreateStructuringElement(structuralElementFlags,factor); + + typename BallClosingFilterType::Pointer closingFilter = BallClosingFilterType::New(); + closingFilter->SetKernel(ball); + closingFilter->SetInput(sourceImage); + closingFilter->SetForegroundValue(1); + closingFilter->UpdateLargestPossibleRegion(); + + mitk::CastToMitkImage(closingFilter->GetOutput(), resultImage); + } + else + { + CrossType cross = CreateStructuringElement(structuralElementFlags,factor); + + typename CrossClosingFilterType::Pointer closingFilter = CrossClosingFilterType::New(); + closingFilter->SetKernel(cross); + closingFilter->SetInput(sourceImage); + closingFilter->SetForegroundValue(1); + closingFilter->UpdateLargestPossibleRegion(); + + mitk::CastToMitkImage(closingFilter->GetOutput(), resultImage); + } } template -void mitk::MorphologicalOperations::itkErode(itk::Image* sourceImage, mitk::Image::Pointer& resultImage, int factor, mitk::MorphologicalOperations::StructuralElementType structuralElement) +void mitk::MorphologicalOperations::itkErode(itk::Image* sourceImage, mitk::Image::Pointer& resultImage, int factor, mitk::MorphologicalOperations::StructuralElementType structuralElementFlags) { - typedef itk::Image ImageType; - typedef itk::BinaryBallStructuringElement BallType; - typedef itk::BinaryCrossStructuringElement CrossType; - typedef typename itk::BinaryErodeImageFilter BallErodeFilterType; - typedef typename itk::BinaryErodeImageFilter CrossErodeFilterType; - - if (structuralElement == Ball) - { - BallType ball; - ball.SetRadius(factor); - ball.CreateStructuringElement(); - - typename BallErodeFilterType::Pointer erodeFilter = BallErodeFilterType::New(); - erodeFilter->SetKernel(ball); - erodeFilter->SetInput(sourceImage); - erodeFilter->SetErodeValue(1); - erodeFilter->UpdateLargestPossibleRegion(); - - mitk::CastToMitkImage(erodeFilter->GetOutput(), resultImage); - } - else - { - CrossType cross; - cross.CreateStructuringElement(); - - typename CrossErodeFilterType::Pointer erodeFilter = CrossErodeFilterType::New(); - erodeFilter->SetKernel(cross); - erodeFilter->SetInput(sourceImage); - erodeFilter->SetErodeValue(1); - erodeFilter->UpdateLargestPossibleRegion(); - - mitk::CastToMitkImage(erodeFilter->GetOutput(), resultImage); - } + typedef itk::Image ImageType; + typedef itk::BinaryBallStructuringElement BallType; + typedef itk::BinaryCrossStructuringElement CrossType; + typedef typename itk::BinaryErodeImageFilter BallErodeFilterType; + typedef typename itk::BinaryErodeImageFilter CrossErodeFilterType; + + if (structuralElementFlags & (Ball_Axial | Ball_Coronal | Ball_Sagital)) + { + BallType ball = CreateStructuringElement(structuralElementFlags,factor); + + typename BallErodeFilterType::Pointer erodeFilter = BallErodeFilterType::New(); + erodeFilter->SetKernel(ball); + erodeFilter->SetInput(sourceImage); + erodeFilter->SetErodeValue(1); + erodeFilter->UpdateLargestPossibleRegion(); + + mitk::CastToMitkImage(erodeFilter->GetOutput(), resultImage); + } + else + { + CrossType cross = CreateStructuringElement(structuralElementFlags,factor); + + typename CrossErodeFilterType::Pointer erodeFilter = CrossErodeFilterType::New(); + erodeFilter->SetKernel(cross); + erodeFilter->SetInput(sourceImage); + erodeFilter->SetErodeValue(1); + erodeFilter->UpdateLargestPossibleRegion(); + + mitk::CastToMitkImage(erodeFilter->GetOutput(), resultImage); + } } template -void mitk::MorphologicalOperations::itkDilate(itk::Image* sourceImage, mitk::Image::Pointer& resultImage, int factor, mitk::MorphologicalOperations::StructuralElementType structuralElement) +void mitk::MorphologicalOperations::itkDilate(itk::Image* sourceImage, mitk::Image::Pointer& resultImage, int factor, mitk::MorphologicalOperations::StructuralElementType structuralElementFlags) { - typedef itk::Image ImageType; - typedef itk::BinaryBallStructuringElement BallType; - typedef itk::BinaryCrossStructuringElement CrossType; - typedef typename itk::BinaryDilateImageFilter BallDilateFilterType; - typedef typename itk::BinaryDilateImageFilter CrossDilateFilterType; - - if (structuralElement == Ball) - { - BallType ball; - ball.SetRadius(factor); - ball.CreateStructuringElement(); - - typename BallDilateFilterType::Pointer dilateFilter = BallDilateFilterType::New(); - dilateFilter->SetKernel(ball); - dilateFilter->SetInput(sourceImage); - dilateFilter->SetDilateValue(1); - dilateFilter->UpdateLargestPossibleRegion(); - - mitk::CastToMitkImage(dilateFilter->GetOutput(), resultImage); - } - else - { - CrossType cross; - cross.CreateStructuringElement(); - - typename CrossDilateFilterType::Pointer dilateFilter = CrossDilateFilterType::New(); - - dilateFilter->SetKernel(cross); - dilateFilter->SetInput(sourceImage); - dilateFilter->SetDilateValue(1); - dilateFilter->UpdateLargestPossibleRegion(); - - mitk::CastToMitkImage(dilateFilter->GetOutput(), resultImage); - } + typedef itk::Image ImageType; + typedef itk::BinaryBallStructuringElement BallType; + typedef itk::BinaryCrossStructuringElement CrossType; + typedef typename itk::BinaryDilateImageFilter BallDilateFilterType; + typedef typename itk::BinaryDilateImageFilter CrossDilateFilterType; + + if (structuralElementFlags & (Ball_Axial | Ball_Coronal | Ball_Sagital)) + { + BallType ball = CreateStructuringElement(structuralElementFlags,factor); + + typename BallDilateFilterType::Pointer dilateFilter = BallDilateFilterType::New(); + dilateFilter->SetKernel(ball); + dilateFilter->SetInput(sourceImage); + dilateFilter->SetDilateValue(1); + dilateFilter->UpdateLargestPossibleRegion(); + + mitk::CastToMitkImage(dilateFilter->GetOutput(), resultImage); + } + else + { + CrossType cross = CreateStructuringElement(structuralElementFlags,factor); + + typename CrossDilateFilterType::Pointer dilateFilter = CrossDilateFilterType::New(); + dilateFilter->SetKernel(cross); + dilateFilter->SetInput(sourceImage); + dilateFilter->SetDilateValue(1); + dilateFilter->UpdateLargestPossibleRegion(); + + mitk::CastToMitkImage(dilateFilter->GetOutput(), resultImage); + } } template -void mitk::MorphologicalOperations::itkOpening(itk::Image* sourceImage, mitk::Image::Pointer& resultImage, int factor, mitk::MorphologicalOperations::StructuralElementType structuralElement) +void mitk::MorphologicalOperations::itkOpening(itk::Image* sourceImage, mitk::Image::Pointer& resultImage, int factor, mitk::MorphologicalOperations::StructuralElementType structuralElementFlags) { - typedef itk::Image ImageType; - typedef itk::BinaryBallStructuringElement BallType; - typedef itk::BinaryCrossStructuringElement CrossType; - typedef typename itk::BinaryMorphologicalOpeningImageFilter BallOpeningFiltertype; - typedef typename itk::BinaryMorphologicalOpeningImageFilter CrossOpeningFiltertype; - - if (structuralElement == Ball) - { - BallType ball; - ball.SetRadius(factor); - ball.CreateStructuringElement(); - - typename BallOpeningFiltertype::Pointer openingFilter = BallOpeningFiltertype::New(); - openingFilter->SetKernel(ball); - openingFilter->SetInput(sourceImage); - openingFilter->SetForegroundValue(1); - openingFilter->SetBackgroundValue(0); - openingFilter->UpdateLargestPossibleRegion(); - - mitk::CastToMitkImage(openingFilter->GetOutput(), resultImage); - } - else - { - CrossType cross; - cross.CreateStructuringElement(); - - typename CrossOpeningFiltertype::Pointer openingFilter = CrossOpeningFiltertype::New(); - openingFilter->SetKernel(cross); - openingFilter->SetInput(sourceImage); - openingFilter->SetForegroundValue(1); - openingFilter->SetBackgroundValue(0); - openingFilter->UpdateLargestPossibleRegion(); - - mitk::CastToMitkImage(openingFilter->GetOutput(), resultImage); - } + typedef itk::Image ImageType; + typedef itk::BinaryBallStructuringElement BallType; + typedef itk::BinaryCrossStructuringElement CrossType; + typedef typename itk::BinaryMorphologicalOpeningImageFilter BallOpeningFiltertype; + typedef typename itk::BinaryMorphologicalOpeningImageFilter CrossOpeningFiltertype; + + if (structuralElementFlags & (Ball_Axial | Ball_Coronal | Ball_Sagital)) + { + BallType ball = CreateStructuringElement(structuralElementFlags,factor); + + typename BallOpeningFiltertype::Pointer openingFilter = BallOpeningFiltertype::New(); + openingFilter->SetKernel(ball); + openingFilter->SetInput(sourceImage); + openingFilter->SetForegroundValue(1); + openingFilter->SetBackgroundValue(0); + openingFilter->UpdateLargestPossibleRegion(); + + mitk::CastToMitkImage(openingFilter->GetOutput(), resultImage); + } + else + { + CrossType cross = CreateStructuringElement(structuralElementFlags,factor); + + typename CrossOpeningFiltertype::Pointer openingFilter = CrossOpeningFiltertype::New(); + openingFilter->SetKernel(cross); + openingFilter->SetInput(sourceImage); + openingFilter->SetForegroundValue(1); + openingFilter->SetBackgroundValue(0); + openingFilter->UpdateLargestPossibleRegion(); + + mitk::CastToMitkImage(openingFilter->GetOutput(), resultImage); + } } template void mitk::MorphologicalOperations::itkFillHoles(itk::Image* sourceImage, mitk::Image::Pointer& resultImage) { - typedef itk::Image ImageType; - typedef typename itk::BinaryFillholeImageFilter FillHoleFilterType; + typedef itk::Image ImageType; + typedef typename itk::BinaryFillholeImageFilter FillHoleFilterType; - typename FillHoleFilterType::Pointer fillHoleFilter = FillHoleFilterType::New(); - fillHoleFilter->SetInput(sourceImage); - fillHoleFilter->SetForegroundValue(1); - fillHoleFilter->UpdateLargestPossibleRegion(); + typename FillHoleFilterType::Pointer fillHoleFilter = FillHoleFilterType::New(); + fillHoleFilter->SetInput(sourceImage); + fillHoleFilter->SetForegroundValue(1); + fillHoleFilter->UpdateLargestPossibleRegion(); - mitk::CastToMitkImage(fillHoleFilter->GetOutput(), resultImage); + mitk::CastToMitkImage(fillHoleFilter->GetOutput(), resultImage); } diff --git a/Modules/Segmentation/SegmentationUtilities/MorphologicalOperations/mitkMorphologicalOperations.h b/Modules/Segmentation/SegmentationUtilities/MorphologicalOperations/mitkMorphologicalOperations.h index 118a9476d4..b8e2898028 100644 --- a/Modules/Segmentation/SegmentationUtilities/MorphologicalOperations/mitkMorphologicalOperations.h +++ b/Modules/Segmentation/SegmentationUtilities/MorphologicalOperations/mitkMorphologicalOperations.h @@ -1,70 +1,116 @@ /*=================================================================== 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 mitkMorphologicalOperations_h #define mitkMorphologicalOperations_h #include #include namespace mitk { /** \brief Encapsulates several morphological operations that can be performed on segmentations. */ class MITKSEGMENTATION_EXPORT MorphologicalOperations { public: enum StructuralElementType { - Ball, - Cross + Ball = 7, + Ball_Axial = 1, + Ball_Sagital = 2, + Ball_Coronal = 4, + + Cross = 56, + Cross_Axial = 8, + Cross_Sagital = 16, + Cross_Coronal = 32 + }; + + ///@{ /** \brief Perform morphological operation on 2D, 3D or 3D+t segmentation. */ static void Closing(mitk::Image::Pointer& image, int factor, StructuralElementType structuralElement); static void Erode(mitk::Image::Pointer& image, int factor, StructuralElementType structuralElement); static void Dilate(mitk::Image::Pointer& image, int factor, StructuralElementType structuralElement); static void Opening(mitk::Image::Pointer& image, int factor, StructuralElementType structuralElement); static void FillHoles(mitk::Image::Pointer& image); ///@} private: MorphologicalOperations(); + template + static TStructuringElement CreateStructuringElement(StructuralElementType structuralElementFlag, int factor) + { + TStructuringElement strElem; + typename TStructuringElement::SizeType size; + size.Fill(0); + switch (structuralElementFlag) { + case Ball_Axial: + case Cross_Axial: + size.SetElement(0,factor); + size.SetElement(1,factor); + break; + case Ball_Coronal: + case Cross_Coronal: + size.SetElement(1,factor); + size.SetElement(2,factor); + break; + case Ball_Sagital: + case Cross_Sagital: + size.SetElement(0,factor); + size.SetElement(2,factor); + break; + case Ball: + case Cross: + size.Fill(factor); + break; + } + + strElem.SetRadius(size); + strElem.CreateStructuringElement(); + return strElem; + } + ///@{ /** \brief Perform morphological operation by using corresponding ITK filter. */ template void static itkClosing(itk::Image* sourceImage, mitk::Image::Pointer& resultImage, int factor, StructuralElementType structuralElement); template void static itkErode(itk::Image* sourceImage, mitk::Image::Pointer& resultImage, int factor, StructuralElementType structuralElement); template void static itkDilate(itk::Image* sourceImage, mitk::Image::Pointer& resultImage, int factor, StructuralElementType structuralElement); template void static itkOpening(itk::Image* sourceImage, mitk::Image::Pointer& resultImage, int factor, StructuralElementType structuralElement); template void static itkFillHoles(itk::Image* sourceImage, mitk::Image::Pointer& resultImage); ///@} }; + } #endif + + diff --git a/Plugins/org.mitk.gui.qt.segmentation/src/internal/SegmentationUtilities/MorphologicalOperations/QmitkMorphologicalOperationsWidget.cpp b/Plugins/org.mitk.gui.qt.segmentation/src/internal/SegmentationUtilities/MorphologicalOperations/QmitkMorphologicalOperationsWidget.cpp index 9d736b3b62..46b9b4f402 100644 --- a/Plugins/org.mitk.gui.qt.segmentation/src/internal/SegmentationUtilities/MorphologicalOperations/QmitkMorphologicalOperationsWidget.cpp +++ b/Plugins/org.mitk.gui.qt.segmentation/src/internal/SegmentationUtilities/MorphologicalOperations/QmitkMorphologicalOperationsWidget.cpp @@ -1,236 +1,239 @@ /*=================================================================== 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 "QmitkMorphologicalOperationsWidget.h" -#include #include #include +#include static const char* const HelpText = "Select a segmentation above"; QmitkMorphologicalOperationsWidget::QmitkMorphologicalOperationsWidget(mitk::SliceNavigationController* timeNavigationController, QWidget* parent) : QmitkSegmentationUtilityWidget(timeNavigationController, parent) { m_Controls.setupUi(this); m_Controls.dataSelectionWidget->AddDataStorageComboBox(QmitkDataSelectionWidget::SegmentationPredicate); m_Controls.dataSelectionWidget->SetHelpText(HelpText); connect(m_Controls.btnClosing, SIGNAL(clicked()), this, SLOT(OnClosingButtonClicked())); connect(m_Controls.btnOpening, SIGNAL(clicked()), this, SLOT(OnOpeningButtonClicked())); connect(m_Controls.btnDilatation, SIGNAL(clicked()), this, SLOT(OnDilatationButtonClicked())); connect(m_Controls.btnErosion, SIGNAL(clicked()), this, SLOT(OnErosionButtonClicked())); connect(m_Controls.btnFillHoles, SIGNAL(clicked()), this, SLOT(OnFillHolesButtonClicked())); connect(m_Controls.radioButtonMorphoCross, SIGNAL(clicked()), this, SLOT(OnRadioButtonsClicked())); connect(m_Controls.radioButtonMorphoBall, SIGNAL(clicked()), this, SLOT(OnRadioButtonsClicked())); connect(m_Controls.dataSelectionWidget, SIGNAL(SelectionChanged(unsigned int, const mitk::DataNode*)), this, SLOT(OnSelectionChanged(unsigned int, const mitk::DataNode*))); if (m_Controls.dataSelectionWidget->GetSelection(0).IsNotNull()) this->OnSelectionChanged(0, m_Controls.dataSelectionWidget->GetSelection(0)); } QmitkMorphologicalOperationsWidget::~QmitkMorphologicalOperationsWidget() { } void QmitkMorphologicalOperationsWidget::OnSelectionChanged(unsigned int index, const mitk::DataNode* selection) { QmitkDataSelectionWidget* dataSelectionWidget = m_Controls.dataSelectionWidget; mitk::DataNode::Pointer node = dataSelectionWidget->GetSelection(0); if (node.IsNotNull()) { m_Controls.dataSelectionWidget->SetHelpText(""); this->EnableButtons(true); } else { m_Controls.dataSelectionWidget->SetHelpText(HelpText); this->EnableButtons(false); } } void QmitkMorphologicalOperationsWidget::EnableButtons(bool enable) { m_Controls.btnClosing->setEnabled(enable); m_Controls.btnDilatation->setEnabled(enable); m_Controls.btnErosion->setEnabled(enable); m_Controls.btnFillHoles->setEnabled(enable); m_Controls.btnOpening->setEnabled(enable); } void QmitkMorphologicalOperationsWidget::OnRadioButtonsClicked() { bool enable = m_Controls.radioButtonMorphoBall->isChecked(); m_Controls.sliderMorphFactor->setEnabled(enable); m_Controls.spinBoxMorphFactor->setEnabled(enable); } void QmitkMorphologicalOperationsWidget::OnClosingButtonClicked() { QApplication::setOverrideCursor(QCursor(Qt::BusyCursor)); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); QmitkDataSelectionWidget* dataSelectionWidget = m_Controls.dataSelectionWidget; mitk::DataNode::Pointer node = dataSelectionWidget->GetSelection(0); mitk::Image::Pointer image = static_cast(node->GetData()); - bool ball = m_Controls.radioButtonMorphoBall->isChecked(); - - mitk::MorphologicalOperations::StructuralElementType structuralElement = ball - ? mitk::MorphologicalOperations::Ball - : mitk::MorphologicalOperations::Cross; - + mitk::MorphologicalOperations::StructuralElementType structuralElement = CreateStructerElement_UI(); try { mitk::MorphologicalOperations::Closing(image, m_Controls.spinBoxMorphFactor->value(), structuralElement); } catch (const itk::ExceptionObject& exception) { MITK_WARN << "Exception caught: " << exception.GetDescription(); QApplication::restoreOverrideCursor(); return; } node->SetData(image); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); QApplication::restoreOverrideCursor(); } void QmitkMorphologicalOperationsWidget::OnOpeningButtonClicked() { QApplication::setOverrideCursor(QCursor(Qt::BusyCursor)); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); QmitkDataSelectionWidget* dataSelectionWidget = m_Controls.dataSelectionWidget; mitk::DataNode::Pointer node = dataSelectionWidget->GetSelection(0); mitk::Image::Pointer image = static_cast(node->GetData()); - bool ball = m_Controls.radioButtonMorphoBall->isChecked(); - mitk::MorphologicalOperations::StructuralElementType structuralElement = ball - ? mitk::MorphologicalOperations::Ball - : mitk::MorphologicalOperations::Cross; + mitk::MorphologicalOperations::StructuralElementType structuralElement = CreateStructerElement_UI(); try { mitk::MorphologicalOperations::Opening(image, m_Controls.spinBoxMorphFactor->value(), structuralElement); } catch (const itk::ExceptionObject& exception) { MITK_WARN << "Exception caught: " << exception.GetDescription(); QApplication::restoreOverrideCursor(); return; } node->SetData(image); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); QApplication::restoreOverrideCursor(); } void QmitkMorphologicalOperationsWidget::OnDilatationButtonClicked() { QApplication::setOverrideCursor(QCursor(Qt::BusyCursor)); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); QmitkDataSelectionWidget* dataSelectionWidget = m_Controls.dataSelectionWidget; mitk::DataNode::Pointer node = dataSelectionWidget->GetSelection(0); mitk::Image::Pointer image = static_cast(node->GetData()); - bool ball = m_Controls.radioButtonMorphoBall->isChecked(); - - mitk::MorphologicalOperations::StructuralElementType structuralElement = ball - ? mitk::MorphologicalOperations::Ball - : mitk::MorphologicalOperations::Cross; + mitk::MorphologicalOperations::StructuralElementType structuralElement = this->CreateStructerElement_UI(); try { mitk::MorphologicalOperations::Dilate(image, m_Controls.spinBoxMorphFactor->value(), structuralElement); } catch (const itk::ExceptionObject& exception) { MITK_WARN << "Exception caught: " << exception.GetDescription(); QApplication::restoreOverrideCursor(); return; } node->SetData(image); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); QApplication::restoreOverrideCursor(); } void QmitkMorphologicalOperationsWidget::OnErosionButtonClicked() { QApplication::setOverrideCursor(QCursor(Qt::BusyCursor)); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); QmitkDataSelectionWidget* dataSelectionWidget = m_Controls.dataSelectionWidget; mitk::DataNode::Pointer node = dataSelectionWidget->GetSelection(0); mitk::Image::Pointer image = static_cast(node->GetData()); - bool ball = m_Controls.radioButtonMorphoBall->isChecked(); - - mitk::MorphologicalOperations::StructuralElementType structuralElement = ball - ? mitk::MorphologicalOperations::Ball - : mitk::MorphologicalOperations::Cross; +mitk::MorphologicalOperations::StructuralElementType structuralElement = CreateStructerElement_UI(); try { mitk::MorphologicalOperations::Erode(image, m_Controls.spinBoxMorphFactor->value(), structuralElement); } catch (const itk::ExceptionObject& exception) { MITK_WARN << "Exception caught: " << exception.GetDescription(); QApplication::restoreOverrideCursor(); return; } node->SetData(image); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); QApplication::restoreOverrideCursor(); } void QmitkMorphologicalOperationsWidget::OnFillHolesButtonClicked() { QApplication::setOverrideCursor(QCursor(Qt::BusyCursor)); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); QmitkDataSelectionWidget* dataSelectionWidget = m_Controls.dataSelectionWidget; mitk::DataNode::Pointer node = dataSelectionWidget->GetSelection(0); mitk::Image::Pointer image = static_cast(node->GetData()); try { mitk::MorphologicalOperations::FillHoles(image); } catch (const itk::ExceptionObject& exception) { MITK_WARN << "Exception caught: " << exception.GetDescription(); QApplication::restoreOverrideCursor(); return; } node->SetData(image); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); QApplication::restoreOverrideCursor(); } + + +mitk::MorphologicalOperations::StructuralElementType QmitkMorphologicalOperationsWidget::CreateStructerElement_UI() +{ + bool ball = m_Controls.radioButtonMorphoBall->isChecked(); + int accum_flag = 0; + if(ball){ + if(m_Controls.planeSelectionComboBox->currentIndex() == 0) accum_flag = mitk::MorphologicalOperations::Ball; // 3D Operation + if(m_Controls.planeSelectionComboBox->currentIndex() == 1) accum_flag = mitk::MorphologicalOperations::Ball_Axial; // 2D Operation - Axial plane + if(m_Controls.planeSelectionComboBox->currentIndex() == 2) accum_flag = mitk::MorphologicalOperations::Ball_Sagital; // 2D Operation - Sagital plane + if(m_Controls.planeSelectionComboBox->currentIndex() == 3) accum_flag = mitk::MorphologicalOperations::Ball_Coronal; // 2D Operation - Coronal plane + }else{ + if(m_Controls.planeSelectionComboBox->currentIndex() == 0) accum_flag = mitk::MorphologicalOperations::Cross; + if(m_Controls.planeSelectionComboBox->currentIndex() == 1) accum_flag = mitk::MorphologicalOperations::Cross_Axial; + if(m_Controls.planeSelectionComboBox->currentIndex() == 2) accum_flag = mitk::MorphologicalOperations::Cross_Sagital; + if(m_Controls.planeSelectionComboBox->currentIndex() == 3) accum_flag = mitk::MorphologicalOperations::Cross_Coronal; + } + return (mitk::MorphologicalOperations::StructuralElementType)accum_flag; +} diff --git a/Plugins/org.mitk.gui.qt.segmentation/src/internal/SegmentationUtilities/MorphologicalOperations/QmitkMorphologicalOperationsWidget.h b/Plugins/org.mitk.gui.qt.segmentation/src/internal/SegmentationUtilities/MorphologicalOperations/QmitkMorphologicalOperationsWidget.h index 01fe747748..1de5468b13 100644 --- a/Plugins/org.mitk.gui.qt.segmentation/src/internal/SegmentationUtilities/MorphologicalOperations/QmitkMorphologicalOperationsWidget.h +++ b/Plugins/org.mitk.gui.qt.segmentation/src/internal/SegmentationUtilities/MorphologicalOperations/QmitkMorphologicalOperationsWidget.h @@ -1,49 +1,51 @@ /*=================================================================== 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 QmitkMorphologicalOperationsWidget_h #define QmitkMorphologicalOperationsWidget_h #include "../QmitkSegmentationUtilityWidget.h" #include +#include /** \brief GUI class for morphological segmentation tools. */ class QmitkMorphologicalOperationsWidget : public QmitkSegmentationUtilityWidget { Q_OBJECT public: explicit QmitkMorphologicalOperationsWidget(mitk::SliceNavigationController* timeNavigationController, QWidget* parent = NULL); ~QmitkMorphologicalOperationsWidget(); public slots: void OnClosingButtonClicked(); void OnOpeningButtonClicked(); void OnDilatationButtonClicked(); void OnErosionButtonClicked(); void OnFillHolesButtonClicked(); void OnSelectionChanged(unsigned int index, const mitk::DataNode* selection); void OnRadioButtonsClicked(); protected: void EnableButtons(bool enable); private: Ui::QmitkMorphologicalOperationsWidgetControls m_Controls; + mitk::MorphologicalOperations::StructuralElementType CreateStructerElement_UI(); }; #endif diff --git a/Plugins/org.mitk.gui.qt.segmentation/src/internal/SegmentationUtilities/MorphologicalOperations/QmitkMorphologicalOperationsWidgetControls.ui b/Plugins/org.mitk.gui.qt.segmentation/src/internal/SegmentationUtilities/MorphologicalOperations/QmitkMorphologicalOperationsWidgetControls.ui index 68af002468..d359213e4b 100644 --- a/Plugins/org.mitk.gui.qt.segmentation/src/internal/SegmentationUtilities/MorphologicalOperations/QmitkMorphologicalOperationsWidgetControls.ui +++ b/Plugins/org.mitk.gui.qt.segmentation/src/internal/SegmentationUtilities/MorphologicalOperations/QmitkMorphologicalOperationsWidgetControls.ui @@ -1,295 +1,319 @@ QmitkMorphologicalOperationsWidgetControls 0 0 263 469 Form Structuring Element Ball true Cross + + + + + 3D Operation + + + + + 2D Operation - Axial + + + + + 2D Operation - Sagital + + + + + 2D Operation - Coronal + + + + Radius 1 20 1 Qt::Horizontal 1 20 false 0 0 Dilation :/SegmentationUtilities/MorphologicalOperations/Dilate_48x48.png:/SegmentationUtilities/MorphologicalOperations/Dilate_48x48.png 32 32 Qt::ToolButtonTextUnderIcon false 0 0 Erosion :/SegmentationUtilities/MorphologicalOperations/Erode_48x48.png:/SegmentationUtilities/MorphologicalOperations/Erode_48x48.png 32 32 Qt::ToolButtonTextUnderIcon false 0 0 Closing :/SegmentationUtilities/MorphologicalOperations/Closing_48x48.png:/SegmentationUtilities/MorphologicalOperations/Closing_48x48.png 32 32 Qt::ToolButtonTextUnderIcon false 0 0 Opening :/SegmentationUtilities/MorphologicalOperations/Opening_48x48.png:/SegmentationUtilities/MorphologicalOperations/Opening_48x48.png 32 32 Qt::ToolButtonTextUnderIcon false 0 0 Globally fills holes in segmentation (radius not required) Fill Holes :/SegmentationUtilities/MorphologicalOperations/FillHoles_48x48.png:/SegmentationUtilities/MorphologicalOperations/FillHoles_48x48.png 32 32 Qt::ToolButtonTextUnderIcon Qt::Vertical 20 518 QmitkDataSelectionWidget QWidget
internal/Common/QmitkDataSelectionWidget.h
1
sliderMorphFactor valueChanged(int) spinBoxMorphFactor setValue(int) 240 27 766 36 spinBoxMorphFactor valueChanged(int) sliderMorphFactor setValue(int) 784 38 657 38