22 #include <vtkGeneralTransform.h>
23 #include <vtkImageChangeInformation.h>
24 #include <vtkImageData.h>
25 #include <vtkImageExtractComponents.h>
26 #include <vtkLinearTransform.h>
30 if (reslicer ==
nullptr)
56 m_ResliceTransform =
nullptr;
57 m_WorldGeometry =
nullptr;
58 delete[] m_OutPutSpacing;
63 Superclass::GenerateOutputInformation();
82 input->SetRequestedRegionToLargestPossibleRegion();
87 return m_OutPutSpacing;
96 MITK_ERROR <<
"mitk::ExtractSliceFilter: No input image available. Please set the input!" << std::endl;
97 itkExceptionMacro(
"mitk::ExtractSliceFilter: No input image available. Please set the input!");
101 if (!m_WorldGeometry)
103 MITK_ERROR <<
"mitk::ExtractSliceFilter: No Geometry for reslicing available." << std::endl;
104 itkExceptionMacro(
"mitk::ExtractSliceFilter: No Geometry for reslicing available.");
108 const TimeGeometry *inputTimeGeometry = this->GetInput()->GetTimeGeometry();
109 if ((inputTimeGeometry ==
nullptr) || (inputTimeGeometry->CountTimeSteps() <= 0))
111 itkWarningMacro(<<
"Error reading input image TimeGeometry.");
118 itkWarningMacro(<<
"This is not a valid timestep: " << m_TimeStep);
125 itkWarningMacro(<<
"No volume data existent at given timestep " << m_TimeStep);
132 double widthInMM, heightInMM;
142 if (abstractGeometry !=
nullptr)
144 m_ResliceTransform = abstractGeometry;
152 m_OutPutSpacing[0] = widthInMM / extent[0];
153 m_OutPutSpacing[1] = heightInMM / extent[1];
169 composedResliceTransform->Identity();
170 composedResliceTransform->Concatenate(
174 m_Reslicer->SetResliceTransform(composedResliceTransform);
179 m_Reslicer->SetBackgroundLevel(m_BackgroundLevel);
183 if (planeGeometry !=
nullptr)
192 if (m_InPlaneResampleExtentByGeometry)
197 extent[0] = m_WorldGeometry->GetExtent(0);
198 extent[1] = m_WorldGeometry->GetExtent(1);
206 Vector3D rightInIndex, bottomInIndex;
209 extent[0] = rightInIndex.GetNorm();
210 extent[1] = bottomInIndex.GetNorm();
215 widthInMM = m_WorldGeometry->GetExtentInMM(0);
216 heightInMM = m_WorldGeometry->GetExtentInMM(1);
218 m_OutPutSpacing[0] = widthInMM / extent[0];
219 m_OutPutSpacing[1] = heightInMM / extent[1];
232 origin += right * (m_OutPutSpacing[0] * 0.5);
233 origin += bottom * (m_OutPutSpacing[1] * 0.5);
238 if (m_ResliceTransform.IsNotNull())
239 m_Reslicer->SetResliceTransform(m_ResliceTransform->GetVtkTransform()->GetLinearInverse());
244 m_Reslicer->SetBackgroundLevel(m_BackgroundLevel);
248 itkExceptionMacro(
"mitk::ExtractSliceFilter: No fitting geometry for reslice axis!");
253 if (m_ResliceTransform.IsNotNull())
258 vtkSmartPointer<vtkImageChangeInformation> unitSpacingImageFilter =
260 unitSpacingImageFilter->ReleaseDataFlagOn();
262 unitSpacingImageFilter->SetOutputSpacing(1.0, 1.0, 1.0);
263 unitSpacingImageFilter->SetInputData(input->
GetVtkImageData(m_TimeStep));
265 m_Reslicer->SetInputConnection(unitSpacingImageFilter->GetOutputPort());
276 double originInVtk[3];
278 m_Reslicer->SetResliceAxesOrigin(originInVtk);
287 vnl2vtk(right.GetVnlVector(), cosines);
289 vnl2vtk(bottom.GetVnlVector(), cosines + 3);
291 vnl2vtk(normal.GetVnlVector(), cosines + 6);
293 m_Reslicer->SetResliceAxesDirectionCosines(cosines);
296 m_Reslicer->SetOutputDimensionality(m_OutputDimension);
299 switch (this->m_InterpolationMode)
301 case RESLICE_NEAREST:
302 m_Reslicer->SetInterpolationModeToNearestNeighbor();
305 m_Reslicer->SetInterpolationModeToLinear();
308 m_Reslicer->SetInterpolationModeToCubic();
312 m_Reslicer->SetInterpolationModeToNearestNeighbor();
316 int xMin, xMax, yMin, yMax;
319 xMax =
static_cast<int>(extent[0]);
320 yMax =
static_cast<int>(extent[1]);
322 if (m_WorldGeometry->GetReferenceGeometry())
324 double sliceBounds[6];
325 for (
auto &sliceBound : sliceBounds)
330 if (this->GetClippedPlaneBounds(m_WorldGeometry->GetReferenceGeometry(), planeGeometry, sliceBounds))
333 xMin =
static_cast<int>(sliceBounds[0] / m_OutPutSpacing[0] + 0.5);
334 xMax =
static_cast<int>(sliceBounds[1] / m_OutPutSpacing[0] + 0.5);
335 yMin =
static_cast<int>(sliceBounds[2] / m_OutPutSpacing[1] + 0.5);
336 yMax =
static_cast<int>(sliceBounds[3] / m_OutPutSpacing[1] + 0.5);
344 m_Reslicer->SetOutputExtent(xMin,
std::max(0, xMax - 1), yMin,
std::max(0, yMax - 1), m_ZMin, m_ZMax);
347 m_Reslicer->SetOutputOrigin(0.0, 0.0, 0.0);
349 m_Reslicer->SetOutputSpacing(m_OutPutSpacing[0], m_OutPutSpacing[1], m_ZSpacing);
352 m_Reslicer->UpdateWholeExtent();
357 m_Reslicer->Update();
360 if (m_VtkOutputRequested)
370 reslicedImage = m_Reslicer->GetOutput();
372 if (
nullptr == reslicedImage)
374 itkWarningMacro(<<
"Reslicer returned empty image");
379 int numberOfScalarComponent = reslicedImage->GetNumberOfScalarComponents();
380 if (numberOfScalarComponent > 1 && static_cast<unsigned int>(numberOfScalarComponent) >= m_Component)
384 vectorComponentExtractor->SetInputData(reslicedImage);
385 vectorComponentExtractor->SetComponents(m_Component);
386 vectorComponentExtractor->Update();
388 reslicedImage = vectorComponentExtractor->GetOutput();
396 if (reslicedImage->GetDataDimension() == 1)
400 resultImage->Initialize(reslicedImage, 1, -1, -1, 1);
404 resultImage->Initialize(reslicedImage);
408 resultImage->SetVolume(reslicedImage->GetScalarPointer());
418 originalGeometry->GetIndexToWorldTransform()->SetMatrix(m_WorldGeometry->GetIndexToWorldTransform()->GetMatrix());
421 Point3D sliceOrigin = originalGeometry->GetOrigin();
423 sliceOrigin += right * (m_OutPutSpacing[0] * 0.5);
424 sliceOrigin += bottom * (m_OutPutSpacing[1] * 0.5);
427 originalGeometry->ImageGeometryOn();
435 Vector3D axis0 = originalGeometry->GetAxisVector(0);
436 Vector3D axis1 = originalGeometry->GetAxisVector(1);
441 sliceOrigin += (axis0 * (xMin * m_OutPutSpacing[0])) + (axis1 * (yMin * m_OutPutSpacing[1]));
443 originalGeometry->SetOrigin(sliceOrigin);
445 originalGeometry->Modified();
447 resultImage->SetGeometry(originalGeometry);
454 boundsCopy[0] = boundsCopy[2] = boundsCopy[4] = 0;
456 boundsCopy[1] = xMax - xMin;
457 boundsCopy[3] = yMax - yMin;
458 resultImage->GetGeometry()->SetBounds(boundsCopy);
466 if (!m_WorldGeometry || !this->GetInput())
469 return this->GetClippedPlaneBounds(
470 m_WorldGeometry->GetReferenceGeometry(),
dynamic_cast<const PlaneGeometry *
>(m_WorldGeometry), bounds);
const Point3D GetOrigin() const
Get the origin, e.g. the upper-left corner of the plane.
static bool CalculateClippedPlaneBounds(const BaseGeometry *boundingGeometry, const PlaneGeometry *planeGeometry, double *bounds)
Calculate the bounding box of the resliced image. This is necessary for arbitrarily rotated planes in...
virtual bool IsVolumeSet(int t=0, int n=0) const override
Check whether volume at time t in channel n is set.
virtual vtkImageData * GetVtkImageData(int t=0, int n=0)
Get a volume at a specific time t of channel n as a vtkImageData.
Vector3D GetNormal() const
Normal of the plane.
Vector3D GetAxisVector(unsigned int direction) const
Get vector along bounding-box in the specified direction in mm.
void vnl2vtk(const vnl_vector< Tin > &in, Tout *out)
Image class for storing images.
void itk2vtk(const Tin &in, Tout &out)
virtual BaseGeometry::Pointer GetGeometryForTimeStep(TimeStepType timeStep) const =0
Returns the geometry which corresponds to the given time step.
Describes a two-dimensional, rectangular plane.
virtual bool IsValidTimeStep(TimeStepType timeStep) const =0
Test for the given time step if a geometry is availible.
BaseGeometry Describes the geometry of a data object.
BoundingBoxType::BoundsArrayType BoundsArrayType
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.