Medical Imaging Interaction Toolkit  2018.4.99-87d68d9f
Medical Imaging Interaction Toolkit
mitkPickingTool.cpp
Go to the documentation of this file.
1 /*============================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
13 #include "mitkPickingTool.h"
14 
15 #include "mitkProperties.h"
16 #include "mitkToolManager.h"
17 
18 // us
19 #include <usGetModuleContext.h>
20 #include <usModule.h>
21 #include <usModuleContext.h>
22 #include <usModuleResource.h>
23 
24 #include "mitkITKImageImport.h"
25 #include "mitkImageAccessByItk.h"
26 #include "mitkImageCast.h"
27 #include "mitkImageTimeSelector.h"
28 #include "mitkImageTimeSelector.h"
29 
30 #include <itkConnectedThresholdImageFilter.h>
31 
32 #include <mitkLabelSetImage.h>
33 
34 namespace mitk
35 {
37 }
38 
39 mitk::PickingTool::PickingTool() : m_WorkingData(nullptr)
40 {
42  m_PointSetNode->GetPropertyList()->SetProperty("name", mitk::StringProperty::New("Picking_Seedpoint"));
43  m_PointSetNode->GetPropertyList()->SetProperty("helper object", mitk::BoolProperty::New(true));
45  m_PointSetNode->SetData(m_PointSet);
46 
47  // Watch for point added or modified
48  itk::SimpleMemberCommand<PickingTool>::Pointer pointAddedCommand = itk::SimpleMemberCommand<PickingTool>::New();
49  pointAddedCommand->SetCallbackFunction(this, &mitk::PickingTool::OnPointAdded);
50  m_PointSetAddObserverTag = m_PointSet->AddObserver(mitk::PointSetAddEvent(), pointAddedCommand);
51 
52  // create new node for picked region
54  // set some properties
55  m_ResultNode->SetProperty("name", mitk::StringProperty::New("result"));
56  m_ResultNode->SetProperty("helper object", mitk::BoolProperty::New(true));
57  m_ResultNode->SetProperty("color", mitk::ColorProperty::New(0, 1, 0));
58  m_ResultNode->SetProperty("layer", mitk::IntProperty::New(1));
59  m_ResultNode->SetProperty("opacity", mitk::FloatProperty::New(0.33f));
60 }
61 
63 {
64  m_PointSet->RemoveObserver(m_PointSetAddObserverTag);
65 }
66 
67 const char **mitk::PickingTool::GetXPM() const
68 {
69  return nullptr;
70 }
71 
72 const char *mitk::PickingTool::GetName() const
73 {
74  return "Picking";
75 }
76 
78 {
80  us::ModuleResource resource = module->GetResource("Pick_48x48.png");
81  return resource;
82 }
83 
85 {
86  Superclass::Activated();
87 
88  DataStorage *dataStorage = this->GetDataStorage();
89  m_WorkingData = this->GetWorkingData();
90 
91  // add to datastorage and enable interaction
92  if (!dataStorage->Exists(m_PointSetNode))
93  dataStorage->Add(m_PointSetNode, m_WorkingData);
94 
96  m_SeedPointInteractor->LoadStateMachine("PointSet.xml");
97  m_SeedPointInteractor->SetEventConfig("PointSetConfig.xml");
99 
100  // now add result to data tree
101  dataStorage->Add(m_ResultNode, m_WorkingData);
102 }
103 
105 {
106  m_PointSet->Clear();
107  // remove from data storage and disable interaction
110 
111  Superclass::Deactivated();
112 }
113 
115 {
116  return this->m_ToolManager->GetReferenceData(0);
117 }
118 
120 {
121  return this->m_ToolManager->GetDataStorage();
122 }
123 
125 {
126  return this->m_ToolManager->GetWorkingData(0);
127 }
128 
130 {
131  return m_PointSetNode;
132 }
133 
135 {
136  if (m_WorkingData != this->GetWorkingData())
137  {
138  DataStorage *dataStorage = this->GetDataStorage();
139 
140  if (dataStorage->Exists(m_PointSetNode))
141  {
142  dataStorage->Remove(m_PointSetNode);
143  dataStorage->Add(m_PointSetNode, this->GetWorkingData());
144  }
145 
146  if (dataStorage->Exists(m_ResultNode))
147  {
148  dataStorage->Remove(m_ResultNode);
149  dataStorage->Add(m_ResultNode, this->GetWorkingData());
150  }
151 
152  m_WorkingData = this->GetWorkingData();
153  }
154 
155  // Perform region growing/picking
156 
157  int timeStep =
159 
160  mitk::PointSet::PointType seedPoint = m_PointSet->GetPointSet(timeStep)->GetPoints()->Begin().Value();
161 
162  // as we want to pick a region from our segmentation image use the working data from ToolManager
163  mitk::Image::Pointer orgImage = dynamic_cast<mitk::Image *>(m_ToolManager->GetWorkingData(0)->GetData());
164 
165  if (orgImage.IsNotNull())
166  {
167  if (orgImage->GetDimension() == 4)
168  { // there may be 4D segmentation data even though we currently don't support that
170  timeSelector->SetInput(orgImage);
171  timeSelector->SetTimeNr(timeStep);
172  timeSelector->UpdateLargestPossibleRegion();
173  mitk::Image *timedImage = timeSelector->GetOutput();
174 
175  AccessByItk_2(timedImage, StartRegionGrowing, timedImage->GetGeometry(), seedPoint);
176  }
177  else if (orgImage->GetDimension() == 3)
178  {
179  AccessByItk_2(orgImage, StartRegionGrowing, orgImage->GetGeometry(), seedPoint);
180  }
181  this->m_PointSet->Clear();
182  }
183 }
184 
185 template <typename TPixel, unsigned int VImageDimension>
186 void mitk::PickingTool::StartRegionGrowing(itk::Image<TPixel, VImageDimension> *itkImage,
187  mitk::BaseGeometry *imageGeometry,
188  mitk::PointSet::PointType seedPoint)
189 {
190  typedef itk::Image<TPixel, VImageDimension> InputImageType;
191  typedef typename InputImageType::IndexType IndexType;
192  typedef itk::ConnectedThresholdImageFilter<InputImageType, InputImageType> RegionGrowingFilterType;
193  typename RegionGrowingFilterType::Pointer regionGrower = RegionGrowingFilterType::New();
194 
195  // convert world coordinates to image indices
196  IndexType seedIndex;
197  imageGeometry->WorldToIndex(seedPoint, seedIndex);
198 
199  // perform region growing in desired segmented region
200  regionGrower->SetInput(itkImage);
201  regionGrower->AddSeed(seedIndex);
202 
203  // TODO: conversion added to silence warning and
204  // maintain existing behaviour, should be fixed
205  // since it's not correct e.g. for signed char
206  regionGrower->SetLower(static_cast<typename InputImageType::PixelType>(1));
207  regionGrower->SetUpper(static_cast<typename InputImageType::PixelType>(255));
208 
209  try
210  {
211  regionGrower->Update();
212  }
213  catch (const itk::ExceptionObject &)
214  {
215  return; // can't work
216  }
217  catch (...)
218  {
219  return;
220  }
221 
222  // Store result and preview
223  mitk::Image::Pointer resultImage = mitk::ImportItkImage(regionGrower->GetOutput(), imageGeometry)->Clone();
225  resultLabelSetImage->InitializeByLabeledImage(resultImage);
226 
227  m_ResultNode->SetData(resultLabelSetImage);
228 
230 }
231 
233 {
235  newNode->SetProperty("name", mitk::StringProperty::New(m_WorkingData->GetName() + "_picked"));
236 
237  float rgb[3] = {1.0f, 0.0f, 0.0f};
238  m_WorkingData->GetColor(rgb);
239  newNode->SetProperty("color", mitk::ColorProperty::New(rgb));
240 
241  float opacity = 1.0f;
242  m_WorkingData->GetOpacity(opacity, nullptr);
243  newNode->SetProperty("opacity", mitk::FloatProperty::New(opacity));
244 
245  newNode->SetData(m_ResultNode->GetData());
246 
247  GetDataStorage()->Add(newNode, this->GetReferenceData());
249 
250  m_ResultNode->SetData(nullptr);
251 
253 }
mitk::DataNode::Pointer m_ResultNode
SinglePointDataInteractor::Pointer m_SeedPointInteractor
Data management class that handles &#39;was created by&#39; relations.
const char * GetName() const override
Returns the name of this tool. Make it short!
mitk::DataNode * GetReferenceData()
void SetVisibility(bool visible, const mitk::BaseRenderer *renderer=nullptr, const char *propertyKey="visible")
Convenience method for setting visibility properties (instances of BoolProperty)
static BaseRenderer * GetInstance(vtkRenderWindow *renWin)
void Deactivated() override
Called when the tool gets deactivated.
static vtkRenderWindow * GetRenderWindowByName(const std::string &name)
DataStorage * GetDataStorage()
mitk::DataNode * GetWorkingData()
static Pointer New()
static Pointer New()
#define MITKSEGMENTATION_EXPORT
virtual DataNode::Pointer GetPointSetNode()
DataCollection - Class to facilitate loading/accessing structured data.
DataNode::Pointer m_PointSetNode
virtual void Add(DataNode *node, const DataStorage::SetOfObjects *parents=nullptr)=0
Adds a DataNode containing a data object to its internal storage.
bool GetOpacity(float &opacity, const mitk::BaseRenderer *renderer, const char *propertyKey="opacity") const
Convenience access method for opacity properties (instances of FloatProperty)
const char ** GetXPM() const override
Returns an icon in the XPM format.
Image::Pointer ImportItkImage(const itk::SmartPointer< ItkOutputImageType > &itkimage, const BaseGeometry *geometry=nullptr, bool update=true)
Imports an itk::Image (with a specific type) as an mitk::Image.Instantiates instance of ITKImageImpor...
void Activated() override
Called when the tool gets activated.
static Pointer New()
mitk::DataStorage * GetDataStorage()
MITK_TOOL_MACRO(MITKSEGMENTATION_EXPORT, LiveWireTool2D, "LiveWire tool")
bool GetColor(float rgb[3], const mitk::BaseRenderer *renderer=nullptr, const char *propertyKey="color") const
Convenience access method for color properties (instances of ColorProperty)
static Pointer New()
static RenderingManager * GetInstance()
virtual unsigned int GetTimeStep() const
Module * GetModule() const
Image class for storing images.
Definition: mitkImage.h:72
ModuleResource GetResource(const std::string &path) const
Definition: usModule.cpp:267
us::ModuleResource GetIconResource() const override
Returns the tool button icon of the tool wrapped by a usModuleResource.
void WorldToIndex(const mitk::Point3D &pt_mm, mitk::Point3D &pt_units) const
Convert world coordinates (in mm) of a point to (continuous!) index coordinates.
static Pointer New()
virtual void Remove(const DataNode *node)=0
Removes node from the DataStorage.
static Pointer New()
Extracts a single region from a segmentation image and creates a new image with same geometry of the ...
static Pointer New()
PointSet::Pointer m_PointSet
DataVectorType GetReferenceData()
ToolManager * m_ToolManager
Definition: mitkTool.h:228
virtual bool Exists(const DataNode *node) const =0
Checks if a node exists in the DataStorage.
void StartRegionGrowing(itk::Image< TPixel, VImageDimension > *itkImage, mitk::BaseGeometry *imageGeometry, mitk::PointSet::PointType seedPoint)
Pointer Clone() const
#define AccessByItk_2(mitkImage, itkImageTypeFunction, arg1, arg2)
mitk::BaseGeometry * GetGeometry(int t=0) const
Return the geometry, which is a TimeGeometry, of the data as non-const pointer.
Definition: mitkBaseData.h:138
DataNode * m_WorkingData
static ModuleContext * GetModuleContext()
Returns the module context of the calling module.
static Pointer New()
void RequestUpdateAll(RequestType type=REQUEST_UPDATE_ALL)
BaseGeometry Describes the geometry of a data object.
Class for nodes of the DataTree.
Definition: mitkDataNode.h:57
static Pointer New()
DataVectorType GetWorkingData()
bool GetName(std::string &nodeName, const mitk::BaseRenderer *renderer=nullptr, const char *propertyKey="name") const
Convenience access method for accessing the name of an object (instance of StringProperty with proper...
Definition: mitkDataNode.h:369