41 #include <vtkImageData.h> 42 #include <vtkSmartPointer.h> 55 #define ROUND(a) ((a) > 0 ? (int)((a) + 0.5) : -(int)(0.5 - (a))) 57 bool mitk::SegTool2D::m_SurfaceInterpolationEnabled =
true;
60 :
Tool(type, interactorModule), m_LastEventSender(nullptr), m_LastEventSlice(0), m_Contourmarkername(
"Position"), m_ShowMarkerNodes(false)
82 int &affectedDimension,
95 imageNormal0.Normalize();
96 imageNormal1.Normalize();
97 imageNormal2.Normalize();
99 imageNormal0.SetVnlVector(vnl_cross_3d<ScalarType>(normal.GetVnlVector(), imageNormal0.GetVnlVector()));
100 imageNormal1.SetVnlVector(vnl_cross_3d<ScalarType>(normal.GetVnlVector(), imageNormal1.GetVnlVector()));
101 imageNormal2.SetVnlVector(vnl_cross_3d<ScalarType>(normal.GetVnlVector(), imageNormal2.GetVnlVector()));
105 if (imageNormal2.GetNorm() <=
eps)
107 affectedDimension = 2;
110 else if (imageNormal1.GetNorm() <=
eps)
112 affectedDimension = 1;
115 else if (imageNormal0.GetNorm() <=
eps)
117 affectedDimension = 0;
121 affectedDimension = -1;
129 plane->
Project(testPoint, projectedPoint);
133 imageGeometry->
WorldToIndex(projectedPoint, indexPoint);
134 affectedSlice =
ROUND(indexPoint[affectedDimension]);
135 MITK_DEBUG <<
"indexPoint " << indexPoint <<
" affectedDimension " << affectedDimension <<
" affectedSlice " 139 if (affectedSlice < 0 || affectedSlice >= static_cast<int>(image->
GetDimension(affectedDimension)))
146 const Image *workingImage,
148 bool detectIntersection)
150 if (!m_SurfaceInterpolationEnabled)
156 if (detectIntersection)
162 contourExtractor->SetInput(slice2);
163 contourExtractor->Update();
164 contour = contourExtractor->GetOutput();
166 if (contour->GetVtkPolyData()->GetNumberOfPoints() == 0)
177 contourExtractor->SetInput(slice);
178 contourExtractor->Update();
179 contour = contourExtractor->GetOutput();
182 timeSelector->SetInput(workingImage);
183 timeSelector->SetTimeNr(0);
184 timeSelector->SetChannelNr(0);
185 timeSelector->Update();
188 if (contour->GetVtkPolyData()->GetNumberOfPoints() != 0 && dimRefImg->GetDimension() == 3)
191 contour->DisconnectPipeline();
218 if (!image || !planeGeometry)
224 vtkSmartPointer<mitkVtkImageOverwrite> reslice = vtkSmartPointer<mitkVtkImageOverwrite>::New();
226 reslice->SetOverwriteMode(
false);
231 extractor->SetInput(image);
232 extractor->SetTimeStep(timeStep);
233 extractor->SetWorldGeometry(planeGeometry);
234 extractor->SetVtkOutputRequest(
false);
238 extractor->SetComponent(component);
240 extractor->Modified();
256 auto *workingImage =
dynamic_cast<Image *
>(workingNode->GetData());
273 auto *referenceImage =
dynamic_cast<Image *
>(referenceNode->GetData());
279 int displayedComponent = 0;
280 if (referenceNode->GetIntProperty(
"Image.Displayed Component", displayedComponent))
297 const auto *abstractTransformGeometry(
300 if (planeGeometry && slice && !abstractTransformGeometry)
303 auto *
image =
dynamic_cast<Image *
>(workingNode->GetData());
311 unsigned int timeStep)
313 if (!planeGeometry || !slice)
316 SliceInformation sliceInfo(slice, const_cast<mitk::PlaneGeometry *>(planeGeometry), timeStep);
319 auto *
image =
dynamic_cast<Image *
>(workingNode->GetData());
323 if (m_SurfaceInterpolationEnabled)
330 bool writeSliceToVolume)
332 std::vector<mitk::Surface::Pointer> contourList;
333 contourList.reserve(sliceList.size());
337 auto *
image =
dynamic_cast<Image *
>(workingNode->GetData());
340 timeSelector->SetInput(image);
341 timeSelector->SetTimeNr(0);
342 timeSelector->SetChannelNr(0);
343 timeSelector->Update();
346 for (
unsigned int i = 0; i < sliceList.size(); ++i)
349 if (writeSliceToVolume)
351 if (m_SurfaceInterpolationEnabled && dimRefImg->GetDimension() == 3)
353 currentSliceInfo.
slice->DisconnectPipeline();
354 contourExtractor->SetInput(currentSliceInfo.
slice);
355 contourExtractor->Update();
357 contour->DisconnectPipeline();
359 contourList.push_back(contour);
369 auto *
image =
dynamic_cast<Image *
>(workingNode->GetData());
374 auto *undoOperation =
377 dynamic_cast<SlicedGeometry3D *>(originalSlice->GetGeometry()),
384 vtkSmartPointer<mitkVtkImageOverwrite> reslice = vtkSmartPointer<mitkVtkImageOverwrite>::New();
387 reslice->SetInputSlice(sliceInfo.
slice->GetVtkImageData());
390 reslice->SetOverwriteMode(
true);
394 extractor->SetInput(image);
395 extractor->SetTimeStep(sliceInfo.
timestep);
396 extractor->SetWorldGeometry(sliceInfo.
plane);
397 extractor->SetVtkOutputRequest(
false);
398 extractor->SetResliceTransformByGeometry(image->GetGeometry(sliceInfo.
timestep));
400 extractor->Modified();
405 image->GetVtkImageData()->Modified();
411 extractor->GetOutput(),
418 new OperationEvent(DiffSliceOperationApplier::GetInstance(), doOperation, undoOperation,
"Segmentation");
426 undoOperation =
nullptr;
427 doOperation =
nullptr;
433 m_ShowMarkerNodes = status;
438 m_SurfaceInterpolationEnabled = enabled;
456 ->GetPlaneGeometry(0));
458 unsigned int size = service->GetNumberOfPlanePositions();
459 unsigned int id = service->AddNewPlanePosition(plane, slicePosition);
463 plane->Map(plane->GetCenter(), p1);
465 p2[0] -= plane->GetSpacing()[0];
466 p2[1] -= plane->GetSpacing()[1];
467 contourMarker->PlaceFigure(p1);
468 contourMarker->SetCurrentControlPoint(p1);
469 contourMarker->SetPlaneGeometry(const_cast<PlaneGeometry *>(plane));
471 std::stringstream markerStream;
474 markerStream << m_Contourmarkername;
476 markerStream <<
id + 1;
480 rotatedContourNode->SetData(contourMarker);
483 rotatedContourNode->SetBoolProperty(
"PlanarFigureInitializedWindow",
true,
m_LastEventSender);
484 rotatedContourNode->SetProperty(
"includeInBoundingBox",
BoolProperty::New(
false));
486 rotatedContourNode->SetProperty(
"planarfigure.drawcontrolpoints",
BoolProperty::New(
false));
487 rotatedContourNode->SetProperty(
"planarfigure.drawname",
BoolProperty::New(
false));
488 rotatedContourNode->SetProperty(
"planarfigure.drawoutline",
BoolProperty::New(
false));
489 rotatedContourNode->SetProperty(
"planarfigure.drawshadow",
BoolProperty::New(
false));
502 mitk::DataStorage::SetOfObjects::ConstPointer markers =
505 for (
auto iter = markers->begin(); iter != markers->end(); ++iter)
507 std::string nodeName = (*iter)->GetName();
508 unsigned int t = nodeName.find_last_of(
" ");
509 unsigned int markerId = atof(nodeName.substr(t + 1).c_str()) - 1;
523 MITK_ERROR <<
"********************************************************************************" << std::endl
524 <<
" " << message << std::endl
525 <<
"********************************************************************************" << std::endl
527 <<
" If your image is rotated or the 2D views don't really contain the patient image, try to press the " 528 "button next to the image selection. " 531 <<
" Please file a BUG REPORT: " << std::endl
532 <<
" https://phabricator.mitk.org/" << std::endl
533 <<
" Contain the following information:" << std::endl
534 <<
" - What image were you working on?" << std::endl
535 <<
" - Which region of the image?" << std::endl
536 <<
" - Which tool did you use?" << std::endl
537 <<
" - What did you do?" << std::endl
538 <<
" - What happened (not)? What did you expect?" << std::endl;
541 template <
typename TPixel,
unsigned int VImageDimension>
547 typedef itk::Image<TPixel, VImageDimension> SliceType;
549 typename SliceType::Pointer sourceSliceITK;
554 typedef itk::ImageRegionIterator<SliceType> OutputIteratorType;
555 typedef itk::ImageRegionConstIterator<SliceType> InputIteratorType;
557 InputIteratorType inputIterator(sourceSliceITK, sourceSliceITK->GetLargestPossibleRegion());
558 OutputIteratorType outputIterator(targetSlice, targetSlice->GetLargestPossibleRegion());
560 outputIterator.GoToBegin();
561 inputIterator.GoToBegin();
564 assert(workingImage);
566 int activePixelValue = workingImage->GetActiveLabel()->GetValue();
568 if (activePixelValue == 0)
570 while (!outputIterator.IsAtEnd())
572 if (inputIterator.Get() != 0)
574 outputIterator.Set(overwritevalue);
580 else if (overwritevalue != 0)
582 while (!outputIterator.IsAtEnd())
584 auto targetValue =
static_cast<int>(outputIterator.Get());
585 if (inputIterator.Get() != 0)
587 if (!workingImage->GetLabel(targetValue)->GetLocked())
589 outputIterator.Set(overwritevalue);
592 if (targetValue == overwritevalue)
594 outputIterator.Set(inputIterator.Get());
603 while (!outputIterator.IsAtEnd())
605 const int targetValue = outputIterator.Get();
606 if (inputIterator.Get() != 0)
608 if (targetValue == activePixelValue)
609 outputIterator.Set(overwritevalue);
621 if ((!targetSlice) || (!sourceSlice))
ServiceReferenceU GetServiceReference(const std::string &clazz)
mitk::Stepper * GetSlice()
Get the Stepper through the slices.
Super class for all position events.
virtual SetOfObjects::ConstPointer GetDerivations(const DataNode *node, const NodePredicateBase *condition=nullptr, bool onlyDirectDerivations=true) const =0
returns a set of derived objects for a given node.
Vector3D GetAxisVector(unsigned int direction) const
Get vector along bounding-box in the specified direction in mm.
An Operation for applying an edited slice to the volume.
virtual const PlaneGeometry * GetCurrentWorldPlaneGeometry()
Get the current 2D-worldgeometry (m_CurrentWorldPlaneGeometry) used for 2D-rendering.
Point3D GetCenter() const
Get the center of the bounding-box in mm.
virtual bool Project(const mitk::Point3D &pt3d_mm, mitk::Point3D &projectedPt3d_mm) const
Project a 3D point given in mm (pt3d_mm) onto the 2D geometry. The result is a 3D point in mm (projec...
virtual void Add(DataNode *node, const DataStorage::SetOfObjects *parents=nullptr)=0
Adds a DataNode containing a data object to its internal storage.
void * GetService(const ServiceReferenceBase &reference)
#define AccessFixedDimensionByItk_3(mitkImage, itkImageTypeFunction, dimension, arg1, arg2, arg3)
BaseRenderer * GetSender() const
const mitk::TimeGeometry * GetTimeGeometry() const
Return the TimeGeometry of the data as const pointer.
unsigned int GetDimension() const
Get dimension of the image.
static RenderingManager * GetInstance()
virtual unsigned int GetTimeStep() const
virtual MapperSlotId GetMapperID()
Get the MapperSlotId to use.
Image class for storing images.
SlicedGeometry3D * GetSlicedGeometry(unsigned int t=0) const
Convenience access method for the geometry, which is of type SlicedGeometry3D (or a sub-class of it)...
void AddNewContours(std::vector< Surface::Pointer > newContours)
Adds new extracted contours to the list. If one or more contours at a given position already exist th...
mitk::Image::Pointer image
const Point3D GetOrigin() const
Get the origin, e.g. the upper-left corner of the plane.
static Pointer New(const char *_arg)
void WorldToIndex(const mitk::Point3D &pt_mm, mitk::Point3D &pt_units) const
Convert world coordinates (in mm) of a point to (continuous!) index coordinates.
Describes the geometry of a data object consisting of slices.
bool RemoveContour(ContourPositionInformation contourInfo)
Removes the contour for a given plane for the current selected segmenation.
Vector3D GetNormal() const
Normal of the plane.
void MITKCORE_EXPORT CastToItkImage(const mitk::Image *mitkImage, itk::SmartPointer< ItkOutputImageType > &itkOutputImage)
Cast an mitk::Image to an itk::Image with a specific type.
static SurfaceInterpolationController * GetInstance()
virtual BaseGeometry::Pointer GetGeometryForTimeStep(TimeStepType timeStep) const =0
Returns the geometry which corresponds to the given time step.
virtual bool SetOperationEvent(UndoStackItem *stackItem)=0
static UndoModel * GetCurrentUndoModel()
gives access to the currently used UndoModel Introduced to access special functions of more specific ...
LabelSetImage class for handling labels and layers in a segmentation session.
MITKCORE_EXPORT const ScalarType eps
virtual SliceNavigationController * GetSliceNavigationController()
virtual unsigned int GetPos() const
Describes a two-dimensional, rectangular plane.
static void IncCurrObjectEventId()
Increases the current ObjectEventId For example if a button click generates operations the ObjectEven...
const mitk::BaseGeometry * GetCurrentGeometry3D()
Returns the BaseGeometry of the currently selected time step.
void AddNewContour(Surface::Pointer newContour)
Adds a new extracted contour to the list.
mitk::BaseGeometry * GetGeometry(int t=0) const
Return the geometry, which is a TimeGeometry, of the data as non-const pointer.
static ModuleContext * GetModuleContext()
Returns the module context of the calling module.
static void IncCurrGroupEventId()
Increases the current GroupEventId For example if a button click generates operations the GroupEventI...
void RequestUpdateAll(RequestType type=REQUEST_UPDATE_ALL)
BaseGeometry Describes the geometry of a data object.
Represents a pair of operations: undo and the according redo.
Class for nodes of the DataTree.
static void Erode(mitk::Image::Pointer &image, int factor, StructuralElementType structuralElement)
Perform morphological operation on 2D, 3D or 3D+t segmentation.