24 #include <itkCommand.h> 26 #include <itkImageSliceConstIteratorWithIndex.h> 57 static mitk::SegmentationInterpolationController::Pointer m_Instance;
59 if (m_Instance.IsNull())
71 if (iter->second ==
this)
108 itkExceptionMacro(
"SegmentationInterpolationController needs a 3D-segmentation or 3D+t, not 2D.");
114 itk::ReceptorMemberCommand<SegmentationInterpolationController>::Pointer command =
115 itk::ReceptorMemberCommand<SegmentationInterpolationController>::New();
117 segmentation->AddObserver(itk::ModifiedEvent(), command);
123 for (
unsigned int timeStep = 0; timeStep <
m_Segmentation->GetTimeSteps(); ++timeStep)
126 for (
unsigned int dim = 0; dim < 3; ++dim)
138 for (
unsigned int timeStep = 0; timeStep <
m_Segmentation->GetTimeSteps(); ++timeStep)
142 timeSelector->SetTimeNr(timeStep);
143 timeSelector->UpdateLargestPossibleRegion();
169 MITK_WARN <<
"Segmentation image has different image characteristics than reference image." << std::endl;
174 for (
unsigned int dim = 0; dim <
m_Segmentation->GetDimension(); ++dim)
177 MITK_WARN <<
"original patient image does not match segmentation (different extent in dimension " << dim
178 <<
"), ignoring patient image" << std::endl;
198 unsigned int sliceDimension,
199 unsigned int sliceIndex,
200 unsigned int timeStep)
204 if (sliceDimension > 2)
211 unsigned int dim0(0);
212 unsigned int dim1(1);
215 switch (sliceDimension)
233 auto *rawSlice = (
unsigned char *)readAccess.
GetData();
243 template <
typename DATATYPE>
247 auto *pixelData((DATATYPE *)options.
pixelData);
249 unsigned int timeStep(options.
timeStep);
254 if (sliceDimension > 2)
259 unsigned int dim0(options.
dim0);
260 unsigned int dim1(options.
dim1);
262 int numberOfPixels(0);
269 for (
unsigned int v = 0; v < dim1max; ++v)
271 for (
unsigned int u = 0; u < dim0max; ++u)
273 DATATYPE value = *(pixelData + u + v * dim0max);
283 numberOfPixels +=
static_cast<int>(value);
296 template <
typename TPixel,
unsigned int VImageDimension>
298 unsigned int timeStep)
300 typedef itk::ImageSliceConstIteratorWithIndex<itk::Image<TPixel, VImageDimension>> IteratorType;
302 IteratorType iter(diffImage, diffImage->GetLargestPossibleRegion());
303 iter.SetFirstDirection(0);
304 iter.SetSecondDirection(1);
306 int numberOfPixels(0);
308 typename IteratorType::IndexType index;
314 while (!iter.IsAtEnd())
316 while (!iter.IsAtEndOfSlice())
318 while (!iter.IsAtEndOfLine())
320 index = iter.GetIndex();
326 TPixel value = iter.Get();
337 numberOfPixels +=
static_cast<int>(value);
351 template <
typename DATATYPE>
354 unsigned int timeStep)
363 for (
unsigned int slice = 0; slice < volume->
GetDimension(2); ++slice)
365 const auto *rawVolume =
366 static_cast<const DATATYPE *
>(readAccess.GetData());
375 unsigned int timeStep(0);
403 for (
unsigned int indent = 1; indent < index; ++indent)
420 for (
unsigned int indent = 0; indent < index; ++indent)
433 unsigned int sliceIndex,
435 unsigned int timeStep)
447 if (sliceDimension > 2)
450 if (sliceIndex >= upperLimit - 1)
458 unsigned int lowerBound(0);
459 unsigned int upperBound(0);
462 for (lowerBound = sliceIndex - 1; ; --lowerBound)
478 for (upperBound = sliceIndex + 1; upperBound < upperLimit; ++upperBound)
504 extractor->SetTimeStep(timeStep);
505 extractor->SetResliceTransformByGeometry(
m_Segmentation->GetTimeGeometry()->GetGeometryForTimeStep(timeStep));
506 extractor->SetVtkOutputRequest(
false);
509 extractor->SetWorldGeometry(currentPlane);
510 extractor->Modified();
512 resultImage = extractor->GetOutput();
513 resultImage->DisconnectPipeline();
520 m_Segmentation->GetSlicedGeometry(timeStep)->WorldToIndex(origin, origin);
521 origin[sliceDimension] = lowerBound;
522 m_Segmentation->GetSlicedGeometry(timeStep)->IndexToWorld(origin, origin);
523 reslicePlane->SetOrigin(origin);
528 extractor->SetTimeStep(timeStep);
529 extractor->SetResliceTransformByGeometry(
m_Segmentation->GetTimeGeometry()->GetGeometryForTimeStep(timeStep));
530 extractor->SetVtkOutputRequest(
false);
532 extractor->SetWorldGeometry(reslicePlane);
533 extractor->Modified();
535 lowerMITKSlice = extractor->GetOutput();
536 lowerMITKSlice->DisconnectPipeline();
539 m_Segmentation->GetSlicedGeometry(timeStep)->WorldToIndex(origin, origin);
540 origin[sliceDimension] = upperBound;
541 m_Segmentation->GetSlicedGeometry(timeStep)->IndexToWorld(origin, origin);
542 reslicePlane->SetOrigin(origin);
547 extractor->SetTimeStep(timeStep);
548 extractor->SetResliceTransformByGeometry(
m_Segmentation->GetTimeGeometry()->GetGeometryForTimeStep(timeStep));
549 extractor->SetVtkOutputRequest(
false);
551 extractor->SetWorldGeometry(reslicePlane);
552 extractor->Modified();
554 upperMITKSlice = extractor->GetOutput();
555 upperMITKSlice->DisconnectPipeline();
557 if (lowerMITKSlice.IsNull() || upperMITKSlice.IsNull())
560 catch (
const std::exception &e)
562 MITK_ERROR <<
"Error in 2D interpolation: " << e.what();
575 mitk::SegmentationInterpolationAlgorithm::Pointer algorithm =
577 return algorithm->Interpolate(lowerMITKSlice.GetPointer(),
579 upperMITKSlice.GetPointer(),
Image::ConstPointer m_Segmentation
void SetChangedSlice(const Image *sliceDiff, unsigned int sliceDimension, unsigned int sliceIndex, unsigned int timeStep)
Update after changing a single slice.
Generates interpolations of 2D slices.
void BlockModified(bool)
Block reaction to an images Modified() events.
static SegmentationInterpolationController * GetInstance()
Get existing instance or create a new one.
static InterpolatorMapType s_InterpolatorForImage
void ScanChangedVolume(const itk::Image< TPixel, VImageDimension > *, unsigned int timeStep)
unsigned int GetDimension() const
Get dimension of the image.
Protected class of mitk::SegmentationInterpolationController. Don't use (you shouldn't be able to do ...
void SetChangedVolume(const Image *sliceDiff, unsigned int timeStep)
#define AccessFixedDimensionByItk_2(mitkImage, itkImageTypeFunction, dimension, arg1, arg2)
virtual ImageDataItemPointer GetVolumeData(int t=0, int n=0, void *data=nullptr, ImportMemoryManagementType importMemoryManagement=CopyMemory) const
Image class for storing images.
void SetSegmentationVolume(const Image *segmentation)
Initialize with a whole volume.
~SegmentationInterpolationController() override
void OnImageModified(const itk::EventObject &)
static SegmentationInterpolationController * InterpolatorForImage(const Image *)
Find interpolator for a given image.
void Activate2DInterpolation(bool)
bool m_2DInterpolationActivated
Image::Pointer Interpolate(unsigned int sliceDimension, unsigned int sliceIndex, const mitk::PlaneGeometry *currentPlane, unsigned int timeStep)
Generates an interpolated image for the given slice.
mitk::Image::Pointer image
const Point3D GetOrigin() const
Get the origin, e.g. the upper-left corner of the plane.
void ScanWholeVolume(const itk::Image< DATATYPE, 3 > *, const Image *volume, unsigned int timeStep)
SegmentationInterpolationController()
std::map< const Image *, SegmentationInterpolationController * > InterpolatorMapType
#define AccessFixedDimensionByItk_1(mitkImage, itkImageTypeFunction, dimension, arg1)
TimeResolvedDirtyVectorType m_SegmentationCountInSlice
Image::ConstPointer m_ReferenceImage
void SetReferenceVolume(const Image *segmentation)
Set a reference image (original patient image) - optional.
void ScanChangedSlice(const itk::Image< DATATYPE, 2 > *, const SetChangedSliceOptions &options)
internal scan of a single slice
Describes a two-dimensional, rectangular plane.
ImageReadAccessor class to get locked read access for a particular image part.
unsigned int sliceDimension
const void * GetData() const
Gives const access to the data.