Medical Imaging Interaction Toolkit  2018.4.99-b585543d
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 (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 "mitkSetRegionTool.h"
14 
15 #include "mitkToolManager.h"
16 
17 #include "mitkBaseRenderer.h"
18 #include "mitkImageDataItem.h"
19 #include "mitkLabelSetImage.h"
20 
21 #include <mitkITKImageImport.h>
24 
25 #include <itkBinaryFillholeImageFilter.h>
26 #include <itkConnectedThresholdImageFilter.h>
27 
28 mitk::SetRegionTool::SetRegionTool(int paintingPixelValue)
29  : FeedbackContourTool("PressMoveRelease"), m_PaintingPixelValue(paintingPixelValue)
30 {
31 }
32 
34 {
35 }
36 
38 {
39  CONNECT_FUNCTION("PrimaryButtonPressed", OnMousePressed);
42 }
43 
45 {
46  Superclass::Activated();
47 }
48 
50 {
51  Superclass::Deactivated();
52 }
53 
55 {
56  auto *positionEvent = dynamic_cast<mitk::InteractionPositionEvent *>(interactionEvent);
57  if (!positionEvent)
58  return;
59 
60  m_LastEventSender = positionEvent->GetSender();
62 
63  // 1. Get the working image
65  if (workingSlice.IsNull())
66  return; // can't do anything without the segmentation
67 
68  // if click was outside the image, don't continue
69  const BaseGeometry *sliceGeometry = workingSlice->GetGeometry();
70  itk::Index<3> projectedPointIn2D;
71  sliceGeometry->WorldToIndex(positionEvent->GetPositionInWorld(), projectedPointIn2D);
72  if (!sliceGeometry->IsIndexInside(projectedPointIn2D))
73  {
74  MITK_WARN << "Point outside of segmentation slice." << std::endl;
75  return; // can't use that as a seed point
76  }
77 
78  typedef itk::Image<DefaultSegmentationDataType, 2> InputImageType;
79  typedef InputImageType::IndexType IndexType;
80  typedef itk::ConnectedThresholdImageFilter<InputImageType, InputImageType> RegionGrowingFilterType;
81  RegionGrowingFilterType::Pointer regionGrower = RegionGrowingFilterType::New();
82 
83  // convert world coordinates to image indices
84  IndexType seedIndex;
85  sliceGeometry->WorldToIndex(positionEvent->GetPositionInWorld(), seedIndex);
86 
87  // perform region growing in desired segmented region
88  InputImageType::Pointer itkImage = InputImageType::New();
89  CastToItkImage(workingSlice, itkImage);
90  regionGrower->SetInput(itkImage);
91  regionGrower->AddSeed(seedIndex);
92 
93  InputImageType::PixelType bound = itkImage->GetPixel(seedIndex);
94 
95  regionGrower->SetLower(bound);
96  regionGrower->SetUpper(bound);
97  regionGrower->SetReplaceValue(1);
98 
99  itk::BinaryFillholeImageFilter<InputImageType>::Pointer fillHolesFilter =
100  itk::BinaryFillholeImageFilter<InputImageType>::New();
101 
102  fillHolesFilter->SetInput(regionGrower->GetOutput());
103  fillHolesFilter->SetForegroundValue(1);
104 
105  // Store result and preview
106  mitk::Image::Pointer resultImage = mitk::GrabItkImageMemory(fillHolesFilter->GetOutput());
107  resultImage->SetGeometry(workingSlice->GetGeometry());
108  // Get the current working color
109  DataNode *workingNode(m_ToolManager->GetWorkingData(0));
110  if (!workingNode)
111  return;
112 
114  contourextractor->SetInput(resultImage);
115  contourextractor->Update();
116 
117  mitk::ContourModel::Pointer awesomeContour = contourextractor->GetOutput();
118  auto t = positionEvent->GetSender()->GetTimeStep();
119 
122  : awesomeContour);
123 
125  mitk::RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow());
126 }
127 
129 {
130  auto *positionEvent = dynamic_cast<mitk::InteractionPositionEvent *>(interactionEvent);
131  if (!positionEvent)
132  return;
133 
134  assert(positionEvent->GetSender()->GetRenderWindow());
135  // 1. Hide the feedback contour, find out which slice the user clicked, find out which slice of the toolmanager's
136  // working image corresponds to that
138  mitk::RenderingManager::GetInstance()->RequestUpdate(positionEvent->GetSender()->GetRenderWindow());
139 
140  int timeStep = positionEvent->GetSender()->GetTimeStep();
141 
142  DataNode *workingNode(m_ToolManager->GetWorkingData(0));
143  if (!workingNode)
144  return;
145 
146  auto *image = dynamic_cast<Image *>(workingNode->GetData());
147  const PlaneGeometry *planeGeometry((positionEvent->GetSender()->GetCurrentWorldPlaneGeometry()));
148  if (!image || !planeGeometry)
149  return;
150 
152 
153  if (slice.IsNull())
154  {
155  MITK_ERROR << "Unable to extract slice." << std::endl;
156  return;
157  }
158 
161  slice, feedbackContour, false, false); // false: don't add 0.5 (done by FillContourInSlice)
162  // false: don't constrain the contour to the image's inside
163  if (projectedContour.IsNull())
164  return;
165 
166  auto *labelImage = dynamic_cast<LabelSetImage *>(image);
167  int activeColor = 1;
168  if (labelImage != nullptr)
169  {
170  activeColor = labelImage->GetActiveLabel()->GetValue();
171  }
172 
174  projectedContour, timeStep, slice, image, m_PaintingPixelValue * activeColor);
175 
176  this->WriteBackSegmentationResult(positionEvent, slice);
177 }
178 
180 {
181 }
unsigned int m_LastEventSlice
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)
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 unsigned int GetSlice() const
virtual void OnMousePressed(StateMachineAction *, InteractionEvent *)
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:20
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)
BaseRenderer * m_LastEventSender
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 *)
#define MITK_WARN
Definition: mitkLogMacros.h:19
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:72
void WriteBackSegmentationResult(const InteractionPositionEvent *, Image *)
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.
mitk::Image::Pointer image
PixelType GetValue() const
Definition: mitkLabel.cpp:169
void WorldToIndex(const mitk::Point3D &pt_mm, mitk::Point3D &pt_units) const
Convert world coordinates (in mm) of a point to (continuous!) index coordinates.
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.
ToolManager * m_ToolManager
Definition: mitkTool.h:228
Describes a two-dimensional, rectangular plane.
#define CONNECT_FUNCTION(a, f)
static ContourModel::Pointer MoveZerothContourTimeStep(const ContourModel *contour, unsigned int timeStep)
Move the contour in time step 0 to to a new contour model at the given time step. ...
void ConnectActionsAndFunctions() override
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:57
DataVectorType GetWorkingData()
void Activated() override
Called when the tool gets activated.