Classes | Public Types | Public Member Functions | Static Public Member Functions | Protected Types | Protected Member Functions | Protected Attributes | Static Protected Attributes

mitk::SegmentationInterpolationController Class Reference
[Classes related to InteractiveSegmentation]

Generates interpolations of 2D slices. More...

#include <mitkSegmentationInterpolationController.h>

List of all members.

Classes

class  SetChangedSliceOptions
 Protected class of mitk::SegmentationInterpolationController. Don't use (you shouldn't be able to do so)! More...

Public Types

typedef
SegmentationInterpolationController 
Self
typedef itk::Object Superclass
typedef itk::SmartPointer< SelfPointer
typedef itk::SmartPointer
< const Self
ConstPointer

Public Member Functions

virtual const char * GetClassName () const
void BlockModified (bool)
 Block reaction to an images Modified() events.
void SetSegmentationVolume (const Image *segmentation)
 Initialize with a whole volume.
void SetReferenceVolume (const Image *segmentation)
 Set a reference image (original patient image) - optional.
void SetChangedSlice (const Image *sliceDiff, unsigned int sliceDimension, unsigned int sliceIndex, unsigned int timeStep)
 Update after changing a single slice.
void SetChangedVolume (const Image *sliceDiff, unsigned int timeStep)
Image::Pointer Interpolate (unsigned int sliceDimension, unsigned int sliceIndex, unsigned int timeStep)
 Generates an interpolated image for the given slice.
void OnImageModified (const itk::EventObject &)

Static Public Member Functions

static Pointer New ()
static
SegmentationInterpolationController
InterpolatorForImage (const Image *)
 specify the segmentation image that should be interpolated

Protected Types

typedef std::vector< unsigned int > DirtyVectorType
typedef std::vector
< std::vector< DirtyVectorType > > 
TimeResolvedDirtyVectorType
typedef std::map< const Image
*, SegmentationInterpolationController * > 
InterpolatorMapType

Protected Member Functions

 SegmentationInterpolationController ()
virtual ~SegmentationInterpolationController ()
template<typename DATATYPE >
void ScanChangedSlice (itk::Image< DATATYPE, 2 > *, const SetChangedSliceOptions &options)
 internal scan of a single slice
template<typename TPixel , unsigned int VImageDimension>
void ScanChangedVolume (itk::Image< TPixel, VImageDimension > *, unsigned int timeStep)
template<typename DATATYPE >
void ScanWholeVolume (itk::Image< DATATYPE, 3 > *, const Image *volume, unsigned int timeStep)
void PrintStatus ()

Protected Attributes

TimeResolvedDirtyVectorType m_SegmentationCountInSlice
Image::ConstPointer m_Segmentation
Image::ConstPointer m_ReferenceImage
bool m_BlockModified

Static Protected Attributes

static InterpolatorMapType s_InterpolatorForImage

Detailed Description

Generates interpolations of 2D slices.

See also:
QmitkSlicesInterpolator
QmitkInteractiveSegmentation

There is a separate page describing the general design of QmitkInteractiveSegmentation: QmitkInteractiveSegmentationTechnicalPage

This class keeps track of the contents of a 3D segmentation image.

Attention:
mitk::SegmentationInterpolationController assumes that the image contains pixel values of 0 and 1.

After you set the segmentation image using SetSegmentationVolume(), the whole image is scanned for pixels other than 0. SegmentationInterpolationController registers as an observer to the segmentation image, and repeats the scan whenvever the image is modified.

You can prevent this (time consuming) scan if you do the changes slice-wise and send difference images to SegmentationInterpolationController. For this purpose SetChangedSlice() should be used. mitk::OverwriteImageFilter already does this every time it changes a slice of an image. There is a static method InterpolatorForImage(), which can be used to find out if there already is an interpolator instance for a specified image. OverwriteImageFilter uses this to get to know its interpolator.

SegmentationInterpolationController needs to maintain some information about the image slices (in every dimension). This information is stored internally in m_SegmentationCountInSlice, which is basically three std::vectors (one for each dimension). Each item describes one image dimension, each vector item holds the count of pixels in "its" slice. This is perhaps better to understand from the following picture (where red items just mean to symbolize "there is some segmentation" - in reality there is an integer count).

slice_based_segmentation_interpolator.png

$Author$

Definition at line 67 of file mitkSegmentationInterpolationController.h.


Member Typedef Documentation

Definition at line 71 of file mitkSegmentationInterpolationController.h.

typedef std::vector<unsigned int> mitk::SegmentationInterpolationController::DirtyVectorType [protected]

Definition at line 162 of file mitkSegmentationInterpolationController.h.

Definition at line 165 of file mitkSegmentationInterpolationController.h.

Definition at line 71 of file mitkSegmentationInterpolationController.h.

Definition at line 71 of file mitkSegmentationInterpolationController.h.

Definition at line 71 of file mitkSegmentationInterpolationController.h.

Definition at line 164 of file mitkSegmentationInterpolationController.h.


Constructor & Destructor Documentation

mitk::SegmentationInterpolationController::SegmentationInterpolationController (  ) [protected]

Definition at line 45 of file mitkSegmentationInterpolationController.cpp.

:m_BlockModified(false)
{
}
mitk::SegmentationInterpolationController::~SegmentationInterpolationController (  ) [protected, virtual]

Definition at line 50 of file mitkSegmentationInterpolationController.cpp.

{
  // remove this from the list of interpolators
  for ( InterpolatorMapType::iterator iter = s_InterpolatorForImage.begin();
        iter != s_InterpolatorForImage.end();
        ++iter )
  {
    if (iter->second == this)
    {
      s_InterpolatorForImage.erase( iter );
      break;
    }
  }
}

Member Function Documentation

void mitk::SegmentationInterpolationController::BlockModified ( bool  block )

Block reaction to an images Modified() events.

Blocking the scan of the whole image is especially useful when you are about to change a single slice of the image. Then you would send a difference image of this single slice to SegmentationInterpolationController but call image->Modified() anyway. Before calling image->Modified() you should block SegmentationInterpolationController's reactions to this modified by using this method.

Definition at line 73 of file mitkSegmentationInterpolationController.cpp.

Referenced by mitk::DiffImageApplier::ExecuteOperation(), and mitk::OverwriteSliceImageFilter::GenerateData().

{
  m_BlockModified = block;
}
virtual const char* mitk::SegmentationInterpolationController::GetClassName (  ) const [virtual]
mitk::Image::Pointer mitk::SegmentationInterpolationController::Interpolate ( unsigned int  sliceDimension,
unsigned int  sliceIndex,
unsigned int  timeStep 
)

Generates an interpolated image for the given slice.

Parameters:
sliceDimensionNumber of the dimension which is constant for all pixels of the meant slice.
sliceIndexWhich slice to take, in the direction specified by sliceDimension. Count starts from 0.
timeStepWhich time step to use

Definition at line 385 of file mitkSegmentationInterpolationController.cpp.

References mitk::ShapeBasedInterpolationAlgorithm::New(), and mitk::ExtractImageFilter::New().

{
  if (m_Segmentation.IsNull()) return NULL;

  if ( timeStep >= m_SegmentationCountInSlice.size() ) return NULL;
  if ( sliceDimension > 2 ) return NULL;
  unsigned int upperLimit = m_SegmentationCountInSlice[timeStep][sliceDimension].size();
  if ( sliceIndex >= upperLimit - 1 ) return NULL; // can't interpolate first and last slice
  if ( sliceIndex < 1  ) return NULL;

  if ( m_SegmentationCountInSlice[timeStep][sliceDimension][sliceIndex] > 0 ) return NULL; // slice contains a segmentation, won't interpolate anything then

  unsigned int lowerBound(0);
  unsigned int upperBound(0);
  bool bounds( false );

  for (lowerBound = sliceIndex - 1; /*lowerBound >= 0*/; --lowerBound)
  {
    if ( m_SegmentationCountInSlice[timeStep][sliceDimension][lowerBound] > 0 )
    {
      bounds = true;
      break;
    }

    if (lowerBound == 0) break; // otherwise overflow and start at something like 4294967295
  }

  if (!bounds) return NULL;

  bounds = false;
  for (upperBound = sliceIndex + 1 ; upperBound < upperLimit; ++upperBound)
  {
    if ( m_SegmentationCountInSlice[timeStep][sliceDimension][upperBound] > 0 )
    {
      bounds = true;
      break;
    }
  }

  if (!bounds) return NULL;
 
  // ok, we have found two neighboring slices with segmentations (and we made sure that the current slice does NOT contain anything
  //MITK_INFO << "Interpolate in timestep " << timeStep << ", dimension " << sliceDimension << ": estimate slice " << sliceIndex << " from slices " << lowerBound << " and " << upperBound << std::endl;

  mitk::Image::Pointer lowerMITKSlice;
  mitk::Image::Pointer upperMITKSlice;
  mitk::Image::Pointer resultImage;
  try
  {
  // extract the two neighoring slices from the segmentation volume
    ExtractImageFilter::Pointer extractor= ExtractImageFilter::New();
    extractor->SetInput( m_Segmentation );
    extractor->SetSliceDimension( sliceDimension );
    extractor->SetSliceIndex( lowerBound );
    extractor->SetTimeStep( timeStep );
    extractor->Update();
    lowerMITKSlice = extractor->GetOutput();
    lowerMITKSlice->DisconnectPipeline(); // otherwise the next output of the filter will overwrite this pointer, too
    
    extractor->SetInput( m_Segmentation );
    extractor->SetSliceDimension( sliceDimension );
    extractor->SetSliceIndex( sliceIndex );
    extractor->SetTimeStep( timeStep );
    extractor->Update();
    resultImage = extractor->GetOutput();
    resultImage->DisconnectPipeline();
    
    extractor->SetInput( m_Segmentation );
    extractor->SetSliceDimension( sliceDimension );
    extractor->SetSliceIndex( upperBound );
    extractor->SetTimeStep( timeStep );
    extractor->Update();
    upperMITKSlice = extractor->GetOutput();

    if ( lowerMITKSlice.IsNull() || upperMITKSlice.IsNull() ) return NULL;
  }
  catch(...)
  {
    return NULL;
  }

  // interpolation algorithm gets some inputs
  //   two segmentations (guaranteed to be of the same data type, but no special data type guaranteed)
  //   orientation (sliceDimension) of the segmentations
  //   position of the two slices (sliceIndices)
  //   one volume image (original patient image)
  //
  // interpolation algorithm can use e.g. itk::ImageSliceConstIteratorWithIndex to
  //   inspect the original patient image at appropriate positions

  mitk::SegmentationInterpolationAlgorithm::Pointer algorithm = mitk::ShapeBasedInterpolationAlgorithm::New().GetPointer();
  return algorithm->Interpolate( lowerMITKSlice.GetPointer(), lowerBound,
                                 upperMITKSlice.GetPointer(), upperBound,
                                 sliceIndex,
                                 sliceDimension,
                                 resultImage,
                                 timeStep,
                                 m_ReferenceImage );

}
mitk::SegmentationInterpolationController * mitk::SegmentationInterpolationController::InterpolatorForImage ( const Image image ) [static]

specify the segmentation image that should be interpolated

Find interpolator for a given image.

Returns:
NULL if there is no interpolator yet.

This method is useful if several "clients" modify the same image and want to access the interpolations. Then they can share the same object.

Definition at line 32 of file mitkSegmentationInterpolationController.cpp.

References s_InterpolatorForImage.

Referenced by mitk::DiffImageApplier::ExecuteOperation(), and mitk::OverwriteSliceImageFilter::GenerateData().

{
  InterpolatorMapType::iterator iter = s_InterpolatorForImage.find( image );
  if ( iter != s_InterpolatorForImage.end() )
  {
    return iter->second;
  }
  else
  {
    return NULL;
  }
}
static Pointer mitk::SegmentationInterpolationController::New (  ) [static]
void mitk::SegmentationInterpolationController::OnImageModified ( const itk::EventObject &   )
void mitk::SegmentationInterpolationController::PrintStatus (  ) [protected]

Definition at line 327 of file mitkSegmentationInterpolationController.cpp.

References MITK_INFO.

{
  unsigned int timeStep(0); // if needed, put a loop over time steps around everyting, but beware, output will be long

  MITK_INFO << "Interpolator status (timestep 0): dimensions " 
           << m_SegmentationCountInSlice[timeStep][0].size() << " " 
           << m_SegmentationCountInSlice[timeStep][1].size() << " "
           << m_SegmentationCountInSlice[timeStep][2].size() << std::endl;
    
  MITK_INFO << "Slice 0: " <<  m_SegmentationCountInSlice[timeStep][2][0] << std::endl;

  // row "x"
  for (unsigned int index = 0; index < m_SegmentationCountInSlice[timeStep][0].size(); ++index)
  {
    if ( m_SegmentationCountInSlice[timeStep][0][index] > 0 )
      MITK_INFO << "O";
    else
      MITK_INFO << ".";
  }
  MITK_INFO << std::endl;
 
  // rows "y" and "z" (diagonal)
  for (unsigned int index = 1; index < m_SegmentationCountInSlice[timeStep][1].size(); ++index)
  {
    if ( m_SegmentationCountInSlice[timeStep][1][index] > 0 )
      MITK_INFO << "O";
    else
      MITK_INFO << ".";

    if ( m_SegmentationCountInSlice[timeStep][2].size() > index ) // if we also have a z value here, then print it, too
    {
      for (unsigned int indent = 1; indent < index; ++indent)
        MITK_INFO << " ";

      if ( m_SegmentationCountInSlice[timeStep][2][index] > 0 )
        MITK_INFO << m_SegmentationCountInSlice[timeStep][2][index];//"O";
      else
        MITK_INFO << ".";
    }

    MITK_INFO << std::endl;
  }

  // z indices that are larger than the biggest y index
  for (unsigned int index = m_SegmentationCountInSlice[timeStep][1].size(); index < m_SegmentationCountInSlice[timeStep][2].size(); ++index)
  {
    for (unsigned int indent = 0; indent < index; ++indent)
    MITK_INFO << " ";

    if ( m_SegmentationCountInSlice[timeStep][2][index] > 0 )
      MITK_INFO << m_SegmentationCountInSlice[timeStep][2][index];//"O";
    else
      MITK_INFO << ".";
    
    MITK_INFO << std::endl;
  }
}
template<typename DATATYPE >
void mitk::SegmentationInterpolationController::ScanChangedSlice ( itk::Image< DATATYPE, 2 > *  ,
const SetChangedSliceOptions options 
) [protected]

internal scan of a single slice

Definition at line 214 of file mitkSegmentationInterpolationController.cpp.

References mitk::SegmentationInterpolationController::SetChangedSliceOptions::dim0, mitk::SegmentationInterpolationController::SetChangedSliceOptions::dim1, mitk::SegmentationInterpolationController::SetChangedSliceOptions::pixelData, mitk::SegmentationInterpolationController::SetChangedSliceOptions::sliceDimension, mitk::SegmentationInterpolationController::SetChangedSliceOptions::sliceIndex, and mitk::SegmentationInterpolationController::SetChangedSliceOptions::timeStep.

{
  DATATYPE* pixelData( (DATATYPE*)options.pixelData );
  
  unsigned int timeStep( options.timeStep );

  unsigned int sliceDimension( options.sliceDimension );
  unsigned int sliceIndex( options.sliceIndex );

  if ( sliceDimension > 2 ) return;
  if ( sliceIndex >= m_SegmentationCountInSlice[timeStep][sliceDimension].size() ) return;
  
  unsigned int dim0( options.dim0 );
  unsigned int dim1( options.dim1 );

  int numberOfPixels(0); // number of pixels in this slice that are not 0

  unsigned int dim0max = m_SegmentationCountInSlice[timeStep][dim0].size();
  unsigned int dim1max = m_SegmentationCountInSlice[timeStep][dim1].size();

  // scan the slice from two directions
  // and set the flags for the two dimensions of the slice
  for (unsigned int v = 0; v < dim1max; ++v)
  {
    for (unsigned int u = 0; u < dim0max; ++u)
    {
      DATATYPE value = *(pixelData + u + v * dim0max);

      assert ( (signed) m_SegmentationCountInSlice[timeStep][dim0][u] + (signed)value >= 0 ); // just for debugging. This must always be true, otherwise some counting is going wrong
      assert ( (signed) m_SegmentationCountInSlice[timeStep][dim1][v] + (signed)value >= 0 );

      m_SegmentationCountInSlice[timeStep][dim0][u] = static_cast<unsigned int>( m_SegmentationCountInSlice[timeStep][dim0][u] + value ); 
      m_SegmentationCountInSlice[timeStep][dim1][v] = static_cast<unsigned int>( m_SegmentationCountInSlice[timeStep][dim1][v] + value );
      numberOfPixels += static_cast<int>( value );
    }
  }

  // flag for the dimension of the slice itself 
  assert ( (signed) m_SegmentationCountInSlice[timeStep][sliceDimension][sliceIndex] + numberOfPixels >= 0 );
  m_SegmentationCountInSlice[timeStep][sliceDimension][sliceIndex] += numberOfPixels;
  
  //MITK_INFO << "scan t=" << timeStep << " from (0,0) to (" << dim0max << "," << dim1max << ") (" << pixelData << "-" << pixelData+dim0max*dim1max-1 <<  ") in slice " << sliceIndex << " found " << numberOfPixels << " pixels" << std::endl;
}
template<typename TPixel , unsigned int VImageDimension>
void mitk::SegmentationInterpolationController::ScanChangedVolume ( itk::Image< TPixel, VImageDimension > *  diffImage,
unsigned int  timeStep 
) [protected]

Definition at line 260 of file mitkSegmentationInterpolationController.cpp.

{
  typedef itk::ImageSliceConstIteratorWithIndex< itk::Image<TPixel, VImageDimension> > IteratorType;

  IteratorType iter( diffImage, diffImage->GetLargestPossibleRegion() );
  iter.SetFirstDirection(0);
  iter.SetSecondDirection(1);

  int numberOfPixels(0); // number of pixels in this slice that are not 0
  
  typename IteratorType::IndexType index;
  unsigned int x = 0;
  unsigned int y = 0;
  unsigned int z = 0;

  iter.GoToBegin();
  while ( !iter.IsAtEnd() )
  {
    while ( !iter.IsAtEndOfSlice() )
    {
      while ( !iter.IsAtEndOfLine() )
      {
        index = iter.GetIndex();

        x = index[0];
        y = index[1];
        z = index[2];

        TPixel value = iter.Get();

        assert ( (signed) m_SegmentationCountInSlice[timeStep][0][x] + (signed)value >= 0 ); // just for debugging. This must always be true, otherwise some counting is going wrong
        assert ( (signed) m_SegmentationCountInSlice[timeStep][1][y] + (signed)value >= 0 );

        m_SegmentationCountInSlice[timeStep][0][x] = static_cast<unsigned int>( m_SegmentationCountInSlice[timeStep][0][x] + value ); 
        m_SegmentationCountInSlice[timeStep][1][y] = static_cast<unsigned int>( m_SegmentationCountInSlice[timeStep][1][y] + value );
  
        numberOfPixels += static_cast<int>( value );
        
        ++iter;
      }
      iter.NextLine();
    }
    assert ( (signed) m_SegmentationCountInSlice[timeStep][2][z] + numberOfPixels >= 0 );
    m_SegmentationCountInSlice[timeStep][2][z] += numberOfPixels;
    numberOfPixels = 0;

    iter.NextSlice();
  }
}
template<typename DATATYPE >
void mitk::SegmentationInterpolationController::ScanWholeVolume ( itk::Image< DATATYPE, 3 > *  ,
const Image volume,
unsigned int  timeStep 
) [protected]

Definition at line 312 of file mitkSegmentationInterpolationController.cpp.

References mitk::Image::GetData(), and mitk::Image::GetDimension().

{
  if (!volume) return;
  if ( timeStep >= m_SegmentationCountInSlice.size() ) return;

  for (unsigned int slice = 0; slice < volume->GetDimension(2); ++slice)
  {
    DATATYPE* rawVolume = static_cast<DATATYPE*>( const_cast<Image*>(volume)->GetVolumeData(timeStep)->GetData() ); // we again promise not to change anything, we'll just count
    //DATATYPE* rawSlice = static_cast<DATATYPE*>( volume->GetSliceData(slice)->GetData() ); // TODO THIS wouldn't work. Did I mess up with some internal mitk::Image data structure?
    DATATYPE* rawSlice = rawVolume + ( volume->GetDimension(0) * volume->GetDimension(1) * slice );

    ScanChangedSlice<DATATYPE>( NULL, SetChangedSliceOptions(2, slice, 0, 1, timeStep, rawSlice) );
  }
}
void mitk::SegmentationInterpolationController::SetChangedSlice ( const Image sliceDiff,
unsigned int  sliceDimension,
unsigned int  sliceIndex,
unsigned int  timeStep 
)

Update after changing a single slice.

Parameters:
sliceDiffis a 2D image with the difference image of the slice determined by sliceDimension and sliceIndex. The difference is (pixel value in the new slice minus pixel value in the old slice).
sliceDimensionNumber of the dimension which is constant for all pixels of the meant slice.
sliceIndexWhich slice to take, in the direction specified by sliceDimension. Count starts from 0.
timeStepWhich time step is changed

Definition at line 181 of file mitkSegmentationInterpolationController.cpp.

References AccessFixedDimensionByItk_1, and mitkIpPicDescriptor.

Referenced by mitk::DiffImageApplier::ExecuteOperation(), and mitk::OverwriteSliceImageFilter::GenerateData().

{
  if ( !sliceDiff ) return;
  if ( sliceDimension > 2 ) return;
  if ( timeStep >= m_SegmentationCountInSlice.size() ) return;
  if ( sliceIndex >= m_SegmentationCountInSlice[timeStep][sliceDimension].size() ) return;

  unsigned int dim0(0);
  unsigned int dim1(1);

  // determine the other two dimensions
  switch (sliceDimension)
  {
    default:
    case 2:
      dim0 = 0; dim1 = 1; break;
    case 1:
      dim0 = 0; dim1 = 2; break;
    case 0:
      dim0 = 1; dim1 = 2; break;
  }

  mitkIpPicDescriptor* rawSlice = const_cast<Image*>(sliceDiff)->GetSliceData()->GetPicDescriptor(); // we promise not to change anything!
  if (!rawSlice) return;

  AccessFixedDimensionByItk_1( sliceDiff, ScanChangedSlice, 2, SetChangedSliceOptions(sliceDimension, sliceIndex, dim0, dim1, timeStep, rawSlice->data) );
  
  //PrintStatus();
  
  Modified();
}
void mitk::SegmentationInterpolationController::SetChangedVolume ( const Image sliceDiff,
unsigned int  timeStep 
)

Definition at line 169 of file mitkSegmentationInterpolationController.cpp.

References AccessFixedDimensionByItk_1, and mitk::Image::GetDimension().

Referenced by mitk::DiffImageApplier::ExecuteOperation().

{
  if ( !sliceDiff ) return;
  if ( sliceDiff->GetDimension() != 3 ) return;
  
  AccessFixedDimensionByItk_1( sliceDiff, ScanChangedVolume, 3, timeStep );

  //PrintStatus();
  Modified();
}
void mitk::SegmentationInterpolationController::SetReferenceVolume ( const Image segmentation )

Set a reference image (original patient image) - optional.

If this volume is set (must exactly match the dimensions of the segmentation), the interpolation algorithm may consider image content to improve the interpolated (estimated) segmentation.

Definition at line 139 of file mitkSegmentationInterpolationController.cpp.

References MITK_ERROR.

{
  m_ReferenceImage = referenceImage;

  if ( m_ReferenceImage.IsNull() ) return; // no image set - ignore it then
  assert ( m_Segmentation.IsNotNull() ); // should never happen

  // ensure the reference image has the same dimensionality and extents as the segmentation image
  if (    m_ReferenceImage.IsNull() 
       || m_Segmentation.IsNull()
       || m_ReferenceImage->GetDimension() != m_Segmentation->GetDimension() 
       || m_ReferenceImage->GetPixelType().GetNumberOfComponents() != 1
       || m_Segmentation->GetPixelType().GetNumberOfComponents() != 1
     )
  {
    MITK_ERROR << "original patient image does not match segmentation, ignoring patient image" << std::endl;
    m_ReferenceImage = NULL;
    return;
  }

  for (unsigned int dim = 0; dim < m_Segmentation->GetDimension(); ++dim)
    if ( m_ReferenceImage->GetDimension(dim) != m_Segmentation->GetDimension(dim) )
    {
      MITK_ERROR << "original patient image does not match segmentation (different extent in dimension " << dim 
                << "), ignoring patient image" << std::endl;
      m_ReferenceImage = NULL;
      return;
    }
}
void mitk::SegmentationInterpolationController::SetSegmentationVolume ( const Image segmentation )

Initialize with a whole volume.

Will scan the volume for segmentation pixels (values other than 0) and fill some internal data structures. You don't have to call this method every time something changes, but only when several slices at once change.

When you change a single slice, call SetChangedSlice() instead.

Definition at line 78 of file mitkSegmentationInterpolationController.cpp.

References AccessFixedDimensionByItk_2, mitk::Image::GetDimension(), mitk::ImageTimeSelector::New(), and OnImageModified().

{
  // clear old information (remove all time steps
  m_SegmentationCountInSlice.clear();

  // delete this from the list of interpolators
  InterpolatorMapType::iterator iter = s_InterpolatorForImage.find( segmentation );
  if ( iter != s_InterpolatorForImage.end() )
  {
    s_InterpolatorForImage.erase( iter );
  }

  if (!segmentation) return;
  if (segmentation->GetDimension() > 4 || segmentation->GetDimension() < 3) 
  {
    itkExceptionMacro("SegmentationInterpolationController needs a 3D-segmentation or 3D+t, not 2D.");
  }

  if (m_Segmentation != segmentation)
  {
    // observe Modified() event of image
    itk::ReceptorMemberCommand<SegmentationInterpolationController>::Pointer command = itk::ReceptorMemberCommand<SegmentationInterpolationController>::New();
    command->SetCallbackFunction( this, &SegmentationInterpolationController::OnImageModified );
    segmentation->AddObserver( itk::ModifiedEvent(), command );
  }

  m_Segmentation = segmentation;

  m_SegmentationCountInSlice.resize( m_Segmentation->GetTimeSteps() );
  for (unsigned int timeStep = 0; timeStep < m_Segmentation->GetTimeSteps(); ++timeStep)
  {
    m_SegmentationCountInSlice[timeStep].resize(3);
    for (unsigned int dim = 0; dim < 3; ++dim)
    {
      m_SegmentationCountInSlice[timeStep][dim].clear();
      m_SegmentationCountInSlice[timeStep][dim].resize( m_Segmentation->GetDimension(dim) );
      m_SegmentationCountInSlice[timeStep][dim].assign( m_Segmentation->GetDimension(dim), 0 );
    }
  }

  s_InterpolatorForImage.insert( std::make_pair( m_Segmentation, this ) );

  // for all timesteps
  // scan whole image
  for (unsigned int timeStep = 0; timeStep < m_Segmentation->GetTimeSteps(); ++timeStep)
  {
    ImageTimeSelector::Pointer timeSelector = ImageTimeSelector::New();
    timeSelector->SetInput( m_Segmentation );
    timeSelector->SetTimeNr( timeStep );
    timeSelector->UpdateLargestPossibleRegion();
    Image::Pointer segmentation3D = timeSelector->GetOutput();
    AccessFixedDimensionByItk_2( segmentation3D, ScanWholeVolume, 3, m_Segmentation, timeStep );
  }

  //PrintStatus();
  
  SetReferenceVolume( m_ReferenceImage );

  Modified();
}

Member Data Documentation

Definition at line 196 of file mitkSegmentationInterpolationController.h.

Definition at line 195 of file mitkSegmentationInterpolationController.h.

Definition at line 194 of file mitkSegmentationInterpolationController.h.

An array of flags. One for each dimension of the image. A flag is set, when a slice in a certain dimension has at least one pixel that is not 0 (which would mean that it has to be considered by the interpolation algorithm).

E.g. flags for transversal slices are stored in m_SegmentationCountInSlice[0][index].

Enhanced with time steps it is now m_SegmentationCountInSlice[timeStep][0][index]

Definition at line 190 of file mitkSegmentationInterpolationController.h.

Definition at line 192 of file mitkSegmentationInterpolationController.h.

Referenced by InterpolatorForImage().


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines