Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkSetRegionTool.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 "mitkSetRegionTool.h"
18 
19 #include "mitkToolManager.h"
20 
21 #include "mitkBaseRenderer.h"
22 #include "mitkImageDataItem.h"
23 #include "mitkLabelSetImage.h"
24 #include "mitkLegacyAdaptors.h"
25 
26 #include <mitkITKImageImport.h>
29 
30 #include <itkBinaryFillholeImageFilter.h>
31 #include <itkConnectedThresholdImageFilter.h>
32 
33 mitk::SetRegionTool::SetRegionTool(int paintingPixelValue)
34  : FeedbackContourTool("PressMoveRelease"), m_PaintingPixelValue(paintingPixelValue)
35 {
36 }
37 
39 {
40 }
41 
43 {
44  CONNECT_FUNCTION("PrimaryButtonPressed", OnMousePressed);
45  CONNECT_FUNCTION("Release", OnMouseReleased);
46  CONNECT_FUNCTION("Move", OnMouseMoved);
47 }
48 
50 {
51  Superclass::Activated();
52 }
53 
55 {
56  Superclass::Deactivated();
57 }
58 
60 {
61  mitk::InteractionPositionEvent *positionEvent = dynamic_cast<mitk::InteractionPositionEvent *>(interactionEvent);
62  if (!positionEvent)
63  return;
64 
65  m_LastEventSender = positionEvent->GetSender();
66  m_LastEventSlice = m_LastEventSender->GetSlice();
67 
68  // 1. Get the working image
70  if (workingSlice.IsNull())
71  return; // can't do anything without the segmentation
72 
73  // if click was outside the image, don't continue
74  const BaseGeometry *sliceGeometry = workingSlice->GetGeometry();
75  itk::Index<3> projectedPointIn2D;
76  sliceGeometry->WorldToIndex(positionEvent->GetPositionInWorld(), projectedPointIn2D);
77  if (!sliceGeometry->IsIndexInside(projectedPointIn2D))
78  {
79  MITK_ERROR << "point apparently not inside segmentation slice" << std::endl;
80  return; // can't use that as a seed point
81  }
82 
83  typedef itk::Image<DefaultSegmentationDataType, 2> InputImageType;
84  typedef InputImageType::IndexType IndexType;
85  typedef itk::ConnectedThresholdImageFilter<InputImageType, InputImageType> RegionGrowingFilterType;
87 
88  // convert world coordinates to image indices
89  IndexType seedIndex;
90  sliceGeometry->WorldToIndex(positionEvent->GetPositionInWorld(), seedIndex);
91 
92  // perform region growing in desired segmented region
94  CastToItkImage(workingSlice, itkImage);
95  regionGrower->SetInput(itkImage);
96  regionGrower->AddSeed(seedIndex);
97 
98  InputImageType::PixelType bound = itkImage->GetPixel(seedIndex);
99 
100  regionGrower->SetLower(bound);
101  regionGrower->SetUpper(bound);
102  regionGrower->SetReplaceValue(1);
103 
106 
107  fillHolesFilter->SetInput(regionGrower->GetOutput());
108  fillHolesFilter->SetForegroundValue(1);
109 
110  // Store result and preview
111  mitk::Image::Pointer resultImage = mitk::GrabItkImageMemory(fillHolesFilter->GetOutput());
112  resultImage->SetGeometry(workingSlice->GetGeometry());
113  // Get the current working color
114  DataNode *workingNode(m_ToolManager->GetWorkingData(0));
115  if (!workingNode)
116  return;
117 
118  Image *image = dynamic_cast<Image *>(workingNode->GetData());
119  LabelSetImage *labelImage = dynamic_cast<LabelSetImage *>(image);
120  int activeColor = 1;
121  if (labelImage != 0)
122  {
123  activeColor = labelImage->GetActiveLabel()->GetValue();
124  }
125 
127  contourextractor->SetInput(resultImage);
128  contourextractor->Update();
129 
130  mitk::ContourModel::Pointer awesomeContour = contourextractor->GetOutput();
134 }
135 
137 {
138  mitk::InteractionPositionEvent *positionEvent = dynamic_cast<mitk::InteractionPositionEvent *>(interactionEvent);
139  if (!positionEvent)
140  return;
141 
142  assert(positionEvent->GetSender()->GetRenderWindow());
143  // 1. Hide the feedback contour, find out which slice the user clicked, find out which slice of the toolmanager's
144  // working image corresponds to that
147 
148  int timeStep = positionEvent->GetSender()->GetTimeStep();
149 
150  DataNode *workingNode(m_ToolManager->GetWorkingData(0));
151  if (!workingNode)
152  return;
153 
154  Image *image = dynamic_cast<Image *>(workingNode->GetData());
155  const PlaneGeometry *planeGeometry((positionEvent->GetSender()->GetCurrentWorldPlaneGeometry()));
156  if (!image || !planeGeometry)
157  return;
158 
160 
161  if (slice.IsNull())
162  {
163  MITK_ERROR << "Unable to extract slice." << std::endl;
164  return;
165  }
166 
169  slice, feedbackContour, false, false); // false: don't add 0.5 (done by FillContourInSlice)
170  // false: don't constrain the contour to the image's inside
171  if (projectedContour.IsNull())
172  return;
173 
174  LabelSetImage *labelImage = dynamic_cast<LabelSetImage *>(image);
175  int activeColor = 1;
176  if (labelImage != 0)
177  {
178  activeColor = labelImage->GetActiveLabel()->GetValue();
179  }
180 
182  projectedContour, timeStep, slice, image, m_PaintingPixelValue * activeColor);
183 
184  this->WriteBackSegmentationResult(positionEvent, slice);
185 }
186 
188 {
189 }
ContourModel is a structure of linked vertices defining a contour in 3D space. The vertices are store...
Super class for all position events.
void SetFeedbackContour(ContourModel::Pointer)
itk::SmartPointer< Self > Pointer
virtual unsigned int GetSlice() const
BaseRenderer * GetSender() const
Image::Pointer GetAffectedImageSliceAs2DImage(const InteractionPositionEvent *positionEvent, const Image *image, unsigned int component=0)
Extract the slice of an image that the user just scribbles on. The given component denotes the vector...
virtual void OnMousePressed(StateMachineAction *, InteractionEvent *)
virtual void Deactivated() override
Called when the tool gets deactivated.
static void FillContourInSlice(ContourModel *projectedContour, Image *sliceImage, mitk::Image::Pointer workingImage, int paintingPixelValue=1)
Fill a contour in a 2D slice with a specified pixel value at time step 0.
#define MITK_ERROR
Definition: mitkLogMacros.h:24
bool IsIndexInside(const mitk::Point3D &index) const
Test whether the point p ((continous!)index coordinates in units) is inside the bounding box...
virtual void OnMouseMoved(StateMachineAction *, InteractionEvent *)
SetRegionTool(int paintingPixelValue=1)
virtual const PlaneGeometry * GetCurrentWorldPlaneGeometry()
Get the current 2D-worldgeometry (m_CurrentWorldPlaneGeometry) used for 2D-rendering.
Image::Pointer GrabItkImageMemory(itk::SmartPointer< ItkOutputImageType > &itkimage, mitk::Image *mitkImage=nullptr, const BaseGeometry *geometry=nullptr, bool update=true)
Grabs the memory of an itk::Image (with a specific type) and puts it into an mitk::Image.The memory is managed by the mitk::Image after calling this function. The itk::Image remains valid until the mitk::Image decides to free the memory.
virtual void OnMouseReleased(StateMachineAction *, InteractionEvent *)
itk::Image< double, 3 > InputImageType
static RenderingManager * GetInstance()
Represents an action, that is executed after a certain event (in statemachine-mechanism) TODO: implem...
Image class for storing images.
Definition: mitkImage.h:76
ContourModel::Pointer ProjectContourTo2DSlice(Image *slice, ContourModel *contourIn3D, bool correctionForIpSegmentation=false, bool constrainToInside=true)
Projects a contour onto an image point by point. Converts from world to index coordinates.
mitk::Label * GetActiveLabel(unsigned int layer=0)
Returns the active label of a specific layer.
virtual unsigned int GetTimeStep() const
void RequestUpdate(vtkRenderWindow *renderWindow)
Base class for tools that use a contour for feedback.
void MITKCORE_EXPORT CastToItkImage(const mitk::Image *mitkImage, itk::SmartPointer< ItkOutputImageType > &itkOutputImage)
Cast an mitk::Image to an itk::Image with a specific type.
LabelSetImage class for handling labels and layers in a segmentation session.
unsigned short PixelType
Describes a two-dimensional, rectangular plane.
#define CONNECT_FUNCTION(a, f)
PixelType GetValue() const
Definition: mitkLabel.cpp:171
void ConnectActionsAndFunctions() override
vtkRenderWindow * GetRenderWindow() const
Access the RenderWindow into which this renderer renders.
BaseGeometry Describes the geometry of a data object.
Image::Pointer GetAffectedWorkingSlice(const InteractionPositionEvent *)
Extract the slice of the currently selected working image that the user just scribbles on...
Class for nodes of the DataTree.
Definition: mitkDataNode.h:66
virtual void Activated() override
Called when the tool gets activated.
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.