diff --git a/Modules/Core/src/Algorithms/mitkExtractSliceFilter2.cpp b/Modules/Core/src/Algorithms/mitkExtractSliceFilter2.cpp index a5938eca66..a8ff3d982a 100644 --- a/Modules/Core/src/Algorithms/mitkExtractSliceFilter2.cpp +++ b/Modules/Core/src/Algorithms/mitkExtractSliceFilter2.cpp @@ -1,278 +1,273 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include #include #include #include #include #include struct mitk::ExtractSliceFilter2::Impl { Impl(); ~Impl(); - mitk::Image* OutputImage; PlaneGeometry::Pointer OutputGeometry; mitk::ExtractSliceFilter2::Interpolator Interpolator; itk::Object::Pointer InterpolateImageFunction; }; mitk::ExtractSliceFilter2::Impl::Impl() - : OutputImage(nullptr), - Interpolator(NearestNeighbor) + : Interpolator(NearestNeighbor) { } mitk::ExtractSliceFilter2::Impl::~Impl() { } -template -void CreateInterpolateImageFunction(const TInputImage* inputImage, mitk::ExtractSliceFilter2::Impl* impl) +namespace { - typename itk::InterpolateImageFunction::Pointer interpolateImageFunction; - - switch (impl->Interpolator) + template + void CreateInterpolateImageFunction(const TInputImage* inputImage, mitk::ExtractSliceFilter2::Interpolator interpolator, itk::Object::Pointer& result) { - case mitk::ExtractSliceFilter2::NearestNeighbor: - interpolateImageFunction = itk::NearestNeighborInterpolateImageFunction::New().GetPointer(); - break; - - case mitk::ExtractSliceFilter2::Linear: - interpolateImageFunction = itk::LinearInterpolateImageFunction::New().GetPointer(); - break; + typename itk::InterpolateImageFunction::Pointer interpolateImageFunction; - case mitk::ExtractSliceFilter2::Cubic: + switch (interpolator) { - auto bSplineInterpolateImageFunction = itk::BSplineInterpolateImageFunction::New(); - bSplineInterpolateImageFunction->SetSplineOrder(2); - interpolateImageFunction = bSplineInterpolateImageFunction.GetPointer(); - break; - } + case mitk::ExtractSliceFilter2::NearestNeighbor: + interpolateImageFunction = itk::NearestNeighborInterpolateImageFunction::New().GetPointer(); + break; - default: - mitkThrow() << "Interplator is unknown."; - } + case mitk::ExtractSliceFilter2::Linear: + interpolateImageFunction = itk::LinearInterpolateImageFunction::New().GetPointer(); + break; - interpolateImageFunction->SetInputImage(inputImage); + case mitk::ExtractSliceFilter2::Cubic: + { + auto bSplineInterpolateImageFunction = itk::BSplineInterpolateImageFunction::New(); + bSplineInterpolateImageFunction->SetSplineOrder(2); + interpolateImageFunction = bSplineInterpolateImageFunction.GetPointer(); + break; + } - impl->InterpolateImageFunction = interpolateImageFunction.GetPointer(); -} + default: + mitkThrow() << "Interplator is unknown."; + } -template -void GenerateData(const itk::Image* inputImage, const mitk::ExtractSliceFilter2::Impl* impl, const mitk::ExtractSliceFilter2::OutputImageRegionType& outputRegion) -{ - typedef itk::Image TInputImage; - typedef itk::InterpolateImageFunction TInterpolateImageFunction; + interpolateImageFunction->SetInputImage(inputImage); - auto outputImage = impl->OutputImage; - auto outputGeometry = impl->OutputGeometry; - auto interpolateImageFunction = static_cast(impl->InterpolateImageFunction.GetPointer()); + result = interpolateImageFunction.GetPointer(); + } - auto origin = outputGeometry->GetOrigin(); - auto spacing = outputGeometry->GetSpacing(); - auto xDirection = outputGeometry->GetAxisVector(0); - auto yDirection = outputGeometry->GetAxisVector(1); + template + void GenerateData(const itk::Image* inputImage, mitk::Image* outputImage, const mitk::ExtractSliceFilter2::OutputImageRegionType& outputRegion, itk::Object* interpolateImageFunction) + { + typedef itk::Image TInputImage; + typedef itk::InterpolateImageFunction TInterpolateImageFunction; - xDirection.Normalize(); - yDirection.Normalize(); + auto outputGeometry = outputImage->GetSlicedGeometry()->GetPlaneGeometry(0); + auto interpolator = static_cast(interpolateImageFunction); - auto spacingAlongXDirection = xDirection * spacing[0]; - auto spacingAlongYDirection = yDirection * spacing[1]; + auto origin = outputGeometry->GetOrigin(); + auto spacing = outputGeometry->GetSpacing(); + auto xDirection = outputGeometry->GetAxisVector(0); + auto yDirection = outputGeometry->GetAxisVector(1); - origin -= spacingAlongXDirection * 0.5; - origin -= spacingAlongYDirection * 0.5; + xDirection.Normalize(); + yDirection.Normalize(); - const std::size_t pixelSize = outputImage->GetPixelType().GetSize(); - const std::size_t height = outputGeometry->GetExtent(1); - const std::size_t xBegin = outputRegion.GetIndex(0); - const std::size_t yBegin = outputRegion.GetIndex(1); - const std::size_t xEnd = xBegin + outputRegion.GetSize(0); - const std::size_t yEnd = yBegin + outputRegion.GetSize(1); + auto spacingAlongXDirection = xDirection * spacing[0]; + auto spacingAlongYDirection = yDirection * spacing[1]; - mitk::ImageWriteAccessor writeAccess(outputImage, nullptr, mitk::ImageAccessorBase::IgnoreLock); - auto data = static_cast(writeAccess.GetData());; + origin -= spacingAlongXDirection * 0.5; + origin -= spacingAlongYDirection * 0.5; - const TPixel backgroundPixel = std::numeric_limits::lowest(); - TPixel pixel; + const std::size_t pixelSize = outputImage->GetPixelType().GetSize(); + const std::size_t height = outputGeometry->GetExtent(1); + const std::size_t xBegin = outputRegion.GetIndex(0); + const std::size_t yBegin = outputRegion.GetIndex(1); + const std::size_t xEnd = xBegin + outputRegion.GetSize(0); + const std::size_t yEnd = yBegin + outputRegion.GetSize(1); - itk::ContinuousIndex index; - mitk::Point3D yPoint; - mitk::Point3D point; + mitk::ImageWriteAccessor writeAccess(outputImage, nullptr, mitk::ImageAccessorBase::IgnoreLock); + auto data = static_cast(writeAccess.GetData());; - for (std::size_t y = yBegin; y < yEnd; ++y) - { - yPoint = origin + spacingAlongYDirection * y; + const TPixel backgroundPixel = std::numeric_limits::lowest(); + TPixel pixel; - for (std::size_t x = xBegin; x < xEnd; ++x) + itk::ContinuousIndex index; + mitk::Point3D yPoint; + mitk::Point3D point; + + for (std::size_t y = yBegin; y < yEnd; ++y) { - point = yPoint + spacingAlongXDirection * x; + yPoint = origin + spacingAlongYDirection * y; - if (inputImage->TransformPhysicalPointToContinuousIndex(point, index)) - { - pixel = interpolateImageFunction->EvaluateAtContinuousIndex(index); - memcpy(static_cast(data + pixelSize * (height * y + x)), static_cast(&pixel), pixelSize); - } - else + for (std::size_t x = xBegin; x < xEnd; ++x) { - memcpy(static_cast(data + pixelSize * (height * y + x)), static_cast(&backgroundPixel), pixelSize); + point = yPoint + spacingAlongXDirection * x; + + if (inputImage->TransformPhysicalPointToContinuousIndex(point, index)) + { + pixel = interpolator->EvaluateAtContinuousIndex(index); + memcpy(static_cast(data + pixelSize * (height * y + x)), static_cast(&pixel), pixelSize); + } + else + { + memcpy(static_cast(data + pixelSize * (height * y + x)), static_cast(&backgroundPixel), pixelSize); + } } } } -} -namespace -{ void VerifyInputImage(const mitk::Image* inputImage) { auto dimension = inputImage->GetDimension(); if (3 != dimension) mitkThrow() << "Input images with " << dimension << " dimensions are not supported."; if (!inputImage->IsInitialized()) mitkThrow() << "Input image is not initialized."; if (!inputImage->IsVolumeSet()) mitkThrow() << "Input image volume is not set."; auto geometry = inputImage->GetGeometry(); if (nullptr == geometry || !geometry->IsValid()) mitkThrow() << "Input image has invalid geometry."; if (!geometry->GetImageGeometry()) mitkThrow() << "Geometry of input image is not an image geometry."; } void VerifyOutputGeometry(const mitk::PlaneGeometry* outputGeometry) { if (nullptr == outputGeometry) mitkThrow() << "Output geometry is not set."; if (!outputGeometry->GetImageGeometry()) mitkThrow() << "Output geometry is not an image geometry."; } } mitk::ExtractSliceFilter2::ExtractSliceFilter2() : m_Impl(new Impl) { } mitk::ExtractSliceFilter2::~ExtractSliceFilter2() { delete m_Impl; } void mitk::ExtractSliceFilter2::AllocateOutputs() { const auto* inputImage = this->GetInput(); const auto* outputGeometry = this->GetOutputGeometry(); auto outputImage = this->GetOutput(); auto pixelType = inputImage->GetPixelType(); outputImage->Initialize(pixelType, 1, *outputGeometry); auto data = new char[static_cast(pixelType.GetSize() * outputGeometry->GetExtent(0) * outputGeometry->GetExtent(1))]; try { if (!outputImage->SetImportVolume(data, 0, 0, mitk::Image::ReferenceMemory)) throw; } catch (...) { delete[] data; } } void mitk::ExtractSliceFilter2::BeforeThreadedGenerateData() { if (nullptr != m_Impl->InterpolateImageFunction && this->GetInput()->GetMTime() < this->GetMTime()) return; const auto* inputImage = this->GetInput(); - AccessFixedDimensionByItk_1(inputImage, CreateInterpolateImageFunction, 3, m_Impl); + AccessFixedDimensionByItk_2(inputImage, CreateInterpolateImageFunction, 3, this->GetInterpolator(), m_Impl->InterpolateImageFunction); } void mitk::ExtractSliceFilter2::ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, itk::ThreadIdType) { - m_Impl->OutputImage = this->GetOutput(); - const auto* inputImage = this->GetInput(); - AccessFixedDimensionByItk_2(inputImage, ::GenerateData, 3, m_Impl, outputRegionForThread); + AccessFixedDimensionByItk_3(inputImage, ::GenerateData, 3, this->GetOutput(), outputRegionForThread, m_Impl->InterpolateImageFunction); } void mitk::ExtractSliceFilter2::SetInput(const InputImageType* image) { if (this->GetInput() == image) return; Superclass::SetInput(image); m_Impl->InterpolateImageFunction = nullptr; } void mitk::ExtractSliceFilter2::SetInput(unsigned int index, const InputImageType* image) { if (0 != index) mitkThrow() << "Input index " << index << " is invalid."; this->SetInput(image); } const mitk::PlaneGeometry* mitk::ExtractSliceFilter2::GetOutputGeometry() const { return m_Impl->OutputGeometry; } void mitk::ExtractSliceFilter2::SetOutputGeometry(PlaneGeometry::Pointer outputGeometry) { if (m_Impl->OutputGeometry != outputGeometry) { m_Impl->OutputGeometry = outputGeometry; this->Modified(); } } mitk::ExtractSliceFilter2::Interpolator mitk::ExtractSliceFilter2::GetInterpolator() const { return m_Impl->Interpolator; } void mitk::ExtractSliceFilter2::SetInterpolator(Interpolator interpolator) { if (m_Impl->Interpolator != interpolator) { m_Impl->Interpolator = interpolator; m_Impl->InterpolateImageFunction = nullptr; this->Modified(); } } void mitk::ExtractSliceFilter2::VerifyInputInformation() { Superclass::VerifyInputInformation(); VerifyInputImage(this->GetInput()); - VerifyOutputGeometry(m_Impl->OutputGeometry.GetPointer()); + VerifyOutputGeometry(this->GetOutputGeometry()); }