00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "mitkBinaryThresholdTool.h"
00019
00020 #include "mitkBinaryThresholdTool.xpm"
00021
00022 #include "mitkToolManager.h"
00023 #include "mitkBoundingObjectToSegmentationFilter.h"
00024
00025 #include <mitkCoreObjectFactory.h>
00026 #include "mitkLevelWindowProperty.h"
00027 #include "mitkColorProperty.h"
00028 #include "mitkProperties.h"
00029 #include "mitkOrganTypeProperty.h"
00030 #include "mitkVtkResliceInterpolationProperty.h"
00031 #include "mitkDataStorage.h"
00032 #include "mitkRenderingManager.h"
00033
00034 #include "mitkImageCast.h"
00035 #include "mitkImageTimeSelector.h"
00036 #include <itkImageRegionIterator.h>
00037 #include <itkMaskImageFilter.h>
00038 #include <itkBinaryThresholdImageFilter.h>
00039
00040 namespace mitk {
00041 MITK_TOOL_MACRO(MitkExt_EXPORT, BinaryThresholdTool, "Thresholding tool");
00042 }
00043
00044 mitk::BinaryThresholdTool::BinaryThresholdTool()
00045 :m_SensibleMinimumThresholdValue(-100),
00046 m_SensibleMaximumThresholdValue(+100),
00047 m_CurrentThresholdValue(1)
00048 {
00049 this->SupportRoiOn();
00050
00051 m_ThresholdFeedbackNode = DataNode::New();
00052 mitk::CoreObjectFactory::GetInstance()->SetDefaultProperties( m_ThresholdFeedbackNode );
00053
00054 m_ThresholdFeedbackNode->SetProperty( "color", ColorProperty::New(1.0, 0.0, 0.0) );
00055 m_ThresholdFeedbackNode->SetProperty( "texture interpolation", BoolProperty::New(false) );
00056 m_ThresholdFeedbackNode->SetProperty( "layer", IntProperty::New( 100 ) );
00057 m_ThresholdFeedbackNode->SetProperty( "levelwindow", LevelWindowProperty::New( LevelWindow(100, 1) ) );
00058 m_ThresholdFeedbackNode->SetProperty( "name", StringProperty::New("Thresholding feedback") );
00059 m_ThresholdFeedbackNode->SetProperty( "opacity", FloatProperty::New(0.3) );
00060 m_ThresholdFeedbackNode->SetProperty( "helper object", BoolProperty::New(true) );
00061 }
00062
00063 mitk::BinaryThresholdTool::~BinaryThresholdTool()
00064 {
00065 }
00066
00067 const char** mitk::BinaryThresholdTool::GetXPM() const
00068 {
00069 return mitkBinaryThresholdTool_xpm;
00070 }
00071
00072 const char* mitk::BinaryThresholdTool::GetName() const
00073 {
00074 return "Thresholding";
00075 }
00076
00077 void mitk::BinaryThresholdTool::Activated()
00078 {
00079 m_ToolManager->RoiDataChanged += mitk::MessageDelegate<mitk::BinaryThresholdTool>(this, &mitk::BinaryThresholdTool::OnRoiDataChanged);
00080 m_OriginalImageNode = m_ToolManager->GetReferenceData(0);
00081 m_NodeForThresholding = m_OriginalImageNode;
00082
00083 if ( m_NodeForThresholding.IsNotNull() )
00084 {
00085 SetupPreviewNodeFor( m_NodeForThresholding );
00086 }
00087 else
00088 {
00089 m_ToolManager->ActivateTool(-1);
00090 }
00091 }
00092
00093 void mitk::BinaryThresholdTool::Deactivated()
00094 {
00095 m_ToolManager->RoiDataChanged -= mitk::MessageDelegate<mitk::BinaryThresholdTool>(this, &mitk::BinaryThresholdTool::OnRoiDataChanged);
00096 m_NodeForThresholding = NULL;
00097 m_OriginalImageNode = NULL;
00098 try
00099 {
00100 if (DataStorage* storage = m_ToolManager->GetDataStorage())
00101 {
00102 storage->Remove( m_ThresholdFeedbackNode );
00103 RenderingManager::GetInstance()->RequestUpdateAll();
00104 }
00105 }
00106 catch(...)
00107 {
00108
00109 }
00110 m_ThresholdFeedbackNode->SetData(NULL);
00111 }
00112
00113 void mitk::BinaryThresholdTool::SetThresholdValue(int value)
00114 {
00115 if (m_ThresholdFeedbackNode.IsNotNull())
00116 {
00117 m_CurrentThresholdValue = value;
00118 m_ThresholdFeedbackNode->SetProperty( "levelwindow", LevelWindowProperty::New( LevelWindow(m_CurrentThresholdValue, 1) ) );
00119 RenderingManager::GetInstance()->RequestUpdateAll();
00120 }
00121 }
00122
00123 void mitk::BinaryThresholdTool::AcceptCurrentThresholdValue(const std::string& organName, const Color& color)
00124 {
00125
00126 CreateNewSegmentationFromThreshold(m_NodeForThresholding, organName, color );
00127
00128 RenderingManager::GetInstance()->RequestUpdateAll();
00129 m_ToolManager->ActivateTool(-1);
00130 }
00131
00132 void mitk::BinaryThresholdTool::CancelThresholding()
00133 {
00134 m_ToolManager->ActivateTool(-1);
00135 }
00136
00137 void mitk::BinaryThresholdTool::SetupPreviewNodeFor( DataNode* nodeForThresholding )
00138 {
00139 if (nodeForThresholding)
00140 {
00141 Image::Pointer image = dynamic_cast<Image*>( nodeForThresholding->GetData() );
00142 Image::Pointer originalImage = dynamic_cast<Image*> (m_OriginalImageNode->GetData());
00143 if (image.IsNotNull())
00144 {
00145
00146
00147 m_ThresholdFeedbackNode->SetData( image );
00148 int layer(50);
00149 nodeForThresholding->GetIntProperty("layer", layer);
00150 m_ThresholdFeedbackNode->SetIntProperty("layer", layer+1);
00151
00152 if (DataStorage* storage = m_ToolManager->GetDataStorage())
00153 {
00154 if (storage->Exists(m_ThresholdFeedbackNode))
00155 storage->Remove(m_ThresholdFeedbackNode);
00156 storage->Add( m_ThresholdFeedbackNode, nodeForThresholding );
00157 }
00158
00159 m_SensibleMinimumThresholdValue = static_cast<int>( originalImage->GetScalarValueMin() );
00160 m_SensibleMaximumThresholdValue = static_cast<int>( originalImage->GetScalarValueMax() );
00161
00162 LevelWindowProperty::Pointer lwp = dynamic_cast<LevelWindowProperty*>( m_ThresholdFeedbackNode->GetProperty( "levelwindow" ));
00163 if (lwp)
00164 {
00165 m_CurrentThresholdValue = static_cast<int>( lwp->GetLevelWindow().GetLevel() );
00166 }
00167 else
00168 {
00169 m_CurrentThresholdValue = (m_SensibleMaximumThresholdValue + m_SensibleMinimumThresholdValue)/2;
00170 }
00171
00172 IntervalBordersChanged.Send(m_SensibleMinimumThresholdValue, m_SensibleMaximumThresholdValue);
00173 ThresholdingValueChanged.Send(m_CurrentThresholdValue);
00174 }
00175 }
00176 }
00177
00178 void mitk::BinaryThresholdTool::CreateNewSegmentationFromThreshold(DataNode* node, const std::string& organName, const Color& color)
00179 {
00180 if (node)
00181 {
00182 Image::Pointer image = dynamic_cast<Image*>( m_NodeForThresholding->GetData() );
00183 if (image.IsNotNull())
00184 {
00185
00186 DataNode::Pointer emptySegmentation = Tool::CreateEmptySegmentationNode( image, organName, color );
00187
00188 if (emptySegmentation)
00189 {
00190
00191 for (unsigned int timeStep = 0; timeStep < image->GetTimeSteps(); ++timeStep)
00192 {
00193 try
00194 {
00195 ImageTimeSelector::Pointer timeSelector = ImageTimeSelector::New();
00196 timeSelector->SetInput( image );
00197 timeSelector->SetTimeNr( timeStep );
00198 timeSelector->UpdateLargestPossibleRegion();
00199 Image::Pointer image3D = timeSelector->GetOutput();
00200
00201 AccessFixedDimensionByItk_2( image3D, ITKThresholding, 3, dynamic_cast<Image*>(emptySegmentation->GetData()), timeStep );
00202 }
00203 catch(...)
00204 {
00205 Tool::ErrorMessage("Error accessing single time steps of the original image. Cannot create segmentation.");
00206 }
00207 }
00208
00209 if (DataStorage* storage = m_ToolManager->GetDataStorage())
00210 {
00211 storage->Add( emptySegmentation, m_OriginalImageNode );
00212 }
00213
00214 m_ToolManager->SetWorkingData( emptySegmentation );
00215 }
00216 }
00217 }
00218 }
00219
00220 template <typename TPixel, unsigned int VImageDimension>
00221 void mitk::BinaryThresholdTool::ITKThresholding( itk::Image<TPixel, VImageDimension>* originalImage, Image* segmentation, unsigned int timeStep )
00222 {
00223 ImageTimeSelector::Pointer timeSelector = ImageTimeSelector::New();
00224 timeSelector->SetInput( segmentation );
00225 timeSelector->SetTimeNr( timeStep );
00226 timeSelector->UpdateLargestPossibleRegion();
00227 Image::Pointer segmentation3D = timeSelector->GetOutput();
00228
00229 typedef itk::Image< Tool::DefaultSegmentationDataType, 3> SegmentationType;
00230 SegmentationType::Pointer itkSegmentation;
00231 CastToItkImage( segmentation3D, itkSegmentation );
00232
00233
00234 typedef itk::ImageRegionConstIterator< itk::Image<TPixel, VImageDimension> > InputIteratorType;
00235 typedef itk::ImageRegionIterator< SegmentationType > SegmentationIteratorType;
00236
00237 InputIteratorType inputIterator( originalImage, originalImage->GetLargestPossibleRegion() );
00238 SegmentationIteratorType outputIterator( itkSegmentation, itkSegmentation->GetLargestPossibleRegion() );
00239
00240 inputIterator.GoToBegin();
00241 outputIterator.GoToBegin();
00242
00243 while (!outputIterator.IsAtEnd())
00244 {
00245 if ( (signed)inputIterator.Get() >= m_CurrentThresholdValue )
00246 {
00247 outputIterator.Set( 1 );
00248 }
00249 else
00250 {
00251 outputIterator.Set( 0 );
00252 }
00253
00254 ++inputIterator;
00255 ++outputIterator;
00256 }
00257 }
00258
00259 void mitk::BinaryThresholdTool::OnRoiDataChanged()
00260 {
00261 typedef itk::Image<int, 3> ItkImageType;
00262 typedef itk::Image<unsigned char, 3> ItkMaskType;
00263 typedef itk::MaskImageFilter<ItkImageType, ItkMaskType, ItkImageType> MaskFilterType;
00264 mitk::DataNode* node = m_ToolManager->GetRoiData(0);
00265 if (node == NULL)
00266 {
00267 this->SetupPreviewNodeFor(m_OriginalImageNode);
00268 m_NodeForThresholding = m_OriginalImageNode;
00269 return;
00270 }
00271
00272 mitk::DataNode::Pointer new_node = mitk::DataNode::New();
00273 mitk::Image* image = dynamic_cast<mitk::Image*> (m_OriginalImageNode->GetData());
00274 mitk::Image::Pointer new_image = mitk::Image::New();
00275
00276 mitk::Image::Pointer roi;
00277 mitk::BoundingObject* boundingObject = dynamic_cast<mitk::BoundingObject*> (node->GetData());
00278
00279 if (boundingObject)
00280 {
00281 mitk::BoundingObjectToSegmentationFilter::Pointer filter = mitk::BoundingObjectToSegmentationFilter::New();
00282 filter->SetBoundingObject( boundingObject);
00283 filter->SetInput(image);
00284 filter->Update();
00285 roi = filter->GetOutput();
00286 }
00287 else
00288 roi = dynamic_cast<mitk::Image*> (node->GetData());
00289
00290 if (roi)
00291 {
00292 MaskFilterType::Pointer filter = MaskFilterType::New();
00293 ItkMaskType::Pointer itkRoi = ItkMaskType::New();
00294 ItkImageType::Pointer itkImage = ItkImageType::New();
00295 mitk::CastToItkImage(image, itkImage);
00296 mitk::CastToItkImage(roi, itkRoi);
00297 filter->SetInput1(itkImage);
00298 filter->SetInput2(itkRoi);
00299 filter->SetOutsideValue(-32765);
00300 filter->Update();
00301 mitk::CastToMitkImage(filter->GetOutput(),new_image);
00302 }
00303 new_node->SetData(new_image);
00304
00305 this->SetupPreviewNodeFor(new_node);
00306 m_NodeForThresholding = new_node;
00307 }