23 #include "vtkMatrix4x4.h" 24 #include "vtkSmartPointer.h" 25 #include "vtkTransform.h" 27 #include "itkImageRegionIteratorWithIndex.h" 28 #include <itkImageIOBase.h> 29 #include <itkImageRegionConstIterator.h> 30 #include <itkRGBAPixel.h> 31 #include <itkRGBPixel.h> 36 : m_Geometry(nullptr),
38 m_UseCropTimeStepOnly(false),
40 m_UseWholeInputRegion(false),
44 this->SetNumberOfIndexedInputs(2);
45 this->SetNumberOfRequiredInputs(2);
50 template <
typename TPixel,
unsigned int VImageDimension>
53 MITK_INFO <<
"Scalar Pixeltype" << std::endl;
55 typedef TPixel TOutputPixel;
56 typedef itk::Image<TPixel, VImageDimension> ItkInputImageType;
57 typedef itk::Image<TOutputPixel, VImageDimension> ItkOutputImageType;
58 typedef typename itk::ImageBase<VImageDimension>::RegionType ItkRegionType;
59 typedef itk::ImageRegionIteratorWithIndex<ItkInputImageType> ItkInputImageIteratorType;
60 typedef itk::ImageRegionIteratorWithIndex<ItkOutputImageType> ItkOutputImageIteratorType;
66 if (this->m_Geometry.IsNull())
69 if (inputItkImage ==
nullptr)
72 "An internal error occurred. Can't convert Image. Please report to bugs@mitk.org");
73 std::cout <<
" image is nullptr...returning" << std::endl;
78 typename ItkRegionType::IndexType::IndexValueType tmpIndex[3];
79 itk2vtk(this->m_InputRequestedRegion.GetIndex(), tmpIndex);
80 typename ItkRegionType::IndexType index;
81 index.SetIndex(tmpIndex);
84 typename ItkRegionType::SizeType::SizeValueType tmpSize[3];
85 itk2vtk(this->m_InputRequestedRegion.GetSize(), tmpSize);
86 typename ItkRegionType::SizeType size;
87 size.SetSize(tmpSize);
90 ItkRegionType inputRegionOfInterest(index, size);
95 outputimagetoitk->SetInput(this->m_OutputTimeSelector->GetOutput());
96 outputimagetoitk->Update();
97 typename ItkOutputImageType::Pointer outputItkImage = outputimagetoitk->GetOutput();
100 ItkInputImageIteratorType inputIt(inputItkImage, inputRegionOfInterest);
101 ItkOutputImageIteratorType outputIt(outputItkImage, outputItkImage->GetLargestPossibleRegion());
110 vtkSmartPointer<vtkMatrix4x4> imageTransform = this->m_Geometry->GetGeometry()->GetVtkTransform()->GetMatrix();
111 Point3D center = this->m_Geometry->GetGeometry()->GetCenter();
112 auto translation = vtkSmartPointer<vtkTransform>::New();
113 translation->Translate(center[0] - imageTransform->GetElement(0, 3),
114 center[1] - imageTransform->GetElement(1, 3),
115 center[2] - imageTransform->GetElement(2, 3));
116 auto transform = vtkSmartPointer<vtkTransform>::New();
117 transform->SetMatrix(imageTransform);
118 transform->PostMultiply();
119 transform->Concatenate(translation);
123 for (
unsigned int i = 0; i < 3; ++i)
124 extent[i] = (this->m_Geometry->GetGeometry()->GetExtent(i));
126 for (inputIt.GoToBegin(), outputIt.GoToBegin(); !inputIt.IsAtEnd(); ++inputIt, ++outputIt)
128 vtk2itk(inputIt.GetIndex(), p);
136 transform->GetInverse()->TransformPoint(p2, p2);
138 bool isInside = (p2[0] >= (-extent[0] / 2.0)) && (p2[0] <= (extent[0] / 2.0)) && (p2[1] >= (-extent[1] / 2.0)) &&
139 (p2[1] <= (extent[1] / 2.0)) && (p2[2] >= (-extent[2] / 2.0)) && (p2[2] <= (extent[2] / 2.0));
141 if ((!this->m_UseCropTimeStepOnly && isInside) ||
142 (this->m_UseCropTimeStepOnly && timeStep == this->m_CurrentTimeStep && isInside))
144 outputIt.Set((TOutputPixel)inputIt.Value());
148 outputIt.Set(outsideValue);
157 this->ProcessObject::SetNthInput(1, const_cast<mitk::GeometryData *>(geometry));
169 if ((output->
IsInitialized() ==
false) || (m_Geometry.IsNull()) ||
170 (m_Geometry->GetTimeGeometry()->CountTimeSteps() == 0))
180 if ((output->IsInitialized()) && (output->GetPipelineMTime() <= m_TimeOfHeaderInitialization.GetMTime()))
187 mitkThrow() <<
"Input is not a mitk::Image";
189 itkDebugMacro(<<
"GenerateOutputInformation()");
191 unsigned int dimension = input->GetDimension();
194 mitkThrow() <<
"ImageCropper cannot handle 1D or 2D Objects.";
197 if ((m_Geometry.IsNull()) || (m_Geometry->GetTimeGeometry()->CountTimeSteps() == 0))
204 mitk::BoundingBox::Pointer bsBoxRelativeToImage =
208 m_InputRequestedRegion = input->GetLargestPossibleRegion();
211 mitk::BoundingBox::PointType
min = bsBoxRelativeToImage->GetMinimum();
213 mitk::BoundingBox::PointType
max = bsBoxRelativeToImage->GetMaximum();
215 maxCorrected[0] = max[0];
216 maxCorrected[1] = max[1];
217 maxCorrected[2] = max[2];
218 maxCorrected[3] = input->GetDimensions()[3];
221 for (
unsigned int i = 0; i < dimension; i++)
223 index[i] = (mitk::SlicedData::IndexType::IndexValueType)(std::ceil(min[i]));
224 size[i] = (mitk::SlicedData::SizeType::SizeValueType)(std::ceil(maxCorrected[i]) - index[i]);
228 if (m_UseWholeInputRegion ==
false)
231 if (m_InputRequestedRegion.Crop(bsRegion) ==
false)
235 m_InputRequestedRegion.SetSize(size);
236 bsRegion.SetSize(size);
237 mitkThrow() <<
"No overlap of the image and the cropping object.";
242 auto dimensions =
new unsigned int[dimension];
244 memcpy(dimensions + 3, input->GetDimensions() + 3, (dimension - 3) *
sizeof(
unsigned int));
248 itk2vtk(m_InputRequestedRegion.GetSize(), dimensions);
254 mitk::BoundingShapeCropper::RegionType outputRegion = output->GetRequestedRegion();
256 m_TimeOfHeaderInitialization.Modified();
264 MITK_ERROR <<
"Filter cannot handle dimensions less than 2 and greater than 4" << std::endl;
265 itkExceptionMacro(
"Filter cannot handle dimensions less than 2 and greater than 4");
274 MITK_INFO <<
"Generate Data" << std::endl;
281 if ((output->IsInitialized() ==
false) || (m_Geometry.IsNull()) ||
282 (m_Geometry->GetTimeGeometry()->CountTimeSteps() == 0))
285 m_InputTimeSelector->SetInput(input);
286 m_OutputTimeSelector->SetInput(this->
GetOutput());
288 mitk::BoundingShapeCropper::RegionType outputRegion = output->GetRequestedRegion();
293 int tstart = outputRegion.GetIndex(3);
294 int tmax = tstart + outputRegion.GetSize(3);
296 if (this->m_UseCropTimeStepOnly)
299 auto indexToWorldTransform = AffineTransform3D::New();
300 indexToWorldTransform->SetParameters(input->GetSlicedGeometry(tstart)->GetIndexToWorldTransform()->GetParameters());
307 m_InputTimeSelector->SetTimeNr(m_CurrentTimeStep);
308 m_InputTimeSelector->UpdateLargestPossibleRegion();
309 m_OutputTimeSelector->SetTimeNr(tstart);
310 m_OutputTimeSelector->UpdateLargestPossibleRegion();
311 ComputeData(m_InputTimeSelector->GetOutput(), m_CurrentTimeStep);
316 for (t = tstart; t < tmax; ++t)
319 auto indexToWorldTransform = AffineTransform3D::New();
320 indexToWorldTransform->SetParameters(input->GetSlicedGeometry(t)->GetIndexToWorldTransform()->GetParameters());
327 m_InputTimeSelector->SetTimeNr(t);
328 m_InputTimeSelector->UpdateLargestPossibleRegion();
329 m_OutputTimeSelector->SetTimeNr(t);
330 m_OutputTimeSelector->UpdateLargestPossibleRegion();
334 m_InputTimeSelector->SetInput(
nullptr);
335 m_OutputTimeSelector->SetInput(
nullptr);
336 m_TimeOfHeaderInitialization.Modified();
void IndexToWorld(const mitk::Vector3D &vec_units, mitk::Vector3D &vec_mm) const
Convert (continuous or discrete) index coordinates of a vector vec_units to world coordinates (in mm)...
virtual ScalarType GetOutsideValue()
void SetIndexToWorldTransform(mitk::AffineTransform3D *transform)
~BoundingShapeCropper() override
const mitk::PixelType GetPixelType(int n=0) const
Returns the PixelType of channel n.
void GenerateOutputInformation() override
DataCollection - Class to facilitate loading/accessing structured data.
void GenerateData() override
#define AccessByItk_1(mitkImage, itkImageTypeFunction, arg1)
itk::Size< RegionDimension > SizeType
void DisplayErrorText(const char *t)
virtual bool GetUseCropTimeStepOnly()
unsigned int GetDimension() const
Get dimension of the image.
itk::ImageRegion< RegionDimension > RegionType
void SetOrigin(const Point3D &origin)
Set the origin, i.e. the upper-left corner of the plane.
Image class for storing images.
void CutImage(itk::Image< TPixel, VImageDimension > *inputItkImage, int timeStep)
Template Function for cropping and masking images with scalar pixel type.
Provides access to a volume at a specific time of the input image.
void vtk2itk(const Tin &in, Tout &out)
virtual void ComputeData(mitk::Image *input3D, int boTimeStep)
Process the image and create the output.
Data class only having a BaseGeometry but not containing any specific data.
mitk::Image::Pointer image
void GenerateInputRequestedRegion() override
Reimplemented from ImageToImageFilter.
Describes the geometry of a data object consisting of slices.
void GenerateTimeInInputRegion(const mitk::TimeGeometry *outputTimeGeometry, const TOutputRegion &outputRegion, const mitk::TimeGeometry *inputTimeGeometry, TInputRegion &inputRegion)
static StatusBar * GetInstance()
static method to get the GUI dependent StatusBar-instance so the methods DisplayText, etc. can be called No reference counting, cause of decentral static use!
void itk2vtk(const Tin &in, Tout &out)
InputImageType * GetInput(void)
void SetGeometry(const mitk::GeometryData *geometry)
Set geometry of the bounding object.
virtual bool IsInitialized() const
Check whether the data has been initialized, i.e., at least the Geometry and other header data has be...
virtual const PixelType GetOutputPixelType()
mitk::BoundingBox::Pointer CalculateBoundingBoxRelativeToTransform(const mitk::AffineTransform3D *transform) const
Calculates a bounding-box around the geometry relative to a coordinate system defined by a transform...
OutputType * GetOutput()
Get the output data of this image source object.
mitk::BaseGeometry * GetGeometry(int t=0) const
Return the geometry, which is a TimeGeometry, of the data as non-const pointer.
BaseGeometry Describes the geometry of a data object.
Class for defining the data type of pixels.
mitk::AffineTransform3D * GetIndexToWorldTransform()
Get the transformation used to convert from index to world coordinates.