21 #include <itkAddImageFilter.h>
22 #include <itkBinaryMedianImageFilter.h>
23 #include <itkBinaryThresholdImageFilter.h>
24 #include <itkConnectedThresholdImageFilter.h>
25 #include <itkConstantPadImageFilter.h>
26 #include <itkDiscreteGaussianImageFilter.h>
27 #include <itkImageRegionIteratorWithIndex.h>
28 #include <itkMultiplyImageFilter.h>
29 #include <itkRegionOfInterestImageFilter.h>
37 #include <vtkCleanPolyData.h>
38 #include <vtkPolyDataNormals.h>
39 #include <vtkQuadricDecimation.h>
44 ShowSegmentationAsSmoothedSurface::ShowSegmentationAsSmoothedSurface()
48 ShowSegmentationAsSmoothedSurface::~ShowSegmentationAsSmoothedSurface()
54 Superclass::Initialize(other);
56 bool syncVisibility =
false;
61 SetParameter(
"Sync visibility", syncVisibility);
62 SetParameter(
"Wireframe",
false);
66 SetParameter(
"Smoothing", 1.0f);
71 SetParameter(
"Decimation", 0.5f);
75 SetParameter(
"Closing", 0.0f);
83 GetPointerParameter(
"Input", image);
85 return image.IsNotNull() && GetGroupNode();
87 catch (
const invalid_argument &)
96 GetPointerParameter(
"Input", image);
99 GetParameter(
"Smoothing", smoothing);
102 GetParameter(
"Decimation", decimation);
105 GetParameter(
"Closing", closing);
108 GetParameter(
"TimeNr", timeNr);
110 if (image->GetDimension() == 4)
111 MITK_INFO <<
"CREATING SMOOTHED POLYGON MODEL (t = " << timeNr <<
')';
113 MITK_INFO <<
"CREATING SMOOTHED POLYGON MODEL";
115 MITK_INFO <<
" Smoothing = " << smoothing;
116 MITK_INFO <<
" Decimation = " << decimation;
123 typedef itk::Image<unsigned char, 3> CharImageType;
124 typedef itk::Image<unsigned short, 3> ShortImageType;
127 if (image->GetDimension() == 4)
130 imageTimeSelector->SetInput(image);
131 imageTimeSelector->SetTimeNr(timeNr);
132 imageTimeSelector->UpdateLargestPossibleRegion();
133 image = imageTimeSelector->GetOutput(0);
140 imageToItkFilter->SetInput(image);
142 catch (
const itk::ExceptionObject &e)
150 imageToItkFilter->Update();
159 bool roiFound =
false;
161 CharImageType::IndexType minIndex;
164 CharImageType::IndexType maxIndex;
167 itk::ImageRegionIteratorWithIndex<CharImageType> iter(itkImage, itkImage->GetLargestPossibleRegion());
169 for (iter.GoToBegin(); !iter.IsAtEnd(); ++iter)
171 if (iter.Get() == imageLabel)
176 CharImageType::IndexType currentIndex = iter.GetIndex();
178 for (
unsigned int dim = 0; dim < 3; ++dim)
180 minIndex[dim] =
min(currentIndex[dim], minIndex[dim]);
181 maxIndex[dim] =
max(currentIndex[dim], maxIndex[dim]);
193 MITK_ERROR <<
"Didn't found segmentation labeled with " << imageLabel <<
"!" << endl;
201 typedef itk::RegionOfInterestImageFilter<CharImageType, CharImageType> ROIFilterType;
204 CharImageType::RegionType region;
205 CharImageType::SizeType size;
207 for (
unsigned int dim = 0; dim < 3; ++dim)
209 size[dim] = maxIndex[dim] - minIndex[dim] + 1;
212 region.SetIndex(minIndex);
213 region.SetSize(size);
215 roiFilter->SetInput(itkImage);
216 roiFilter->SetRegionOfInterest(region);
217 roiFilter->ReleaseDataFlagOn();
218 roiFilter->ReleaseDataBeforeUpdateFlagOn();
220 typedef itk::ConstantPadImageFilter<CharImageType, CharImageType> PadFilterType;
223 const PadFilterType::SizeValueType pad[3] = {10, 10, 10};
225 padFilter->SetInput(roiFilter->GetOutput());
226 padFilter->SetConstant(0);
227 padFilter->SetPadLowerBound(pad);
228 padFilter->SetPadUpperBound(pad);
229 padFilter->ReleaseDataFlagOn();
230 padFilter->ReleaseDataBeforeUpdateFlagOn();
235 roiImage->DisconnectPipeline();
244 TransformType::OutputVectorType translation;
246 for (
unsigned int dim = 0; dim < 3; ++dim)
247 translation[dim] = (
int)minIndex[dim] - (int)pad[dim];
249 transform->SetIdentity();
250 transform->Translate(translation);
251 geometry->Compose(transform,
true);
259 typedef itk::BinaryMedianImageFilter<CharImageType, CharImageType> MedianFilterType;
262 CharImageType::SizeType radius = {0};
264 medianFilter->SetRadius(radius);
265 medianFilter->SetBackgroundValue(0);
266 medianFilter->SetForegroundValue(1);
267 medianFilter->SetInput(roiImage);
268 medianFilter->ReleaseDataFlagOn();
269 medianFilter->ReleaseDataBeforeUpdateFlagOn();
270 medianFilter->Update();
278 unsigned int surfaceRatio = (
unsigned int)((1.0f - closing) * 100.0f);
284 closingFilter->SetInput(medianFilter->GetOutput());
285 closingFilter->ReleaseDataFlagOn();
286 closingFilter->ReleaseDataBeforeUpdateFlagOn();
287 closingFilter->SetSurfaceRatio(surfaceRatio);
288 closingFilter->Update();
292 closedImage->DisconnectPipeline();
294 medianFilter =
nullptr;
295 closingFilter =
nullptr;
303 typedef itk::BinaryThresholdImageFilter<ShortImageType, FloatImageType> BinaryThresholdToFloatFilterType;
307 binThresToFloatFilter->SetInput(closedImage);
308 binThresToFloatFilter->SetLowerThreshold(1);
309 binThresToFloatFilter->SetUpperThreshold(1);
310 binThresToFloatFilter->SetInsideValue(100);
311 binThresToFloatFilter->SetOutsideValue(0);
312 binThresToFloatFilter->ReleaseDataFlagOn();
313 binThresToFloatFilter->ReleaseDataBeforeUpdateFlagOn();
315 typedef itk::DiscreteGaussianImageFilter<FloatImageType, FloatImageType> GaussianFilterType;
320 gaussFilter->SetInput(binThresToFloatFilter->GetOutput());
321 gaussFilter->SetUseImageSpacing(
true);
322 gaussFilter->SetVariance(smoothing);
323 gaussFilter->ReleaseDataFlagOn();
324 gaussFilter->ReleaseDataBeforeUpdateFlagOn();
326 typedef itk::BinaryThresholdImageFilter<FloatImageType, CharImageType> BinaryThresholdFromFloatFilterType;
330 binThresFromFloatFilter->SetInput(gaussFilter->GetOutput());
331 binThresFromFloatFilter->SetLowerThreshold(50);
332 binThresFromFloatFilter->SetUpperThreshold(255);
333 binThresFromFloatFilter->SetInsideValue(1);
334 binThresFromFloatFilter->SetOutsideValue(0);
335 binThresFromFloatFilter->ReleaseDataFlagOn();
336 binThresFromFloatFilter->ReleaseDataBeforeUpdateFlagOn();
337 binThresFromFloatFilter->Update();
341 blurredImage->DisconnectPipeline();
342 closedImage =
nullptr;
343 binThresToFloatFilter =
nullptr;
344 gaussFilter =
nullptr;
352 typedef itk::ConnectedThresholdImageFilter<CharImageType, CharImageType> ConnectedThresholdFilterType;
356 CharImageType::IndexType corner;
362 connectedThresFilter->SetInput(blurredImage);
363 connectedThresFilter->SetSeed(corner);
364 connectedThresFilter->SetLower(0);
365 connectedThresFilter->SetUpper(0);
366 connectedThresFilter->SetReplaceValue(2);
367 connectedThresFilter->ReleaseDataFlagOn();
368 connectedThresFilter->ReleaseDataBeforeUpdateFlagOn();
370 typedef itk::BinaryThresholdImageFilter<CharImageType, CharImageType> BinaryThresholdFilterType;
374 binThresFilter->SetInput(connectedThresFilter->GetOutput());
375 binThresFilter->SetLowerThreshold(0);
376 binThresFilter->SetUpperThreshold(0);
377 binThresFilter->SetInsideValue(50);
378 binThresFilter->SetOutsideValue(0);
379 binThresFilter->ReleaseDataFlagOn();
380 binThresFilter->ReleaseDataBeforeUpdateFlagOn();
382 typedef itk::AddImageFilter<CharImageType, CharImageType, CharImageType> AddFilterType;
386 addFilter->SetInput1(blurredImage);
387 addFilter->SetInput2(binThresFilter->GetOutput());
388 addFilter->ReleaseDataFlagOn();
389 addFilter->ReleaseDataBeforeUpdateFlagOn();
401 filteredImage->SetGeometry(geometry);
405 imageToSurfaceFilter->SetInput(filteredImage);
406 imageToSurfaceFilter->SetThreshold(50);
407 imageToSurfaceFilter->SmoothOn();
410 m_Surface = imageToSurfaceFilter->GetOutput(0);
416 if (decimation > 0.0f && decimation < 1.0f)
418 MITK_INFO <<
"Quadric mesh decimation...";
421 quadricDecimation->SetInputData(m_Surface->GetVtkPolyData());
422 quadricDecimation->SetTargetReduction(decimation);
423 quadricDecimation->AttributeErrorMetricOn();
424 quadricDecimation->GlobalWarningDisplayOff();
425 quadricDecimation->Update();
428 cleaner->SetInputConnection(quadricDecimation->GetOutputPort());
429 cleaner->PieceInvariantOn();
430 cleaner->ConvertLinesToPointsOn();
431 cleaner->ConvertStripsToPolysOn();
432 cleaner->PointMergingOn();
435 m_Surface->SetVtkPolyData(cleaner->GetOutput());
443 computeNormals->SetInputData(m_Surface->GetVtkPolyData());
444 computeNormals->SetFeatureAngle(360.0f);
445 computeNormals->AutoOrientNormalsOn();
446 computeNormals->FlipNormalsOff();
447 computeNormals->Update();
449 m_Surface->SetVtkPolyData(computeNormals->GetOutput());
458 bool wireframe =
false;
459 GetParameter(
"Wireframe", wireframe);
466 if (representation !=
nullptr)
474 std::string groupNodeName =
"surface";
475 DataNode *groupNode = GetGroupNode();
477 if (groupNode !=
nullptr)
478 groupNode->
GetName(groupNodeName);
481 node->SetData(m_Surface);
485 if (colorProperty !=
nullptr)
486 node->ReplaceProperty(
"color", colorProperty->
Clone());
490 bool showResult =
true;
491 GetParameter(
"Show result", showResult);
493 bool syncVisibility =
false;
494 GetParameter(
"Sync visibility", syncVisibility);
497 GetPointerParameter(
"Input", image);
499 BaseProperty *organTypeProperty = image->GetProperty(
"organ type");
501 if (organTypeProperty !=
nullptr)
502 m_Surface->SetProperty(
"organ type", organTypeProperty);
506 if (visibleProperty !=
nullptr && syncVisibility)
507 node->ReplaceProperty(
"visible", visibleProperty->
Clone());
511 InsertBelowGroupNode(node);
513 Superclass::ThreadedUpdateSuccessful();
void Progress(unsigned int steps=1)
Sets the current amount of progress to current progress + steps.
itk::SmartPointer< Self > Pointer
Standard implementation of BaseGeometry.
bool GetName(std::string &nodeName, const mitk::BaseRenderer *renderer=nullptr, const char *propertyKey="name") const
Convenience access method for accessing the name of an object (instance of StringProperty with proper...
GeometryTransformHolder::TransformType TransformType
DataCollection - Class to facilitate loading/accessing structured data.
itk::Image< double, 3 > FloatImageType
mitk::BaseProperty * GetProperty(const char *propertyKey, const mitk::BaseRenderer *renderer=nullptr) const
Get the property (instance of BaseProperty) with key propertyKey from the PropertyList of the rendere...
static ProgressBar * GetInstance()
static method to get the GUI dependent ProgressBar-instance so the methods for steps to do and progre...
Abstract base class for properties.
void CastToMitkImage(const itk::SmartPointer< ItkOutputImageType > &itkimage, itk::SmartPointer< mitk::Image > &mitkoutputimage)
Cast an itk::Image (with a specific type) to an mitk::Image.
bool ReadyToRun() override
virtual void SetRepresentationToWireframe()
void Initialize(const NonBlockingAlgorithm *other=nullptr) override
void ThreadedUpdateSuccessful() override
void GetParameter(const char *parameter, T &value) const
Class for nodes of the DataTree.
bool ThreadedUpdateFunction() override
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.