Medical Imaging Interaction Toolkit  2016.11.0
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,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
17 #include "mitkPickingTool.h"
18 
19 #include "mitkProperties.h"
20 #include "mitkToolManager.h"
21 
22 // us
23 #include <usGetModuleContext.h>
24 #include <usModule.h>
25 #include <usModuleContext.h>
26 #include <usModuleResource.h>
27 
28 #include "mitkITKImageImport.h"
29 #include "mitkImageAccessByItk.h"
30 #include "mitkImageCast.h"
31 #include "mitkImageTimeSelector.h"
32 #include "mitkImageTimeSelector.h"
33 
34 #include <itkConnectedThresholdImageFilter.h>
35 
36 #include <mitkLabelSetImage.h>
37 
38 namespace mitk
39 {
41 }
42 
43 mitk::PickingTool::PickingTool() : m_WorkingData(NULL)
44 {
46  m_PointSetNode->GetPropertyList()->SetProperty("name", mitk::StringProperty::New("Picking_Seedpoint"));
47  m_PointSetNode->GetPropertyList()->SetProperty("helper object", mitk::BoolProperty::New(true));
49  m_PointSetNode->SetData(m_PointSet);
51  m_SeedPointInteractor->LoadStateMachine("PointSet.xml");
52  m_SeedPointInteractor->SetEventConfig("PointSetConfig.xml");
54 
55  // Watch for point added or modified
57  pointAddedCommand->SetCallbackFunction(this, &mitk::PickingTool::OnPointAdded);
58  m_PointSetAddObserverTag = m_PointSet->AddObserver(mitk::PointSetAddEvent(), pointAddedCommand);
59 
60  // create new node for picked region
62  // set some properties
63  m_ResultNode->SetProperty("name", mitk::StringProperty::New("result"));
64  m_ResultNode->SetProperty("helper object", mitk::BoolProperty::New(true));
65  m_ResultNode->SetProperty("color", mitk::ColorProperty::New(0, 1, 0));
66  m_ResultNode->SetProperty("layer", mitk::IntProperty::New(1));
67  m_ResultNode->SetProperty("opacity", mitk::FloatProperty::New(0.33f));
68 }
69 
71 {
72  m_PointSet->RemoveObserver(m_PointSetAddObserverTag);
73 }
74 
75 const char **mitk::PickingTool::GetXPM() const
76 {
77  return NULL;
78 }
79 
80 const char *mitk::PickingTool::GetName() const
81 {
82  return "Picking";
83 }
84 
86 {
88  us::ModuleResource resource = module->GetResource("Pick_48x48.png");
89  return resource;
90 }
91 
93 {
94  Superclass::Activated();
95 
96  DataStorage *dataStorage = this->GetDataStorage();
97  m_WorkingData = this->GetWorkingData();
98 
99  // add to datastorage and enable interaction
100  if (!dataStorage->Exists(m_PointSetNode))
101  dataStorage->Add(m_PointSetNode, m_WorkingData);
102 
103  // now add result to data tree
104  dataStorage->Add(m_ResultNode, m_WorkingData);
105 }
106 
108 {
109  m_PointSet->Clear();
110  // remove from data storage and disable interaction
111  GetDataStorage()->Remove(m_PointSetNode);
112  GetDataStorage()->Remove(m_ResultNode);
113 
114  Superclass::Deactivated();
115 }
116 
118 {
119  return this->m_ToolManager->GetReferenceData(0);
120 }
121 
123 {
124  return this->m_ToolManager->GetDataStorage();
125 }
126 
128 {
129  return this->m_ToolManager->GetWorkingData(0);
130 }
131 
133 {
134  return m_PointSetNode;
135 }
136 
138 {
139  if (m_WorkingData != this->GetWorkingData())
140  {
141  DataStorage *dataStorage = this->GetDataStorage();
142 
143  if (dataStorage->Exists(m_PointSetNode))
144  {
145  dataStorage->Remove(m_PointSetNode);
146  dataStorage->Add(m_PointSetNode, this->GetWorkingData());
147  }
148 
149  if (dataStorage->Exists(m_ResultNode))
150  {
151  dataStorage->Remove(m_ResultNode);
152  dataStorage->Add(m_ResultNode, this->GetWorkingData());
153  }
154 
155  m_WorkingData = this->GetWorkingData();
156  }
157 
158  // Perform region growing/picking
159 
160  int timeStep =
162 
163  mitk::PointSet::PointType seedPoint = m_PointSet->GetPointSet(timeStep)->GetPoints()->Begin().Value();
164 
165  // as we want to pick a region from our segmentation image use the working data from ToolManager
166  mitk::Image::Pointer orgImage = dynamic_cast<mitk::Image *>(m_ToolManager->GetWorkingData(0)->GetData());
167 
168  if (orgImage.IsNotNull())
169  {
170  if (orgImage->GetDimension() == 4)
171  { // there may be 4D segmentation data even though we currently don't support that
173  timeSelector->SetInput(orgImage);
174  timeSelector->SetTimeNr(timeStep);
175  timeSelector->UpdateLargestPossibleRegion();
176  mitk::Image *timedImage = timeSelector->GetOutput();
177 
178  AccessByItk_2(timedImage, StartRegionGrowing, timedImage->GetGeometry(), seedPoint);
179  }
180  else if (orgImage->GetDimension() == 3)
181  {
182  AccessByItk_2(orgImage, StartRegionGrowing, orgImage->GetGeometry(), seedPoint);
183  }
184  this->m_PointSet->Clear();
185  }
186 }
187 
188 template <typename TPixel, unsigned int VImageDimension>
189 void mitk::PickingTool::StartRegionGrowing(itk::Image<TPixel, VImageDimension> *itkImage,
190  mitk::BaseGeometry *imageGeometry,
191  mitk::PointSet::PointType seedPoint)
192 {
193  typedef itk::Image<TPixel, VImageDimension> InputImageType;
194  typedef typename InputImageType::IndexType IndexType;
195  typedef itk::ConnectedThresholdImageFilter<InputImageType, InputImageType> RegionGrowingFilterType;
197 
198  // convert world coordinates to image indices
199  IndexType seedIndex;
200  imageGeometry->WorldToIndex(seedPoint, seedIndex);
201 
202  // perform region growing in desired segmented region
203  regionGrower->SetInput(itkImage);
204  regionGrower->AddSeed(seedIndex);
205 
206  regionGrower->SetLower(1);
207  regionGrower->SetUpper(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, NULL);
243  newNode->SetProperty("opacity", mitk::FloatProperty::New(opacity));
244 
245  newNode->SetData(m_ResultNode->GetData());
246 
247  GetDataStorage()->Add(newNode, this->GetReferenceData());
248  m_WorkingData->SetVisibility(false);
249 
250  m_ResultNode->SetData(NULL);
251 
253 }
virtual void Add(mitk::DataNode *node, const mitk::DataStorage::SetOfObjects *parents=nullptr)=0
Adds a DataNode containing a data object to its internal storage.
mitk::DataNode::Pointer m_ResultNode
SinglePointDataInteractor::Pointer m_SeedPointInteractor
Data management class that handles 'was created by' relations.
itk::SmartPointer< Self > Pointer
virtual const char * GetName() const override
Returns the name of this tool. Make it short!
Pointer Clone() const
mitk::DataNode * GetReferenceData()
static BaseRenderer * GetInstance(vtkRenderWindow *renWin)
virtual void Deactivated() override
Called when the tool gets deactivated.
static vtkRenderWindow * GetRenderWindowByName(const std::string &name)
mitk::DataNode * GetWorkingData()
static Pointer New()
static Pointer New()
#define MITKSEGMENTATION_EXPORT
virtual DataNode::Pointer GetPointSetNode()
DataCollection - Class to facilitate loading/accessing structured data.
static mitk::DataStorage::Pointer GetDataStorage()
#define MITK_TOOL_MACRO(EXPORT_SPEC, CLASS_NAME, DESCRIPTION)
DataNode::Pointer m_PointSetNode
virtual 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...
virtual void Activated() override
Called when the tool gets activated.
static Pointer New()
mitk::DataStorage * GetDataStorage()
itk::Image< double, 3 > InputImageType
static Pointer New()
static RenderingManager * GetInstance()
Module * GetModule() const
Image class for storing images.
Definition: mitkImage.h:76
us::ModuleResource GetIconResource() const override
Returns the tool button icon of the tool wrapped by a usModuleResource.
static Pointer New()
virtual unsigned int GetTimeStep() const
static Pointer New()
static Pointer New()
Extracts a single region from a segmentation image and creates a new image with same geometry of the ...
PointSet::Pointer m_PointSet
void StartRegionGrowing(itk::Image< TPixel, VImageDimension > *itkImage, mitk::BaseGeometry *imageGeometry, mitk::PointSet::PointType seedPoint)
virtual bool Exists(const mitk::DataNode *node) const =0
Checks if a node exists in the DataStorage.
#define AccessByItk_2(mitkImage, itkImageTypeFunction, arg1, arg2)
virtual void Remove(const mitk::DataNode *node)=0
Removes node from the DataStorage.
ModuleResource GetResource(const std::string &path) const
Definition: usModule.cpp:267
mitk::BaseGeometry * GetGeometry(int t=0) const
Return the geometry, which is a TimeGeometry, of the data as non-const pointer.
Definition: mitkBaseData.h:129
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:66
static Pointer New()
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 itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.