00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "mitkSegmentationInterpolationController.h"
00019
00020 #include "mitkImageCast.h"
00021 #include "mitkExtractImageFilter.h"
00022 #include "mitkImageTimeSelector.h"
00023
00024 #include "mitkShapeBasedInterpolationAlgorithm.h"
00025
00026 #include <itkCommand.h>
00027 #include <itkImage.h>
00028 #include <itkImageSliceConstIteratorWithIndex.h>
00029
00030 mitk::SegmentationInterpolationController::InterpolatorMapType mitk::SegmentationInterpolationController::s_InterpolatorForImage;
00031
00032 mitk::SegmentationInterpolationController* mitk::SegmentationInterpolationController::InterpolatorForImage(const Image* image)
00033 {
00034 InterpolatorMapType::iterator iter = s_InterpolatorForImage.find( image );
00035 if ( iter != s_InterpolatorForImage.end() )
00036 {
00037 return iter->second;
00038 }
00039 else
00040 {
00041 return NULL;
00042 }
00043 }
00044
00045 mitk::SegmentationInterpolationController::SegmentationInterpolationController()
00046 :m_BlockModified(false)
00047 {
00048 }
00049
00050 mitk::SegmentationInterpolationController::~SegmentationInterpolationController()
00051 {
00052
00053 for ( InterpolatorMapType::iterator iter = s_InterpolatorForImage.begin();
00054 iter != s_InterpolatorForImage.end();
00055 ++iter )
00056 {
00057 if (iter->second == this)
00058 {
00059 s_InterpolatorForImage.erase( iter );
00060 break;
00061 }
00062 }
00063 }
00064
00065 void mitk::SegmentationInterpolationController::OnImageModified(const itk::EventObject&)
00066 {
00067 if (!m_BlockModified && m_Segmentation.IsNotNull() )
00068 {
00069 SetSegmentationVolume( m_Segmentation );
00070 }
00071 }
00072
00073 void mitk::SegmentationInterpolationController::BlockModified(bool block)
00074 {
00075 m_BlockModified = block;
00076 }
00077
00078 void mitk::SegmentationInterpolationController::SetSegmentationVolume( const Image* segmentation )
00079 {
00080
00081 m_SegmentationCountInSlice.clear();
00082
00083
00084 InterpolatorMapType::iterator iter = s_InterpolatorForImage.find( segmentation );
00085 if ( iter != s_InterpolatorForImage.end() )
00086 {
00087 s_InterpolatorForImage.erase( iter );
00088 }
00089
00090 if (!segmentation) return;
00091 if (segmentation->GetDimension() > 4 || segmentation->GetDimension() < 3)
00092 {
00093 itkExceptionMacro("SegmentationInterpolationController needs a 3D-segmentation or 3D+t, not 2D.");
00094 }
00095
00096 if (m_Segmentation != segmentation)
00097 {
00098
00099 itk::ReceptorMemberCommand<SegmentationInterpolationController>::Pointer command = itk::ReceptorMemberCommand<SegmentationInterpolationController>::New();
00100 command->SetCallbackFunction( this, &SegmentationInterpolationController::OnImageModified );
00101 segmentation->AddObserver( itk::ModifiedEvent(), command );
00102 }
00103
00104 m_Segmentation = segmentation;
00105
00106 m_SegmentationCountInSlice.resize( m_Segmentation->GetTimeSteps() );
00107 for (unsigned int timeStep = 0; timeStep < m_Segmentation->GetTimeSteps(); ++timeStep)
00108 {
00109 m_SegmentationCountInSlice[timeStep].resize(3);
00110 for (unsigned int dim = 0; dim < 3; ++dim)
00111 {
00112 m_SegmentationCountInSlice[timeStep][dim].clear();
00113 m_SegmentationCountInSlice[timeStep][dim].resize( m_Segmentation->GetDimension(dim) );
00114 m_SegmentationCountInSlice[timeStep][dim].assign( m_Segmentation->GetDimension(dim), 0 );
00115 }
00116 }
00117
00118 s_InterpolatorForImage.insert( std::make_pair( m_Segmentation, this ) );
00119
00120
00121
00122 for (unsigned int timeStep = 0; timeStep < m_Segmentation->GetTimeSteps(); ++timeStep)
00123 {
00124 ImageTimeSelector::Pointer timeSelector = ImageTimeSelector::New();
00125 timeSelector->SetInput( m_Segmentation );
00126 timeSelector->SetTimeNr( timeStep );
00127 timeSelector->UpdateLargestPossibleRegion();
00128 Image::Pointer segmentation3D = timeSelector->GetOutput();
00129 AccessFixedDimensionByItk_2( segmentation3D, ScanWholeVolume, 3, m_Segmentation, timeStep );
00130 }
00131
00132
00133
00134 SetReferenceVolume( m_ReferenceImage );
00135
00136 Modified();
00137 }
00138
00139 void mitk::SegmentationInterpolationController::SetReferenceVolume( const Image* referenceImage )
00140 {
00141 m_ReferenceImage = referenceImage;
00142
00143 if ( m_ReferenceImage.IsNull() ) return;
00144 assert ( m_Segmentation.IsNotNull() );
00145
00146
00147 if ( m_ReferenceImage.IsNull()
00148 || m_Segmentation.IsNull()
00149 || m_ReferenceImage->GetDimension() != m_Segmentation->GetDimension()
00150 || m_ReferenceImage->GetPixelType().GetNumberOfComponents() != 1
00151 || m_Segmentation->GetPixelType().GetNumberOfComponents() != 1
00152 )
00153 {
00154 MITK_ERROR << "original patient image does not match segmentation, ignoring patient image" << std::endl;
00155 m_ReferenceImage = NULL;
00156 return;
00157 }
00158
00159 for (unsigned int dim = 0; dim < m_Segmentation->GetDimension(); ++dim)
00160 if ( m_ReferenceImage->GetDimension(dim) != m_Segmentation->GetDimension(dim) )
00161 {
00162 MITK_ERROR << "original patient image does not match segmentation (different extent in dimension " << dim
00163 << "), ignoring patient image" << std::endl;
00164 m_ReferenceImage = NULL;
00165 return;
00166 }
00167 }
00168
00169 void mitk::SegmentationInterpolationController::SetChangedVolume( const Image* sliceDiff, unsigned int timeStep )
00170 {
00171 if ( !sliceDiff ) return;
00172 if ( sliceDiff->GetDimension() != 3 ) return;
00173
00174 AccessFixedDimensionByItk_1( sliceDiff, ScanChangedVolume, 3, timeStep );
00175
00176
00177 Modified();
00178 }
00179
00180
00181 void mitk::SegmentationInterpolationController::SetChangedSlice( const Image* sliceDiff, unsigned int sliceDimension, unsigned int sliceIndex, unsigned int timeStep )
00182 {
00183 if ( !sliceDiff ) return;
00184 if ( sliceDimension > 2 ) return;
00185 if ( timeStep >= m_SegmentationCountInSlice.size() ) return;
00186 if ( sliceIndex >= m_SegmentationCountInSlice[timeStep][sliceDimension].size() ) return;
00187
00188 unsigned int dim0(0);
00189 unsigned int dim1(1);
00190
00191
00192 switch (sliceDimension)
00193 {
00194 default:
00195 case 2:
00196 dim0 = 0; dim1 = 1; break;
00197 case 1:
00198 dim0 = 0; dim1 = 2; break;
00199 case 0:
00200 dim0 = 1; dim1 = 2; break;
00201 }
00202
00203 mitkIpPicDescriptor* rawSlice = const_cast<Image*>(sliceDiff)->GetSliceData()->GetPicDescriptor();
00204 if (!rawSlice) return;
00205
00206 AccessFixedDimensionByItk_1( sliceDiff, ScanChangedSlice, 2, SetChangedSliceOptions(sliceDimension, sliceIndex, dim0, dim1, timeStep, rawSlice->data) );
00207
00208
00209
00210 Modified();
00211 }
00212
00213 template < typename DATATYPE >
00214 void mitk::SegmentationInterpolationController::ScanChangedSlice( itk::Image<DATATYPE, 2>*, const SetChangedSliceOptions& options )
00215 {
00216 DATATYPE* pixelData( (DATATYPE*)options.pixelData );
00217
00218 unsigned int timeStep( options.timeStep );
00219
00220 unsigned int sliceDimension( options.sliceDimension );
00221 unsigned int sliceIndex( options.sliceIndex );
00222
00223 if ( sliceDimension > 2 ) return;
00224 if ( sliceIndex >= m_SegmentationCountInSlice[timeStep][sliceDimension].size() ) return;
00225
00226 unsigned int dim0( options.dim0 );
00227 unsigned int dim1( options.dim1 );
00228
00229 int numberOfPixels(0);
00230
00231 unsigned int dim0max = m_SegmentationCountInSlice[timeStep][dim0].size();
00232 unsigned int dim1max = m_SegmentationCountInSlice[timeStep][dim1].size();
00233
00234
00235
00236 for (unsigned int v = 0; v < dim1max; ++v)
00237 {
00238 for (unsigned int u = 0; u < dim0max; ++u)
00239 {
00240 DATATYPE value = *(pixelData + u + v * dim0max);
00241
00242 assert ( (signed) m_SegmentationCountInSlice[timeStep][dim0][u] + (signed)value >= 0 );
00243 assert ( (signed) m_SegmentationCountInSlice[timeStep][dim1][v] + (signed)value >= 0 );
00244
00245 m_SegmentationCountInSlice[timeStep][dim0][u] = static_cast<unsigned int>( m_SegmentationCountInSlice[timeStep][dim0][u] + value );
00246 m_SegmentationCountInSlice[timeStep][dim1][v] = static_cast<unsigned int>( m_SegmentationCountInSlice[timeStep][dim1][v] + value );
00247 numberOfPixels += static_cast<int>( value );
00248 }
00249 }
00250
00251
00252 assert ( (signed) m_SegmentationCountInSlice[timeStep][sliceDimension][sliceIndex] + numberOfPixels >= 0 );
00253 m_SegmentationCountInSlice[timeStep][sliceDimension][sliceIndex] += numberOfPixels;
00254
00255
00256 }
00257
00258
00259 template < typename TPixel, unsigned int VImageDimension >
00260 void mitk::SegmentationInterpolationController::ScanChangedVolume( itk::Image<TPixel, VImageDimension>* diffImage, unsigned int timeStep )
00261 {
00262 typedef itk::ImageSliceConstIteratorWithIndex< itk::Image<TPixel, VImageDimension> > IteratorType;
00263
00264 IteratorType iter( diffImage, diffImage->GetLargestPossibleRegion() );
00265 iter.SetFirstDirection(0);
00266 iter.SetSecondDirection(1);
00267
00268 int numberOfPixels(0);
00269
00270 typename IteratorType::IndexType index;
00271 unsigned int x = 0;
00272 unsigned int y = 0;
00273 unsigned int z = 0;
00274
00275 iter.GoToBegin();
00276 while ( !iter.IsAtEnd() )
00277 {
00278 while ( !iter.IsAtEndOfSlice() )
00279 {
00280 while ( !iter.IsAtEndOfLine() )
00281 {
00282 index = iter.GetIndex();
00283
00284 x = index[0];
00285 y = index[1];
00286 z = index[2];
00287
00288 TPixel value = iter.Get();
00289
00290 assert ( (signed) m_SegmentationCountInSlice[timeStep][0][x] + (signed)value >= 0 );
00291 assert ( (signed) m_SegmentationCountInSlice[timeStep][1][y] + (signed)value >= 0 );
00292
00293 m_SegmentationCountInSlice[timeStep][0][x] = static_cast<unsigned int>( m_SegmentationCountInSlice[timeStep][0][x] + value );
00294 m_SegmentationCountInSlice[timeStep][1][y] = static_cast<unsigned int>( m_SegmentationCountInSlice[timeStep][1][y] + value );
00295
00296 numberOfPixels += static_cast<int>( value );
00297
00298 ++iter;
00299 }
00300 iter.NextLine();
00301 }
00302 assert ( (signed) m_SegmentationCountInSlice[timeStep][2][z] + numberOfPixels >= 0 );
00303 m_SegmentationCountInSlice[timeStep][2][z] += numberOfPixels;
00304 numberOfPixels = 0;
00305
00306 iter.NextSlice();
00307 }
00308 }
00309
00310
00311 template < typename DATATYPE >
00312 void mitk::SegmentationInterpolationController::ScanWholeVolume( itk::Image<DATATYPE, 3>*, const Image* volume, unsigned int timeStep )
00313 {
00314 if (!volume) return;
00315 if ( timeStep >= m_SegmentationCountInSlice.size() ) return;
00316
00317 for (unsigned int slice = 0; slice < volume->GetDimension(2); ++slice)
00318 {
00319 DATATYPE* rawVolume = static_cast<DATATYPE*>( const_cast<Image*>(volume)->GetVolumeData(timeStep)->GetData() );
00320
00321 DATATYPE* rawSlice = rawVolume + ( volume->GetDimension(0) * volume->GetDimension(1) * slice );
00322
00323 ScanChangedSlice<DATATYPE>( NULL, SetChangedSliceOptions(2, slice, 0, 1, timeStep, rawSlice) );
00324 }
00325 }
00326
00327 void mitk::SegmentationInterpolationController::PrintStatus()
00328 {
00329 unsigned int timeStep(0);
00330
00331 MITK_INFO << "Interpolator status (timestep 0): dimensions "
00332 << m_SegmentationCountInSlice[timeStep][0].size() << " "
00333 << m_SegmentationCountInSlice[timeStep][1].size() << " "
00334 << m_SegmentationCountInSlice[timeStep][2].size() << std::endl;
00335
00336 MITK_INFO << "Slice 0: " << m_SegmentationCountInSlice[timeStep][2][0] << std::endl;
00337
00338
00339 for (unsigned int index = 0; index < m_SegmentationCountInSlice[timeStep][0].size(); ++index)
00340 {
00341 if ( m_SegmentationCountInSlice[timeStep][0][index] > 0 )
00342 MITK_INFO << "O";
00343 else
00344 MITK_INFO << ".";
00345 }
00346 MITK_INFO << std::endl;
00347
00348
00349 for (unsigned int index = 1; index < m_SegmentationCountInSlice[timeStep][1].size(); ++index)
00350 {
00351 if ( m_SegmentationCountInSlice[timeStep][1][index] > 0 )
00352 MITK_INFO << "O";
00353 else
00354 MITK_INFO << ".";
00355
00356 if ( m_SegmentationCountInSlice[timeStep][2].size() > index )
00357 {
00358 for (unsigned int indent = 1; indent < index; ++indent)
00359 MITK_INFO << " ";
00360
00361 if ( m_SegmentationCountInSlice[timeStep][2][index] > 0 )
00362 MITK_INFO << m_SegmentationCountInSlice[timeStep][2][index];
00363 else
00364 MITK_INFO << ".";
00365 }
00366
00367 MITK_INFO << std::endl;
00368 }
00369
00370
00371 for (unsigned int index = m_SegmentationCountInSlice[timeStep][1].size(); index < m_SegmentationCountInSlice[timeStep][2].size(); ++index)
00372 {
00373 for (unsigned int indent = 0; indent < index; ++indent)
00374 MITK_INFO << " ";
00375
00376 if ( m_SegmentationCountInSlice[timeStep][2][index] > 0 )
00377 MITK_INFO << m_SegmentationCountInSlice[timeStep][2][index];
00378 else
00379 MITK_INFO << ".";
00380
00381 MITK_INFO << std::endl;
00382 }
00383 }
00384
00385 mitk::Image::Pointer mitk::SegmentationInterpolationController::Interpolate( unsigned int sliceDimension, unsigned int sliceIndex, unsigned int timeStep )
00386 {
00387 if (m_Segmentation.IsNull()) return NULL;
00388
00389 if ( timeStep >= m_SegmentationCountInSlice.size() ) return NULL;
00390 if ( sliceDimension > 2 ) return NULL;
00391 unsigned int upperLimit = m_SegmentationCountInSlice[timeStep][sliceDimension].size();
00392 if ( sliceIndex >= upperLimit - 1 ) return NULL;
00393 if ( sliceIndex < 1 ) return NULL;
00394
00395 if ( m_SegmentationCountInSlice[timeStep][sliceDimension][sliceIndex] > 0 ) return NULL;
00396
00397 unsigned int lowerBound(0);
00398 unsigned int upperBound(0);
00399 bool bounds( false );
00400
00401 for (lowerBound = sliceIndex - 1; ; --lowerBound)
00402 {
00403 if ( m_SegmentationCountInSlice[timeStep][sliceDimension][lowerBound] > 0 )
00404 {
00405 bounds = true;
00406 break;
00407 }
00408
00409 if (lowerBound == 0) break;
00410 }
00411
00412 if (!bounds) return NULL;
00413
00414 bounds = false;
00415 for (upperBound = sliceIndex + 1 ; upperBound < upperLimit; ++upperBound)
00416 {
00417 if ( m_SegmentationCountInSlice[timeStep][sliceDimension][upperBound] > 0 )
00418 {
00419 bounds = true;
00420 break;
00421 }
00422 }
00423
00424 if (!bounds) return NULL;
00425
00426
00427
00428
00429 mitk::Image::Pointer lowerMITKSlice;
00430 mitk::Image::Pointer upperMITKSlice;
00431 mitk::Image::Pointer resultImage;
00432 try
00433 {
00434
00435 ExtractImageFilter::Pointer extractor= ExtractImageFilter::New();
00436 extractor->SetInput( m_Segmentation );
00437 extractor->SetSliceDimension( sliceDimension );
00438 extractor->SetSliceIndex( lowerBound );
00439 extractor->SetTimeStep( timeStep );
00440 extractor->Update();
00441 lowerMITKSlice = extractor->GetOutput();
00442 lowerMITKSlice->DisconnectPipeline();
00443
00444 extractor->SetInput( m_Segmentation );
00445 extractor->SetSliceDimension( sliceDimension );
00446 extractor->SetSliceIndex( sliceIndex );
00447 extractor->SetTimeStep( timeStep );
00448 extractor->Update();
00449 resultImage = extractor->GetOutput();
00450 resultImage->DisconnectPipeline();
00451
00452 extractor->SetInput( m_Segmentation );
00453 extractor->SetSliceDimension( sliceDimension );
00454 extractor->SetSliceIndex( upperBound );
00455 extractor->SetTimeStep( timeStep );
00456 extractor->Update();
00457 upperMITKSlice = extractor->GetOutput();
00458
00459 if ( lowerMITKSlice.IsNull() || upperMITKSlice.IsNull() ) return NULL;
00460 }
00461 catch(...)
00462 {
00463 return NULL;
00464 }
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475 mitk::SegmentationInterpolationAlgorithm::Pointer algorithm = mitk::ShapeBasedInterpolationAlgorithm::New().GetPointer();
00476 return algorithm->Interpolate( lowerMITKSlice.GetPointer(), lowerBound,
00477 upperMITKSlice.GetPointer(), upperBound,
00478 sliceIndex,
00479 sliceDimension,
00480 resultImage,
00481 timeStep,
00482 m_ReferenceImage );
00483
00484 }
00485