diff --git a/Modules/Segmentation/Interactions/mitkOtsuTool3D.cpp b/Modules/Segmentation/Interactions/mitkOtsuTool3D.cpp index 1083ef4282..7cbea7e92a 100644 --- a/Modules/Segmentation/Interactions/mitkOtsuTool3D.cpp +++ b/Modules/Segmentation/Interactions/mitkOtsuTool3D.cpp @@ -1,303 +1,308 @@ /*=================================================================== 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 "mitkLabelSetImage.h" #include "mitkImageAccessByItk.h" // ITK #include #include #include #include "mitkRegionGrow3DTool.xpm" // us #include #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() ); + mitk::LabelSetImage::Pointer resultImage = mitk::LabelSetImage::New(); + resultImage->InitializeByLabeledImage( otsuFilter->GetOutput() ); + this->m_MultiLabelResultNode->SetData(resultImage); 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())); + mitk::LabelSetImage::Pointer resultImage = mitk::LabelSetImage::New(); + resultImage->InitializeByLabeledImage(dynamic_cast(m_BinaryPreviewNode->GetData())); + GetTargetSegmentationNode()->SetData(resultImage); + m_ToolManager->ActivateTool(-1); } void mitk::OtsuTool3D::UpdateBinaryPreview(std::vector regionIDs) { m_MultiLabelResultNode->SetVisibility(false); mitk::Image::Pointer multiLabelSegmentation = dynamic_cast(m_MultiLabelResultNode->GetData()); AccessByItk_1( multiLabelSegmentation, CalculatePreview, regionIDs); } 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< mitk::Tool::DefaultSegmentationDataType, VImageDimension > OutputImageType; typedef itk::BinaryThresholdImageFilter< InputImageType, OutputImageType > FilterType; typename FilterType::Pointer filter = FilterType::New(); //InputImageType::Pointer itkImage; typename OutputImageType::Pointer itkBinaryTempImage1; typename OutputImageType::Pointer itkBinaryTempImage2; typename OutputImageType::Pointer itkBinaryResultImage; //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(); typename 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(); } int mitk::OtsuTool3D::GetNumberOfBins() { ScalarType min = m_OriginalImage.GetPointer()->GetStatistics()->GetScalarValueMin(); ScalarType max = m_OriginalImage.GetPointer()->GetStatistics()->GetScalarValueMaxNoRecompute(); return static_cast(max-min) + 1; } diff --git a/Modules/Segmentation/Interactions/mitkPickingTool.cpp b/Modules/Segmentation/Interactions/mitkPickingTool.cpp index 39413eb054..0c9f6de2d1 100644 --- a/Modules/Segmentation/Interactions/mitkPickingTool.cpp +++ b/Modules/Segmentation/Interactions/mitkPickingTool.cpp @@ -1,245 +1,248 @@ /*=================================================================== 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 "mitkPickingTool.h" #include "mitkToolManager.h" #include "mitkProperties.h" // us #include #include #include #include #include "mitkImageCast.h" #include "mitkImageTimeSelector.h" #include "mitkITKImageImport.h" #include "mitkImageAccessByItk.h" #include "mitkImageTimeSelector.h" #include +#include namespace mitk { MITK_TOOL_MACRO(MITKSEGMENTATION_EXPORT, PickingTool, "PickingTool"); } mitk::PickingTool::PickingTool() : m_WorkingData(NULL) { m_PointSetNode = mitk::DataNode::New(); m_PointSetNode->GetPropertyList()->SetProperty("name", mitk::StringProperty::New("Picking_Seedpoint")); m_PointSetNode->GetPropertyList()->SetProperty("helper object", mitk::BoolProperty::New(true)); m_PointSet = mitk::PointSet::New(); m_PointSetNode->SetData(m_PointSet); m_SeedPointInteractor = mitk::SinglePointDataInteractor::New(); m_SeedPointInteractor->LoadStateMachine("PointSet.xml"); m_SeedPointInteractor->SetEventConfig("PointSetConfig.xml"); m_SeedPointInteractor->SetDataNode(m_PointSetNode); //Watch for point added or modified itk::SimpleMemberCommand::Pointer pointAddedCommand = itk::SimpleMemberCommand::New(); pointAddedCommand->SetCallbackFunction(this, &mitk::PickingTool::OnPointAdded); m_PointSetAddObserverTag = m_PointSet->AddObserver( mitk::PointSetAddEvent(), pointAddedCommand); //create new node for picked region m_ResultNode = mitk::DataNode::New(); // set some properties m_ResultNode->SetProperty("name", mitk::StringProperty::New("result")); m_ResultNode->SetProperty("helper object", mitk::BoolProperty::New(true)); m_ResultNode->SetProperty("color", mitk::ColorProperty::New(0, 1, 0)); m_ResultNode->SetProperty("layer", mitk::IntProperty::New(1)); m_ResultNode->SetProperty("opacity", mitk::FloatProperty::New(0.33f)); } mitk::PickingTool::~PickingTool() { m_PointSet->RemoveObserver(m_PointSetAddObserverTag); } const char** mitk::PickingTool::GetXPM() const { return NULL; } const char* mitk::PickingTool::GetName() const { return "Picking"; } us::ModuleResource mitk::PickingTool::GetIconResource() const { us::Module* module = us::GetModuleContext()->GetModule(); us::ModuleResource resource = module->GetResource("Pick_48x48.png"); return resource; } void mitk::PickingTool::Activated() { DataStorage* dataStorage = this->GetDataStorage(); m_WorkingData = this->GetWorkingData(); //add to datastorage and enable interaction if (!dataStorage->Exists(m_PointSetNode)) dataStorage->Add(m_PointSetNode, m_WorkingData); // now add result to data tree dataStorage->Add(m_ResultNode, m_WorkingData); } void mitk::PickingTool::Deactivated() { m_PointSet->Clear(); //remove from data storage and disable interaction GetDataStorage()->Remove(m_PointSetNode); GetDataStorage()->Remove( m_ResultNode); } mitk::DataNode* mitk::PickingTool::GetReferenceData(){ return this->m_ToolManager->GetReferenceData(0); } mitk::DataStorage* mitk::PickingTool::GetDataStorage(){ return this->m_ToolManager->GetDataStorage(); } mitk::DataNode* mitk::PickingTool::GetWorkingData(){ return this->m_ToolManager->GetWorkingData(0); } mitk::DataNode::Pointer mitk::PickingTool::GetPointSetNode() { return m_PointSetNode; } void mitk::PickingTool::OnPointAdded() { if (m_WorkingData != this->GetWorkingData()) { DataStorage* dataStorage = this->GetDataStorage(); if (dataStorage->Exists(m_PointSetNode)) { dataStorage->Remove(m_PointSetNode); dataStorage->Add(m_PointSetNode, this->GetWorkingData()); } if (dataStorage->Exists(m_ResultNode)) { dataStorage->Remove(m_ResultNode); dataStorage->Add(m_ResultNode, this->GetWorkingData()); } m_WorkingData = this->GetWorkingData(); } //Perform region growing/picking int timeStep = mitk::BaseRenderer::GetInstance( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget1") )->GetTimeStep(); mitk::PointSet::PointType seedPoint = m_PointSet->GetPointSet(timeStep)->GetPoints()->Begin().Value(); //as we want to pick a region from our segmentation image use the working data from ToolManager mitk::Image::Pointer orgImage = dynamic_cast (m_ToolManager->GetWorkingData(0)->GetData()); if (orgImage.IsNotNull()) { if (orgImage->GetDimension() == 4) { //there may be 4D segmentation data even though we currently don't support that mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New(); timeSelector->SetInput(orgImage); timeSelector->SetTimeNr( timeStep ); timeSelector->UpdateLargestPossibleRegion(); mitk::Image* timedImage = timeSelector->GetOutput(); AccessByItk_2( timedImage , StartRegionGrowing, timedImage->GetGeometry(), seedPoint); } else if (orgImage->GetDimension() == 3) { AccessByItk_2(orgImage, StartRegionGrowing, orgImage->GetGeometry(), seedPoint); } this->m_PointSet->Clear(); } } template void mitk::PickingTool::StartRegionGrowing(itk::Image* itkImage, mitk::BaseGeometry* imageGeometry, mitk::PointSet::PointType seedPoint) { typedef itk::Image InputImageType; typedef typename InputImageType::IndexType IndexType; typedef itk::ConnectedThresholdImageFilter RegionGrowingFilterType; typename RegionGrowingFilterType::Pointer regionGrower = RegionGrowingFilterType::New(); // convert world coordinates to image indices IndexType seedIndex; imageGeometry->WorldToIndex( seedPoint, seedIndex); //perform region growing in desired segmented region regionGrower->SetInput( itkImage ); regionGrower->AddSeed( seedIndex ); regionGrower->SetLower( 1 ); regionGrower->SetUpper( 255 ); try { regionGrower->Update(); } catch(const itk::ExceptionObject&) { return; // can't work } catch( ... ) { return; } //Store result and preview mitk::Image::Pointer resultImage = mitk::ImportItkImage(regionGrower->GetOutput(),imageGeometry)->Clone(); + mitk::LabelSetImage::Pointer resultLabelSetImage = mitk::LabelSetImage::New(); + resultLabelSetImage->InitializeByLabeledImage(resultImage); - m_ResultNode->SetData( resultImage ); + m_ResultNode->SetData(resultLabelSetImage); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void mitk::PickingTool::ConfirmSegmentation() { mitk::DataNode::Pointer newNode = mitk::DataNode::New(); newNode->SetProperty("name", mitk::StringProperty::New(m_WorkingData->GetName() + "_picked")); float rgb[3] = { 1.0f, 0.0f, 0.0f }; m_WorkingData->GetColor(rgb); newNode->SetProperty("color", mitk::ColorProperty::New(rgb)); float opacity = 1.0f; m_WorkingData->GetOpacity(opacity, NULL); newNode->SetProperty("opacity", mitk::FloatProperty::New(opacity)); newNode->SetData(m_ResultNode->GetData()); GetDataStorage()->Add(newNode, this->GetReferenceData()); m_ResultNode->SetData(NULL); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); }