26 #include <itkImageRegionConstIterator.h>
27 #include <itkRegionOfInterestImageFilter.h>
31 : m_BackgroundValue(0), m_MarginFactor(1.0), m_TimeSelector(nullptr), m_OverrideCroppingRegion(false)
39 template <
typename TPixel,
unsigned int VImageDimension>
41 unsigned int timestep)
43 if (inputItkImage ==
nullptr)
46 "An internal error occurred. Can't convert Image. Please report to bugs@mitk.org");
47 MITK_ERROR <<
"image is NULL...returning" << std::endl;
51 typedef itk::Image<TPixel, VImageDimension> InternalImageType;
54 typedef itk::RegionOfInterestImageFilter<InternalImageType, InternalImageType> ROIFilterType;
60 roiFilter->SetInput(0, inputItkImage);
61 roiFilter->SetRegionOfInterest(this->GetCroppingRegion());
63 outputItk = roiFilter->GetOutput();
64 outputItk->DisconnectPipeline();
68 MITK_INFO <<
"Crop-Output dimension: " << (newMitkImage->GetDimension() == 3)
69 <<
" Filter-Output dimension: " << this->GetOutput()->GetDimension() <<
" Timestep: " << timestep;
72 this->GetOutput()->SetVolume(newMitkImgAcc.
GetData(), timestep);
80 if (input->GetDimension() <= 2)
82 MITK_ERROR <<
"Only 3D any 4D images are supported." << std::endl;
86 ComputeNewImageBounds();
88 if ((output->IsInitialized()) && (output->GetPipelineMTime() <= m_TimeOfHeaderInitialization.GetMTime()))
91 itkDebugMacro(<<
"GenerateOutputInformation()");
100 m_InputRequestedRegion = input->GetLargestPossibleRegion();
105 index[0] = m_RegionIndex[0];
106 index[1] = m_RegionIndex[1];
107 index[2] = m_RegionIndex[2];
108 index[3] = m_InputRequestedRegion.GetIndex()[3];
109 index[4] = m_InputRequestedRegion.GetIndex()[4];
112 size[0] = m_RegionSize[0];
113 size[1] = m_RegionSize[1];
114 size[2] = m_RegionSize[2];
115 size[3] = m_InputRequestedRegion.GetSize()[3];
116 size[4] = m_InputRequestedRegion.GetSize()[4];
121 if (m_InputRequestedRegion.Crop(cropRegion) ==
false)
125 m_InputRequestedRegion.SetSize(size);
131 input->SetRequestedRegion(&m_InputRequestedRegion);
134 unsigned int dimension = input->GetDimension();
135 auto dimensions =
new unsigned int[dimension];
136 itk2vtk(m_InputRequestedRegion.GetSize(), dimensions);
138 memcpy(dimensions + 3, input->GetDimensions() + 3, (dimension - 3) *
sizeof(
unsigned int));
141 output->Initialize(
mitk::PixelType(GetOutputPixelType()), dimension, dimensions);
148 cloneTransform->Compose(input->GetGeometry()->GetIndexToWorldTransform());
149 output->GetGeometry()->SetIndexToWorldTransform(cloneTransform.GetPointer());
157 input->GetSlicedGeometry()->IndexToWorld(origin, origin);
162 dynamic_cast<mitk::PlaneGeometry *
>(inputGeometry->GetPlaneGeometry(0)->Clone().GetPointer());
174 plane->InitializeStandardPlane(dimX, dimY, right, down, &spacing);
176 plane->SetOrigin(origin);
181 plane, inputGeometry->GetSpacing()[2], output->GetSlicedGeometry()->GetSlices());
185 propTimeGeometry->
Initialize(slicedGeometry, output->GetDimension(3));
187 m_TimeOfHeaderInitialization.Modified();
189 output->SetPropertyList(input->GetPropertyList()->Clone());
200 if (input->GetDimension() <= 2)
202 MITK_ERROR <<
"Only 3D and 4D images supported";
206 if ((output->IsInitialized() ==
false))
209 if (m_TimeSelector.IsNull())
212 m_TimeSelector->SetInput(input);
216 int tstart = outputRegion.GetIndex(3);
217 int tmax = tstart + outputRegion.GetSize(3);
219 for (
int timestep = tstart; timestep < tmax; ++timestep)
221 m_TimeSelector->SetTimeNr(timestep);
222 m_TimeSelector->UpdateLargestPossibleRegion();
229 m_TimeOfHeaderInitialization.Modified();
236 if (m_OverrideCroppingRegion)
238 for (
unsigned int i = 0; i < 3; ++i)
240 m_RegionIndex[i] = m_CroppingRegion.GetIndex()[i];
241 m_RegionSize[i] = m_CroppingRegion.GetSize()[i];
243 if (m_RegionIndex[i] >= static_cast<RegionType::IndexValueType>(inputMitk->GetDimension(i)))
245 itkExceptionMacro(
"Cropping index is not inside the image. " << std::endl
248 << m_CroppingRegion.GetIndex()
252 << m_CroppingRegion.GetSize());
255 if (m_RegionIndex[i] + m_RegionSize[i] >= inputMitk->GetDimension(i))
257 m_RegionSize[i] = inputMitk->GetDimension(i) - m_RegionIndex[i];
261 for (
unsigned int i = 0; i < 3; ++i)
263 m_RegionIndex[i] = m_CroppingRegion.GetIndex()[i];
264 m_RegionSize[i] = m_CroppingRegion.GetSize()[i];
270 unsigned int timeSteps = 1;
271 if (inputMitk->GetDimension() == 4)
272 timeSteps = inputMitk->GetDimension(3);
274 ImageType::IndexType minima, maxima;
276 if (inputMitk->GetDimension() == 4)
280 m_TimeSelector->SetInput(inputMitk);
281 m_TimeSelector->SetTimeNr(0);
282 m_TimeSelector->UpdateLargestPossibleRegion();
283 inputMitk = m_TimeSelector->GetOutput();
290 ImageType::RegionType origRegion = inputItk->GetLargestPossibleRegion();
293 maxima = inputItk->GetLargestPossibleRegion().GetIndex();
294 minima[0] = inputItk->GetLargestPossibleRegion().GetSize()[0];
295 minima[1] = inputItk->GetLargestPossibleRegion().GetSize()[1];
296 minima[2] = inputItk->GetLargestPossibleRegion().GetSize()[2];
298 typedef itk::ImageRegionConstIterator<ImageType> ConstIteratorType;
300 for (
unsigned int idx = 0; idx < timeSteps; ++idx)
305 m_TimeSelector->SetTimeNr(idx);
306 m_TimeSelector->UpdateLargestPossibleRegion();
307 inputMitk = m_TimeSelector->GetOutput();
311 ConstIteratorType inIt(inputItk, origRegion);
313 for (inIt.GoToBegin(); !inIt.IsAtEnd(); ++inIt)
315 float pix_val = inIt.Get();
316 if (fabs(pix_val - m_BackgroundValue) >
mitk::eps)
318 for (
int i = 0; i < 3; i++)
320 minima[i] = vnl_math_min((
int)minima[i], (
int)(inIt.GetIndex()[i]));
321 maxima[i] = vnl_math_max((
int)maxima[i], (
int)(inIt.GetIndex()[i]));
327 typedef ImageType::RegionType::SizeType::SizeValueType SizeValueType;
329 m_RegionSize[0] = (SizeValueType)(m_MarginFactor * (maxima[0] - minima[0] + 1));
330 m_RegionSize[1] = (SizeValueType)(m_MarginFactor * (maxima[1] - minima[1] + 1));
331 m_RegionSize[2] = (SizeValueType)(m_MarginFactor * (maxima[2] - minima[2] + 1));
332 m_RegionIndex = minima;
334 m_RegionIndex[0] -= (m_RegionSize[0] - maxima[0] + minima[0] - 1) / 2;
335 m_RegionIndex[1] -= (m_RegionSize[1] - maxima[1] + minima[1] - 1) / 2;
336 m_RegionIndex[2] -= (m_RegionSize[2] - maxima[2] + minima[2] - 1) / 2;
338 ImageType::RegionType cropRegion(m_RegionIndex, m_RegionSize);
339 origRegion.Crop(cropRegion);
341 m_RegionSize[0] = origRegion.GetSize()[0];
342 m_RegionSize[1] = origRegion.GetSize()[1];
343 m_RegionSize[2] = origRegion.GetSize()[2];
345 m_RegionIndex[0] = origRegion.GetIndex()[0];
346 m_RegionIndex[1] = origRegion.GetIndex()[1];
347 m_RegionIndex[2] = origRegion.GetIndex()[2];
349 m_CroppingRegion = origRegion;
364 m_CroppingRegion = overrideRegion;
365 m_OverrideCroppingRegion =
true;
itk::SmartPointer< Self > Pointer
virtual const PixelType GetOutputPixelType()
const void * GetData() const
Gives const access to the data.
virtual ~AutoCropImageFilter()
itk::ImageIOBase::IOPixelType GetPixelType() const
void ComputeNewImageBounds()
virtual void InitializeEvenlySpaced(mitk::PlaneGeometry *geometry2D, unsigned int slices)
Completely initialize this instance as evenly-spaced with slices parallel to the provided PlaneGeomet...
itk::Size< RegionDimension > SizeType
void DisplayErrorText(const char *t)
virtual void GenerateInputRequestedRegion() override
virtual void GenerateOutputInformation() override
void SetCroppingRegion(RegionType overrideRegion)
itk::ImageRegion< RegionDimension > RegionType
void SetOrigin(const Point3D &origin)
Set the origin, i.e. the upper-left corner of the plane.
virtual void GenerateData() override
A version of GenerateData() specific for image processing filters.
Image class for storing images.
void vtk2itk(const Tin &in, Tout &out)
Describes the geometry of a data object consisting of slices.
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)
#define AccessFixedDimensionByItk_1(mitkImage, itkImageTypeFunction, dimension, arg1)
void CastToMitkImage(const itk::SmartPointer< ItkOutputImageType > &itkimage, itk::SmartPointer< mitk::Image > &mitkoutputimage)
Cast an itk::Image (with a specific type) to an mitk::Image.
void MITKCORE_EXPORT CastToItkImage(const mitk::Image *mitkImage, itk::SmartPointer< ItkOutputImageType > &itkOutputImage)
Cast an mitk::Image to an itk::Image with a specific type.
MITKCORE_EXPORT const ScalarType eps
void ITKCrop3DImage(itk::Image< TPixel, VImageDimension > *inputItkImage, unsigned int timestep)
Describes a two-dimensional, rectangular plane.
ImageReadAccessor class to get locked read access for a particular image part.
ImageType::Pointer ImagePointer
virtual void Initialize() override
Initilizes a new object with one time steps which contains an empty geometry.
Class for defining the data type of pixels.
itk::ImageRegion< 3 > RegionType
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.