diff --git a/Modules/Segmentation/Algorithms/mitkOtsuSegmentationFilter.cpp b/Modules/Segmentation/Algorithms/mitkOtsuSegmentationFilter.cpp index 6198487307..07a63a77df 100644 --- a/Modules/Segmentation/Algorithms/mitkOtsuSegmentationFilter.cpp +++ b/Modules/Segmentation/Algorithms/mitkOtsuSegmentationFilter.cpp @@ -1,78 +1,78 @@ /*=================================================================== 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 "mitkOtsuSegmentationFilter.h" #include "mitkImageCast.h" #include "mitkImageAccessByItk.h" #include "itkOtsuMultipleThresholdsImageFilter.h" struct paramContainer { paramContainer( unsigned int numThresholds, bool useValley, unsigned int numBins, mitk::Image::Pointer image ) : m_NumberOfThresholds(numThresholds), m_ValleyEmphasis(useValley), m_NumberOfBins(numBins), m_Image(image) { } unsigned int m_NumberOfThresholds; bool m_ValleyEmphasis; unsigned int m_NumberOfBins; mitk::Image::Pointer m_Image; }; template void AccessItkOtsuFilter(itk::Image* itkImage, paramContainer params) { typedef itk::Image itkInputImageType; - typedef itk::Image< mitk::OtsuSegmentationFilter::OutputPixelType, 3 > itkOutputImageType; + typedef itk::Image< mitk::OtsuSegmentationFilter::OutputPixelType, VImageDimension > itkOutputImageType; typedef itk::OtsuMultipleThresholdsImageFilter< itkInputImageType, itkOutputImageType > OtsuFilterType; typename OtsuFilterType::Pointer filter = OtsuFilterType::New(); filter->SetNumberOfThresholds( params.m_NumberOfThresholds ); filter->SetInput( itkImage ); filter->SetValleyEmphasis( params.m_ValleyEmphasis ); filter->SetNumberOfHistogramBins ( params.m_NumberOfBins ); try { filter->Update(); } catch( ... ) { mitkThrow() << "itkOtsuFilter error."; } mitk::CastToMitkImage(filter->GetOutput(), params.m_Image); return; } namespace mitk { OtsuSegmentationFilter::OtsuSegmentationFilter() : m_NumberOfThresholds(2), m_ValleyEmphasis(false), m_NumberOfBins(128) { } OtsuSegmentationFilter::~OtsuSegmentationFilter() { } void OtsuSegmentationFilter::GenerateData() { mitk::Image::ConstPointer mitkImage = GetInput(); AccessByItk_n( mitkImage, AccessItkOtsuFilter, (paramContainer( m_NumberOfThresholds, m_ValleyEmphasis, m_NumberOfBins, this->GetOutput()) ) ); } } diff --git a/Modules/Segmentation/Interactions/mitkOtsuTool3D.cpp b/Modules/Segmentation/Interactions/mitkOtsuTool3D.cpp index d4e6f39665..fcae2de182 100644 --- a/Modules/Segmentation/Interactions/mitkOtsuTool3D.cpp +++ b/Modules/Segmentation/Interactions/mitkOtsuTool3D.cpp @@ -1,290 +1,294 @@ /*=================================================================== 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. ===================================================================*/ // MITK #include "mitkOtsuTool3D.h" #include "mitkToolManager.h" #include "mitkRenderingManager.h" #include #include #include #include #include #include #include "mitkOtsuSegmentationFilter.h" #include "mitkImage.h" +#include "mitkImageAccessByItk.h" // ITK #include #include #include #include "mitkRegionGrow3DTool.xpm" // us #include #include #include #include namespace mitk { MITK_TOOL_MACRO(MitkSegmentation_EXPORT, OtsuTool3D, "Otsu Segmentation"); } mitk::OtsuTool3D::OtsuTool3D() { } mitk::OtsuTool3D::~OtsuTool3D() { } void mitk::OtsuTool3D::Activated() { if (m_ToolManager) { m_OriginalImage = dynamic_cast(m_ToolManager->GetReferenceData(0)->GetData()); m_BinaryPreviewNode = mitk::DataNode::New(); m_BinaryPreviewNode->SetName("Binary_Preview"); m_BinaryPreviewNode->SetProperty( "color", ColorProperty::New(0.0, 1.0, 0.0) ); m_BinaryPreviewNode->SetProperty( "opacity", FloatProperty::New(0.3) ); //m_BinaryPreviewNode->SetBoolProperty("helper object", true); //m_BinaryPreviewNode->SetProperty("binary", mitk::BoolProperty::New(true)); m_ToolManager->GetDataStorage()->Add( this->m_BinaryPreviewNode ); m_MultiLabelResultNode = mitk::DataNode::New(); m_MultiLabelResultNode->SetName("Otsu_Preview"); //m_MultiLabelResultNode->SetBoolProperty("helper object", true); m_MultiLabelResultNode->SetVisibility(true); m_MaskedImagePreviewNode = mitk::DataNode::New(); m_MaskedImagePreviewNode->SetName("Volume_Preview"); //m_MultiLabelResultNode->SetBoolProperty("helper object", true); m_MaskedImagePreviewNode->SetVisibility(false); m_ToolManager->GetDataStorage()->Add( this->m_MultiLabelResultNode ); } } void mitk::OtsuTool3D::Deactivated() { m_ToolManager->GetDataStorage()->Remove( this->m_MultiLabelResultNode ); m_MultiLabelResultNode = NULL; m_ToolManager->GetDataStorage()->Remove( this->m_BinaryPreviewNode ); m_BinaryPreviewNode = NULL; m_ToolManager->GetDataStorage()->Remove( this->m_MaskedImagePreviewNode); m_MaskedImagePreviewNode = NULL; } const char** mitk::OtsuTool3D::GetXPM() const { return NULL; } us::ModuleResource mitk::OtsuTool3D::GetIconResource() const { us::Module* module = us::GetModuleContext()->GetModule(); us::ModuleResource resource = module->GetResource("Otsu_48x48.png"); return resource; } void mitk::OtsuTool3D::RunSegmentation(int regions, bool useValley, int numberOfBins) { //this->m_OtsuSegmentationDialog->setCursor(Qt::WaitCursor); int numberOfThresholds = regions - 1; unsigned int timestep = mitk::RenderingManager::GetInstance()->GetTimeNavigationController()->GetTime()->GetPos(); mitk::Image::Pointer image3D = Get3DImage(m_OriginalImage, timestep); mitk::OtsuSegmentationFilter::Pointer otsuFilter = mitk::OtsuSegmentationFilter::New(); otsuFilter->SetNumberOfThresholds( numberOfThresholds ); otsuFilter->SetValleyEmphasis( useValley ); otsuFilter->SetNumberOfBins( numberOfBins ); otsuFilter->SetInput( image3D ); try { otsuFilter->Update(); } catch( ... ) { mitkThrow() << "itkOtsuFilter error (image dimension must be in {2, 3} and image must not be RGB)"; } m_ToolManager->GetDataStorage()->Remove( this->m_MultiLabelResultNode ); m_MultiLabelResultNode = NULL; m_MultiLabelResultNode = mitk::DataNode::New(); m_MultiLabelResultNode->SetName("Otsu_Preview"); m_MultiLabelResultNode->SetVisibility(true); m_ToolManager->GetDataStorage()->Add( this->m_MultiLabelResultNode ); m_MultiLabelResultNode->SetOpacity(1.0); this->m_MultiLabelResultNode->SetData( otsuFilter->GetOutput() ); m_MultiLabelResultNode->SetProperty("binary", mitk::BoolProperty::New(false)); mitk::RenderingModeProperty::Pointer renderingMode = mitk::RenderingModeProperty::New(); renderingMode->SetValue( mitk::RenderingModeProperty::LOOKUPTABLE_LEVELWINDOW_COLOR ); m_MultiLabelResultNode->SetProperty("Image Rendering.Mode", renderingMode); mitk::LookupTable::Pointer lut = mitk::LookupTable::New(); mitk::LookupTableProperty::Pointer prop = mitk::LookupTableProperty::New(lut); vtkSmartPointer lookupTable = vtkSmartPointer::New(); lookupTable->SetHueRange(1.0, 0.0); lookupTable->SetSaturationRange(1.0, 1.0); lookupTable->SetValueRange(1.0, 1.0); lookupTable->SetTableRange(-1.0, 1.0); lookupTable->Build(); lut->SetVtkLookupTable(lookupTable); prop->SetLookupTable(lut); m_MultiLabelResultNode->SetProperty("LookupTable",prop); mitk::LevelWindowProperty::Pointer levWinProp = mitk::LevelWindowProperty::New(); mitk::LevelWindow levelwindow; levelwindow.SetRangeMinMax(0, numberOfThresholds + 1); levWinProp->SetLevelWindow( levelwindow ); m_MultiLabelResultNode->SetProperty( "levelwindow", levWinProp ); //m_BinaryPreviewNode->SetVisibility(false); // m_MultiLabelResultNode->SetVisibility(true); //this->m_OtsuSegmentationDialog->setCursor(Qt::ArrowCursor); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void mitk::OtsuTool3D::ConfirmSegmentation() { GetTargetSegmentationNode()->SetData(dynamic_cast(m_BinaryPreviewNode->GetData())); m_ToolManager->ActivateTool(-1); } void mitk::OtsuTool3D::UpdateBinaryPreview(std::vector regionIDs) { m_MultiLabelResultNode->SetVisibility(false); - //pixel with regionID -> binary image - const unsigned short dim = 3; - typedef unsigned char PixelType; + mitk::Image::Pointer multiLabelSegmentation = dynamic_cast(m_MultiLabelResultNode->GetData()); + AccessByItk_1( multiLabelSegmentation, CalculatePreview, regionIDs); +} - typedef itk::Image< PixelType, dim > InputImageType; - typedef itk::Image< PixelType, dim > OutputImageType; +template< typename TPixel, unsigned int VImageDimension> +void mitk::OtsuTool3D::CalculatePreview(itk::Image< TPixel, VImageDimension>* itkImage, std::vector regionIDs) +{ + typedef itk::Image< TPixel, VImageDimension > InputImageType; + typedef itk::Image< unsigned char, VImageDimension > OutputImageType; typedef itk::BinaryThresholdImageFilter< InputImageType, OutputImageType > FilterType; FilterType::Pointer filter = FilterType::New(); - InputImageType::Pointer itkImage; + //InputImageType::Pointer itkImage; OutputImageType::Pointer itkBinaryTempImage1; OutputImageType::Pointer itkBinaryTempImage2; OutputImageType::Pointer itkBinaryResultImage; - mitk::Image::Pointer multiLabelSegmentation = dynamic_cast(m_MultiLabelResultNode->GetData()); - mitk::CastToItkImage(multiLabelSegmentation, itkImage); + //mitk::Image::Pointer multiLabelSegmentation = dynamic_cast(m_MultiLabelResultNode->GetData()); + //mitk::CastToItkImage(multiLabelSegmentation, itkImage); filter->SetInput(itkImage); filter->SetLowerThreshold(regionIDs[0]); filter->SetUpperThreshold(regionIDs[0]); filter->SetInsideValue(1); filter->SetOutsideValue(0); filter->Update(); itkBinaryTempImage2 = filter->GetOutput(); itk::OrImageFilter::Pointer orFilter = itk::OrImageFilter::New(); // if more than one region id is used compute the union of all given binary regions for (std::vector::iterator it = regionIDs.begin() ; it != regionIDs.end(); ++it) { filter->SetLowerThreshold(*it); filter->SetUpperThreshold(*it); filter->SetInsideValue(1); filter->SetOutsideValue(0); filter->Update(); itkBinaryTempImage1 = filter->GetOutput(); orFilter->SetInput1(itkBinaryTempImage1); orFilter->SetInput2(itkBinaryTempImage2); orFilter->UpdateLargestPossibleRegion(); itkBinaryResultImage = orFilter->GetOutput(); itkBinaryTempImage2 = itkBinaryResultImage; } //---------------------------------------------------------------------------------------------------- mitk::Image::Pointer binarySegmentation; mitk::CastToMitkImage( itkBinaryResultImage, binarySegmentation); m_BinaryPreviewNode->SetData(binarySegmentation); m_BinaryPreviewNode->SetVisibility(true); m_BinaryPreviewNode->SetProperty("outline binary", mitk::BoolProperty::New(false)); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } //void mitk::OtsuTool3D::UpdateBinaryPreview(int regionID) //{ // m_MultiLabelResultNode->SetVisibility(false); // //pixel with regionID -> binary image // const unsigned short dim = 3; // typedef unsigned char PixelType; // // typedef itk::Image< PixelType, dim > InputImageType; // typedef itk::Image< PixelType, dim > OutputImageType; // // typedef itk::BinaryThresholdImageFilter< InputImageType, OutputImageType > FilterType; // // FilterType::Pointer filter = FilterType::New(); // // InputImageType::Pointer itkImage; // // mitk::Image::Pointer multiLabelSegmentation = dynamic_cast(m_MultiLabelResultNode->GetData()); // mitk::CastToItkImage(multiLabelSegmentation, itkImage); // // filter->SetInput(itkImage); // filter->SetLowerThreshold(regionID); // filter->SetUpperThreshold(regionID); // filter->SetInsideValue(1); // filter->SetOutsideValue(0); // filter->Update(); // mitk::Image::Pointer binarySegmentation; // mitk::CastToMitkImage( filter->GetOutput(), binarySegmentation); // m_BinaryPreviewNode->SetData(binarySegmentation); // m_BinaryPreviewNode->SetVisibility(true); // m_BinaryPreviewNode->SetProperty("outline binary", mitk::BoolProperty::New(false)); // // mitk::RenderingManager::GetInstance()->RequestUpdateAll(); //} const char* mitk::OtsuTool3D::GetName() const { return "Otsu"; } void mitk::OtsuTool3D::UpdateVolumePreview(bool volumeRendering) { if (volumeRendering) { m_MaskedImagePreviewNode->SetBoolProperty("volumerendering", true); m_MaskedImagePreviewNode->SetBoolProperty("volumerendering.uselod", true); } else { m_MaskedImagePreviewNode->SetBoolProperty("volumerendering", false); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void mitk::OtsuTool3D::ShowMultiLabelResultNode(bool show) { m_MultiLabelResultNode->SetVisibility(show); m_BinaryPreviewNode->SetVisibility(!show); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } diff --git a/Modules/Segmentation/Interactions/mitkOtsuTool3D.h b/Modules/Segmentation/Interactions/mitkOtsuTool3D.h index 0c98282c6f..6ca05fa45c 100644 --- a/Modules/Segmentation/Interactions/mitkOtsuTool3D.h +++ b/Modules/Segmentation/Interactions/mitkOtsuTool3D.h @@ -1,66 +1,70 @@ /*=================================================================== 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 MITKOTSUTOOL3D_H #define MITKOTSUTOOL3D_H #include #include "mitkAutoSegmentationTool.h" +#include "itkImage.h" namespace us { class ModuleResource; } namespace mitk{ class Image; class MitkSegmentation_EXPORT OtsuTool3D : public AutoSegmentationTool { public: mitkClassMacro(OtsuTool3D, AutoSegmentationTool); itkFactorylessNewMacro(Self) itkCloneMacro(Self) virtual const char* GetName() const; virtual const char** GetXPM() const; us::ModuleResource GetIconResource() const; virtual void Activated(); virtual void Deactivated(); void RunSegmentation( int regions, bool useValley, int numberOfBins); void ConfirmSegmentation(); //void UpdateBinaryPreview(int regionID); void UpdateBinaryPreview(std::vector regionIDs); void UpdateVolumePreview(bool volumeRendering); void ShowMultiLabelResultNode(bool); protected: OtsuTool3D(); virtual ~OtsuTool3D(); + template< typename TPixel, unsigned int VImageDimension> + void CalculatePreview( itk::Image< TPixel, VImageDimension>* itkImage, std::vector regionIDs); + itk::SmartPointer m_OriginalImage; //holds the user selected binary segmentation mitk::DataNode::Pointer m_BinaryPreviewNode; //holds the multilabel result as a preview image mitk::DataNode::Pointer m_MultiLabelResultNode; //holds the user selected binary segmentation masked original image mitk::DataNode::Pointer m_MaskedImagePreviewNode; };//class }//namespace #endif diff --git a/Modules/Segmentation/Interactions/mitkWatershedTool.cpp b/Modules/Segmentation/Interactions/mitkWatershedTool.cpp index 0582aea6d4..b110c9d51f 100644 --- a/Modules/Segmentation/Interactions/mitkWatershedTool.cpp +++ b/Modules/Segmentation/Interactions/mitkWatershedTool.cpp @@ -1,210 +1,210 @@ /*=================================================================== 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 "mitkWatershedTool.h" #include "mitkBinaryThresholdTool.xpm" #include "mitkToolManager.h" #include "mitkImageAccessByItk.h" #include "mitkImageCast.h" #include "mitkITKImageImport.h" #include "mitkRenderingManager.h" #include #include "mitkRenderingModeProperty.h" #include "mitkLookupTable.h" #include "mitkLookupTableProperty.h" #include "mitkIOUtil.h" #include "mitkLevelWindowManager.h" #include "mitkImageStatisticsHolder.h" #include "mitkToolCommand.h" #include "mitkProgressBar.h" #include "mitkImage.h" #include #include #include #include #include #include #include #include namespace mitk { MITK_TOOL_MACRO(MitkSegmentation_EXPORT, WatershedTool, "Watershed tool"); } mitk::WatershedTool::WatershedTool() : m_Level(0.), m_Threshold(0.) { } mitk::WatershedTool::~WatershedTool() { } void mitk::WatershedTool::Activated() { Superclass::Activated(); } void mitk::WatershedTool::Deactivated() { Superclass::Deactivated(); } us::ModuleResource mitk::WatershedTool::GetIconResource() const { us::Module* module = us::GetModuleContext()->GetModule(); us::ModuleResource resource = module->GetResource("Watershed_48x48.png"); return resource; } const char** mitk::WatershedTool::GetXPM() const { return NULL; } const char* mitk::WatershedTool::GetName() const { return "Watershed"; } void mitk::WatershedTool::DoIt() { // get image from tool manager mitk::DataNode::Pointer referenceData = m_ToolManager->GetReferenceData(0); mitk::Image::Pointer input = dynamic_cast(referenceData->GetData()); if (input.IsNull()) return; unsigned int timestep = mitk::RenderingManager::GetInstance()->GetTimeNavigationController()->GetTime()->GetPos(); input = Get3DImage(input, timestep); mitk::Image::Pointer output; try { // create and run itk filter pipeline - AccessFixedDimensionByItk_1(input.GetPointer(),ITKWatershed,3,output); + AccessByItk_1(input.GetPointer(),ITKWatershed,output); // create a new datanode for output mitk::DataNode::Pointer dataNode = mitk::DataNode::New(); dataNode->SetData(output); // set properties of datanode dataNode->SetProperty("binary", mitk::BoolProperty::New(false)); dataNode->SetProperty("name", mitk::StringProperty::New("Watershed Result")); mitk::RenderingModeProperty::Pointer renderingMode = mitk::RenderingModeProperty::New(); renderingMode->SetValue( mitk::RenderingModeProperty::LOOKUPTABLE_LEVELWINDOW_COLOR ); dataNode->SetProperty("Image Rendering.Mode", renderingMode); // since we create a multi label image, define a vtk lookup table mitk::LookupTable::Pointer lut = mitk::LookupTable::New(); mitk::LookupTableProperty::Pointer prop = mitk::LookupTableProperty::New(lut); vtkSmartPointer lookupTable = vtkSmartPointer::New(); lookupTable->SetHueRange(1.0, 0.0); lookupTable->SetSaturationRange(1.0, 1.0); lookupTable->SetValueRange(1.0, 1.0); lookupTable->SetTableRange(-1.0, 1.0); lookupTable->Build(); lookupTable->SetTableValue(1,0,0,0); lut->SetVtkLookupTable(lookupTable); prop->SetLookupTable(lut); dataNode->SetProperty("LookupTable",prop); // make the levelwindow fit to right values mitk::LevelWindowProperty::Pointer levWinProp = mitk::LevelWindowProperty::New(); mitk::LevelWindow levelwindow; levelwindow.SetRangeMinMax(0, output->GetStatistics()->GetScalarValueMax()); levWinProp->SetLevelWindow( levelwindow ); dataNode->SetProperty( "levelwindow", levWinProp ); dataNode->SetProperty( "opacity", mitk::FloatProperty::New(0.5)); // set name of data node std::string name = referenceData->GetName() + "_Watershed"; dataNode->SetName( name ); // look, if there is already a node with this name mitk::DataStorage::SetOfObjects::ConstPointer children = m_ToolManager->GetDataStorage()->GetDerivations(referenceData); mitk::DataStorage::SetOfObjects::ConstIterator currentNode = children->Begin(); mitk::DataNode::Pointer removeNode; while(currentNode != children->End()) { if(dataNode->GetName().compare(currentNode->Value()->GetName()) == 0) { removeNode = currentNode->Value(); } currentNode++; } // remove node with same name if(removeNode.IsNotNull()) m_ToolManager->GetDataStorage()->Remove(removeNode); // add output to the data storage m_ToolManager->GetDataStorage()->Add(dataNode,referenceData); } catch(itk::ExceptionObject& e) { MITK_ERROR<<"Watershed Filter Error: " << e.GetDescription(); } RenderingManager::GetInstance()->RequestUpdateAll(); } template void mitk::WatershedTool::ITKWatershed( itk::Image* originalImage, mitk::Image::Pointer& segmentation ) { typedef itk::WatershedImageFilter< itk::Image > WatershedFilter; typedef itk::GradientMagnitudeRecursiveGaussianImageFilter< itk::Image, itk::Image > MagnitudeFilter; // at first add a gradient magnitude filter typename MagnitudeFilter::Pointer magnitude = MagnitudeFilter::New(); magnitude->SetInput(originalImage); magnitude->SetSigma(1.0); // use the progress bar mitk::ToolCommand::Pointer command = mitk::ToolCommand::New(); command->AddStepsToDo(60); // then add the watershed filter to the pipeline typename WatershedFilter::Pointer watershed = WatershedFilter::New(); watershed->SetInput(magnitude->GetOutput()); watershed->SetThreshold(m_Threshold); watershed->SetLevel(m_Level); watershed->AddObserver(itk::ProgressEvent(),command); watershed->Update(); // then make sure, that the output has the desired pixel type - typedef itk::CastImageFilter > CastFilter; + typedef itk::CastImageFilter > CastFilter; typename CastFilter::Pointer cast = CastFilter::New(); cast->SetInput(watershed->GetOutput()); // start the whole pipeline cast->Update(); // reset the progress bar by setting progress command->SetProgress(10); // since we obtain a new image from our pipeline, we have to make sure, that our mitk::Image::Pointer // is responsible for the memory management of the output image segmentation = mitk::GrabItkImageMemory(cast->GetOutput()); }