45 #include <vtkImageData.h>
46 #include <vtkSmartPointer.h>
59 #define ROUND(a) ((a) > 0 ? (int)((a) + 0.5) : -(int)(0.5 - (a)))
61 bool mitk::SegTool2D::m_SurfaceInterpolationEnabled =
true;
64 :
Tool(type), m_LastEventSender(NULL), m_LastEventSlice(0), m_Contourmarkername(
"Position"), m_ShowMarkerNodes(false)
86 int &affectedDimension,
99 imageNormal0.Normalize();
100 imageNormal1.Normalize();
101 imageNormal2.Normalize();
103 imageNormal0.SetVnlVector(vnl_cross_3d<ScalarType>(normal.GetVnlVector(), imageNormal0.GetVnlVector()));
104 imageNormal1.SetVnlVector(vnl_cross_3d<ScalarType>(normal.GetVnlVector(), imageNormal1.GetVnlVector()));
105 imageNormal2.SetVnlVector(vnl_cross_3d<ScalarType>(normal.GetVnlVector(), imageNormal2.GetVnlVector()));
109 if (imageNormal2.GetNorm() <=
eps)
111 affectedDimension = 2;
114 else if (imageNormal1.GetNorm() <=
eps)
116 affectedDimension = 1;
119 else if (imageNormal0.GetNorm() <=
eps)
121 affectedDimension = 0;
125 affectedDimension = -1;
133 plane->
Project(testPoint, projectedPoint);
137 imageGeometry->
WorldToIndex(projectedPoint, indexPoint);
138 affectedSlice =
ROUND(indexPoint[affectedDimension]);
139 MITK_DEBUG <<
"indexPoint " << indexPoint <<
" affectedDimension " << affectedDimension <<
" affectedSlice "
143 if (affectedSlice < 0 || affectedSlice >= static_cast<int>(image->
GetDimension(affectedDimension)))
150 const Image *workingImage,
152 bool detectIntersection)
154 if (!m_SurfaceInterpolationEnabled)
160 if (detectIntersection)
166 contourExtractor->SetInput(slice2);
167 contourExtractor->Update();
168 contour = contourExtractor->GetOutput();
170 if (contour->GetVtkPolyData()->GetNumberOfPoints() == 0)
181 contourExtractor->SetInput(slice);
182 contourExtractor->Update();
183 contour = contourExtractor->GetOutput();
186 timeSelector->SetInput(workingImage);
187 timeSelector->SetTimeNr(0);
188 timeSelector->SetChannelNr(0);
189 timeSelector->Update();
192 if (contour->GetVtkPolyData()->GetNumberOfPoints() != 0 && dimRefImg->GetDimension() == 3)
195 contour->DisconnectPipeline();
222 if (!image || !planeGeometry)
230 reslice->SetOverwriteMode(
false);
235 extractor->SetInput(image);
236 extractor->SetTimeStep(timeStep);
237 extractor->SetWorldGeometry(planeGeometry);
238 extractor->SetVtkOutputRequest(
false);
242 extractor->SetComponent(component);
244 extractor->Modified();
254 DataNode *workingNode(m_ToolManager->GetWorkingData(0));
260 Image *workingImage =
dynamic_cast<Image *
>(workingNode->GetData());
266 return GetAffectedImageSliceAs2DImage(positionEvent, workingImage);
271 DataNode *referenceNode(m_ToolManager->GetReferenceData(0));
277 Image *referenceImage =
dynamic_cast<Image *
>(referenceNode->GetData());
283 int displayedComponent = 0;
284 if (referenceNode->GetIntProperty(
"Image.Displayed Component", displayedComponent))
287 return GetAffectedImageSliceAs2DImage(positionEvent, referenceImage, displayedComponent);
291 return GetAffectedImageSliceAs2DImage(positionEvent, referenceImage);
304 if (planeGeometry && slice && !abstractTransformGeometry)
306 DataNode *workingNode(m_ToolManager->GetWorkingData(0));
307 Image *image =
dynamic_cast<Image *
>(workingNode->GetData());
309 this->WriteBackSegmentationResult(planeGeometry, slice, timeStep);
315 unsigned int timeStep)
317 if (!planeGeometry || !slice)
320 SliceInformation sliceInfo(slice, const_cast<mitk::PlaneGeometry *>(planeGeometry), timeStep);
321 this->WriteSliceToVolume(sliceInfo);
322 DataNode *workingNode(m_ToolManager->GetWorkingData(0));
323 Image *image =
dynamic_cast<Image *
>(workingNode->GetData());
325 this->UpdateSurfaceInterpolation(slice, image, planeGeometry,
false);
327 if (m_SurfaceInterpolationEnabled)
328 this->AddContourmarker();
334 bool writeSliceToVolume)
336 std::vector<mitk::Surface::Pointer> contourList;
337 contourList.reserve(sliceList.size());
340 DataNode *workingNode(m_ToolManager->GetWorkingData(0));
341 Image *image =
dynamic_cast<Image *
>(workingNode->GetData());
344 timeSelector->SetInput(image);
345 timeSelector->SetTimeNr(0);
346 timeSelector->SetChannelNr(0);
347 timeSelector->Update();
350 for (
unsigned int i = 0; i < sliceList.size(); ++i)
353 if (writeSliceToVolume)
354 this->WriteSliceToVolume(currentSliceInfo);
355 if (m_SurfaceInterpolationEnabled && dimRefImg->GetDimension() == 3)
357 currentSliceInfo.
slice->DisconnectPipeline();
358 contourExtractor->SetInput(currentSliceInfo.
slice);
359 contourExtractor->Update();
361 contour->DisconnectPipeline();
363 contourList.push_back(contour);
372 DataNode *workingNode(m_ToolManager->GetWorkingData(0));
373 Image *image =
dynamic_cast<Image *
>(workingNode->GetData());
381 dynamic_cast<SlicedGeometry3D *>(originalSlice->GetGeometry()),
391 reslice->SetInputSlice(sliceInfo.
slice->GetVtkImageData());
394 reslice->SetOverwriteMode(
true);
398 extractor->SetInput(image);
399 extractor->SetTimeStep(sliceInfo.
timestep);
400 extractor->SetWorldGeometry(sliceInfo.
plane);
401 extractor->SetVtkOutputRequest(
false);
402 extractor->SetResliceTransformByGeometry(image->GetGeometry(sliceInfo.
timestep));
404 extractor->Modified();
409 image->GetVtkImageData()->Modified();
415 extractor->GetOutput(),
422 new OperationEvent(DiffSliceOperationApplier::GetInstance(), doOperation, undoOperation,
"Segmentation");
430 undoOperation = NULL;
437 m_ShowMarkerNodes = status;
442 m_SurfaceInterpolationEnabled = enabled;
447 if (m_LastEventSender == NULL)
454 unsigned int slicePosition = m_LastEventSender->GetSliceNavigationController()->GetSlice()->GetPos();
459 m_LastEventSender->GetSliceNavigationController()->GetCurrentGeometry3D())
460 ->GetPlaneGeometry(0));
462 unsigned int size = service->GetNumberOfPlanePositions();
463 unsigned int id = service->AddNewPlanePosition(plane, slicePosition);
471 contourMarker->PlaceFigure(p1);
472 contourMarker->SetCurrentControlPoint(p1);
473 contourMarker->SetPlaneGeometry(const_cast<PlaneGeometry *>(plane));
475 std::stringstream markerStream;
478 markerStream << m_Contourmarkername;
480 markerStream <<
id + 1;
484 rotatedContourNode->SetData(contourMarker);
487 rotatedContourNode->SetBoolProperty(
"PlanarFigureInitializedWindow",
true, m_LastEventSender);
488 rotatedContourNode->SetProperty(
"includeInBoundingBox",
BoolProperty::New(
false));
490 rotatedContourNode->SetProperty(
"planarfigure.drawcontrolpoints",
BoolProperty::New(
false));
491 rotatedContourNode->SetProperty(
"planarfigure.drawname",
BoolProperty::New(
false));
492 rotatedContourNode->SetProperty(
"planarfigure.drawoutline",
BoolProperty::New(
false));
493 rotatedContourNode->SetProperty(
"planarfigure.drawshadow",
BoolProperty::New(
false));
499 m_ToolManager->GetDataStorage()->Add(rotatedContourNode, workingNode);
507 m_ToolManager->GetDataStorage()->GetDerivations(workingNode, isMarker);
509 for (mitk::DataStorage::SetOfObjects::const_iterator iter = markers->begin(); iter != markers->end(); ++iter)
511 std::string nodeName = (*iter)->GetName();
512 unsigned int t = nodeName.find_last_of(
" ");
513 unsigned int markerId = atof(nodeName.substr(t + 1).c_str()) - 1;
519 m_ToolManager->GetDataStorage()->Add(rotatedContourNode, workingNode);
527 MITK_ERROR <<
"********************************************************************************" << std::endl
528 <<
" " << message << std::endl
529 <<
"********************************************************************************" << std::endl
531 <<
" If your image is rotated or the 2D views don't really contain the patient image, try to press the "
532 "button next to the image selection. "
535 <<
" Please file a BUG REPORT: " << std::endl
536 <<
" https://phabricator.mitk.org/" << std::endl
537 <<
" Contain the following information:" << std::endl
538 <<
" - What image were you working on?" << std::endl
539 <<
" - Which region of the image?" << std::endl
540 <<
" - Which tool did you use?" << std::endl
541 <<
" - What did you do?" << std::endl
542 <<
" - What happened (not)? What did you expect?" << std::endl;
545 template <
typename TPixel,
unsigned int VImageDimension>
551 typedef itk::Image<TPixel, VImageDimension> SliceType;
558 typedef itk::ImageRegionIterator<SliceType> OutputIteratorType;
559 typedef itk::ImageRegionConstIterator<SliceType> InputIteratorType;
561 InputIteratorType inputIterator(sourceSliceITK, sourceSliceITK->GetLargestPossibleRegion());
562 OutputIteratorType outputIterator(targetSlice, targetSlice->GetLargestPossibleRegion());
564 outputIterator.GoToBegin();
565 inputIterator.GoToBegin();
568 assert(workingImage);
572 if (activePixelValue == 0)
574 while (!outputIterator.IsAtEnd())
576 if (inputIterator.Get() != 0)
578 outputIterator.Set(overwritevalue);
584 else if (overwritevalue != 0)
586 while (!outputIterator.IsAtEnd())
588 int targetValue =
static_cast<int>(outputIterator.Get());
589 if (inputIterator.Get() != 0)
593 outputIterator.Set(overwritevalue);
596 if (targetValue == overwritevalue)
598 outputIterator.Set(inputIterator.Get());
607 while (!outputIterator.IsAtEnd())
609 const int targetValue = outputIterator.Get();
610 if (inputIterator.Get() != 0)
612 if (targetValue == activePixelValue)
613 outputIterator.Set(overwritevalue);
623 Image *targetSlice,
Image *sourceSlice,
mitk::Image *workingImage,
int paintingPixelValue,
int timestep)
625 if ((!targetSlice) || (!sourceSlice))
const Point3D GetOrigin() const
Get the origin, e.g. the upper-left corner of the plane.
ServiceReferenceU GetServiceReference(const std::string &clazz)
Super class for all position events.
itk::SmartPointer< Self > Pointer
BaseRenderer * GetSender() const
virtual bool Map(const mitk::Point3D &pt3d_mm, mitk::Point2D &pt2d_mm) const
Project a 3D point given in mm (pt3d_mm) onto the 2D geometry. The result is a 2D point in mm (pt2d_m...
mitk::Label * GetLabel(PixelType pixelValue, unsigned int layer=0) const
Returns the mitk::Label with the given pixelValue and for the given layer.
const mitk::Vector3D GetSpacing() const
Get the spacing (size of a pixel).
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.
const mitk::TimeGeometry * GetTimeGeometry() const
Return the TimeGeometry of the data as const pointer.
void * GetService(const ServiceReferenceBase &reference)
#define AccessFixedDimensionByItk_3(mitkImage, itkImageTypeFunction, dimension, arg1, arg2, arg3)
Vector3D GetNormal() const
Normal of the plane.
itk::SmartPointer< const Self > ConstPointer
Vector3D GetAxisVector(unsigned int direction) const
Get vector along bounding-box in the specified direction in mm.
static RenderingManager * GetInstance()
virtual MapperSlotId GetMapperID()
Get the MapperSlotId to use.
Image class for storing images.
mitk::Label * GetActiveLabel(unsigned int layer=0)
Returns the active label of a specific layer.
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...
Point3D GetCenter() const
Get the center of the bounding-box in mm.
static Pointer New(const char *_arg)
Describes the geometry of a data object consisting of slices.
virtual unsigned int GetTimeStep() const
bool RemoveContour(ContourPositionInformation contourInfo)
Removes the contour for a given plane for the current selected segmenation.
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...
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
SlicedGeometry3D * GetSlicedGeometry(unsigned int t=0) const
Convenience access method for the geometry, which is of type SlicedGeometry3D (or a sub-class of it)...
Describes a two-dimensional, rectangular plane.
static void IncCurrObjectEventId()
Increases the current ObjectEventId For example if a button click generates operations the ObjectEven...
void AddNewContour(Surface::Pointer newContour)
Adds a new extracted contour to the list.
PixelType GetValue() const
unsigned int GetDimension() const
Get dimension of the image.
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.
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.