00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "mitkImageStatisticsCalculator.h"
00020 #include "mitkImageAccessByItk.h"
00021 #include "mitkExtractImageFilter.h"
00022
00023 #include <itkScalarImageToHistogramGenerator.h>
00024
00025 #include <itkStatisticsImageFilter.h>
00026 #include <itkLabelStatisticsImageFilter.h>
00027
00028 #include <itkCastImageFilter.h>
00029 #include <itkImageFileWriter.h>
00030 #include <itkVTKImageImport.h>
00031 #include <itkVTKImageExport.h>
00032
00033
00034 #include <vtkPoints.h>
00035 #include <vtkCellArray.h>
00036 #include <vtkPolyData.h>
00037 #include <vtkLinearExtrusionFilter.h>
00038 #include <vtkPolyDataToImageStencil.h>
00039 #include <vtkImageStencil.h>
00040 #include <vtkImageImport.h>
00041 #include <vtkImageExport.h>
00042 #include <vtkImageData.h>
00043
00044 #include <vtkMetaImageWriter.h>
00045
00046 #include <exception>
00047
00048
00049
00050
00051 namespace mitk
00052 {
00053
00054 ImageStatisticsCalculator::ImageStatisticsCalculator()
00055 : m_MaskingMode( MASKING_MODE_NONE ),
00056 m_MaskingModeChanged( false )
00057 {
00058 m_EmptyHistogram = HistogramType::New();
00059 HistogramType::SizeType histogramSize;
00060 histogramSize.Fill( 256 );
00061 m_EmptyHistogram->Initialize( histogramSize );
00062
00063 m_EmptyStatistics.Reset();
00064 }
00065
00066
00067 ImageStatisticsCalculator::~ImageStatisticsCalculator()
00068 {
00069 }
00070
00071
00072 void ImageStatisticsCalculator::SetImage( const mitk::Image *image )
00073 {
00074 if ( m_Image != image )
00075 {
00076 m_Image = image;
00077 this->Modified();
00078
00079 unsigned int numberOfTimeSteps = image->GetTimeSteps();
00080
00081
00082 m_ImageHistogramVector.resize( numberOfTimeSteps );
00083 m_MaskedImageHistogramVector.resize( numberOfTimeSteps );
00084 m_PlanarFigureHistogramVector.resize( numberOfTimeSteps );
00085
00086 m_ImageStatisticsVector.resize( numberOfTimeSteps );
00087 m_MaskedImageStatisticsVector.resize( numberOfTimeSteps );
00088 m_PlanarFigureStatisticsVector.resize( numberOfTimeSteps );
00089
00090 m_ImageStatisticsTimeStampVector.resize( numberOfTimeSteps );
00091 m_MaskedImageStatisticsTimeStampVector.resize( numberOfTimeSteps );
00092 m_PlanarFigureStatisticsTimeStampVector.resize( numberOfTimeSteps );
00093
00094 m_ImageStatisticsCalculationTriggerVector.resize( numberOfTimeSteps );
00095 m_MaskedImageStatisticsCalculationTriggerVector.resize( numberOfTimeSteps );
00096 m_PlanarFigureStatisticsCalculationTriggerVector.resize( numberOfTimeSteps );
00097
00098 for ( unsigned int t = 0; t < image->GetTimeSteps(); ++t )
00099 {
00100 m_ImageStatisticsTimeStampVector[t].Modified();
00101 m_ImageStatisticsCalculationTriggerVector[t] = true;
00102 }
00103 }
00104 }
00105
00106
00107 void ImageStatisticsCalculator::SetImageMask( const mitk::Image *imageMask )
00108 {
00109 if ( m_Image.IsNull() )
00110 {
00111 itkExceptionMacro( << "Image needs to be set first!" );
00112 }
00113
00114 if ( m_Image->GetTimeSteps() != imageMask->GetTimeSteps() )
00115 {
00116 itkExceptionMacro( << "Image and image mask need to have equal number of time steps!" );
00117 }
00118
00119 if ( m_ImageMask != imageMask )
00120 {
00121 m_ImageMask = imageMask;
00122 this->Modified();
00123
00124 for ( unsigned int t = 0; t < m_Image->GetTimeSteps(); ++t )
00125 {
00126 m_MaskedImageStatisticsTimeStampVector[t].Modified();
00127 m_MaskedImageStatisticsCalculationTriggerVector[t] = true;
00128 }
00129 }
00130 }
00131
00132
00133 void ImageStatisticsCalculator::SetPlanarFigure( const mitk::PlanarFigure *planarFigure )
00134 {
00135 if ( m_Image.IsNull() )
00136 {
00137 itkExceptionMacro( << "Image needs to be set first!" );
00138 }
00139
00140 if ( m_PlanarFigure != planarFigure )
00141 {
00142 m_PlanarFigure = planarFigure;
00143 this->Modified();
00144
00145 for ( unsigned int t = 0; t < m_Image->GetTimeSteps(); ++t )
00146 {
00147 m_PlanarFigureStatisticsTimeStampVector[t].Modified();
00148 m_PlanarFigureStatisticsCalculationTriggerVector[t] = true;
00149 }
00150 }
00151 }
00152
00153
00154 void ImageStatisticsCalculator::SetMaskingMode( unsigned int mode )
00155 {
00156 if ( m_MaskingMode != mode )
00157 {
00158 m_MaskingMode = mode;
00159 m_MaskingModeChanged = true;
00160 this->Modified();
00161 }
00162 }
00163
00164
00165 void ImageStatisticsCalculator::SetMaskingModeToNone()
00166 {
00167 if ( m_MaskingMode != MASKING_MODE_NONE )
00168 {
00169 m_MaskingMode = MASKING_MODE_NONE;
00170 m_MaskingModeChanged = true;
00171 this->Modified();
00172 }
00173 }
00174
00175
00176 void ImageStatisticsCalculator::SetMaskingModeToImage()
00177 {
00178 if ( m_MaskingMode != MASKING_MODE_IMAGE )
00179 {
00180 m_MaskingMode = MASKING_MODE_IMAGE;
00181 m_MaskingModeChanged = true;
00182 this->Modified();
00183 }
00184 }
00185
00186
00187 void ImageStatisticsCalculator::SetMaskingModeToPlanarFigure()
00188 {
00189 if ( m_MaskingMode != MASKING_MODE_PLANARFIGURE )
00190 {
00191 m_MaskingMode = MASKING_MODE_PLANARFIGURE;
00192 m_MaskingModeChanged = true;
00193 this->Modified();
00194 }
00195 }
00196
00197
00198
00199 bool ImageStatisticsCalculator::ComputeStatistics( unsigned int timeStep )
00200 {
00201 if ( m_Image.IsNull() )
00202 {
00203 itkExceptionMacro( << "Image not set!" );
00204 }
00205
00206 if ( m_Image->GetReferenceCount() == 1 )
00207 {
00208
00209 return false;
00210 }
00211
00212 if ( timeStep >= m_Image->GetTimeSteps() )
00213 {
00214 throw std::runtime_error( "Error: invalid time step!" );
00215 }
00216
00217
00218
00219 if ( m_ImageMask.IsNotNull() && (m_ImageMask->GetReferenceCount() == 1) )
00220 {
00221 m_ImageMask = NULL;
00222 }
00223
00224
00225
00226 unsigned long imageMTime = m_ImageStatisticsTimeStampVector[timeStep].GetMTime();
00227 unsigned long maskedImageMTime = m_MaskedImageStatisticsTimeStampVector[timeStep].GetMTime();
00228 unsigned long planarFigureMTime = m_PlanarFigureStatisticsTimeStampVector[timeStep].GetMTime();
00229
00230 bool imageStatisticsCalculationTrigger = m_ImageStatisticsCalculationTriggerVector[timeStep];
00231 bool maskedImageStatisticsCalculationTrigger = m_MaskedImageStatisticsCalculationTriggerVector[timeStep];
00232 bool planarFigureStatisticsCalculationTrigger = m_PlanarFigureStatisticsCalculationTriggerVector[timeStep];
00233
00234 if ( ((m_MaskingMode != MASKING_MODE_NONE) || (imageMTime > m_Image->GetMTime() && !imageStatisticsCalculationTrigger))
00235 && ((m_MaskingMode != MASKING_MODE_IMAGE) || (maskedImageMTime > m_ImageMask->GetMTime() && !maskedImageStatisticsCalculationTrigger))
00236 && ((m_MaskingMode != MASKING_MODE_PLANARFIGURE) || (planarFigureMTime > m_PlanarFigure->GetMTime() && !planarFigureStatisticsCalculationTrigger)) )
00237 {
00238
00239 if ( m_MaskingModeChanged )
00240 {
00241 m_MaskingModeChanged = false;
00242 return true;
00243 }
00244 else
00245 {
00246 return false;
00247 }
00248 }
00249
00250
00251 m_MaskingModeChanged = false;
00252
00253
00254
00255
00256 this->ExtractImageAndMask( timeStep );
00257
00258
00259 Statistics *statistics;
00260 HistogramType::ConstPointer *histogram;
00261 switch ( m_MaskingMode )
00262 {
00263 case MASKING_MODE_NONE:
00264 default:
00265 statistics = &m_ImageStatisticsVector[timeStep];
00266 histogram = &m_ImageHistogramVector[timeStep];
00267
00268 m_ImageStatisticsTimeStampVector[timeStep].Modified();
00269 m_ImageStatisticsCalculationTriggerVector[timeStep] = false;
00270 break;
00271
00272 case MASKING_MODE_IMAGE:
00273 statistics = &m_MaskedImageStatisticsVector[timeStep];
00274 histogram = &m_MaskedImageHistogramVector[timeStep];
00275
00276 m_MaskedImageStatisticsTimeStampVector[timeStep].Modified();
00277 m_MaskedImageStatisticsCalculationTriggerVector[timeStep] = false;
00278 break;
00279
00280 case MASKING_MODE_PLANARFIGURE:
00281 statistics = &m_PlanarFigureStatisticsVector[timeStep];
00282 histogram = &m_PlanarFigureHistogramVector[timeStep];
00283
00284 m_PlanarFigureStatisticsTimeStampVector[timeStep].Modified();
00285 m_PlanarFigureStatisticsCalculationTriggerVector[timeStep] = false;
00286 break;
00287 }
00288
00289
00290 if ( m_InternalImage->GetDimension() == 3 )
00291 {
00292 if ( m_MaskingMode == MASKING_MODE_NONE )
00293 {
00294 AccessFixedDimensionByItk_2(
00295 m_InternalImage,
00296 InternalCalculateStatisticsUnmasked,
00297 3,
00298 *statistics,
00299 histogram );
00300 }
00301 else
00302 {
00303 AccessFixedDimensionByItk_3(
00304 m_InternalImage,
00305 InternalCalculateStatisticsMasked,
00306 3,
00307 m_InternalImageMask3D.GetPointer(),
00308 *statistics,
00309 histogram );
00310 }
00311 }
00312 else if ( m_InternalImage->GetDimension() == 2 )
00313 {
00314 if ( m_MaskingMode == MASKING_MODE_NONE )
00315 {
00316 AccessFixedDimensionByItk_2(
00317 m_InternalImage,
00318 InternalCalculateStatisticsUnmasked,
00319 2,
00320 *statistics,
00321 histogram );
00322 }
00323 else
00324 {
00325 AccessFixedDimensionByItk_3(
00326 m_InternalImage,
00327 InternalCalculateStatisticsMasked,
00328 2,
00329 m_InternalImageMask2D.GetPointer(),
00330 *statistics,
00331 histogram );
00332 }
00333 }
00334 else
00335 {
00336 MITK_ERROR << "ImageStatistics: Image dimension not supported!";
00337 }
00338
00339
00340
00341 m_InternalImage = mitk::Image::ConstPointer();
00342 m_InternalImageMask3D = MaskImage3DType::Pointer();
00343 m_InternalImageMask2D = MaskImage2DType::Pointer();
00344 return true;
00345 }
00346
00347
00348 const ImageStatisticsCalculator::HistogramType *
00349 ImageStatisticsCalculator::GetHistogram( unsigned int timeStep ) const
00350 {
00351 if ( m_Image.IsNull() || (timeStep >= m_Image->GetTimeSteps()) )
00352 {
00353 return NULL;
00354 }
00355
00356 switch ( m_MaskingMode )
00357 {
00358 case MASKING_MODE_NONE:
00359 default:
00360 return m_ImageHistogramVector[timeStep];
00361
00362 case MASKING_MODE_IMAGE:
00363 return m_MaskedImageHistogramVector[timeStep];
00364
00365 case MASKING_MODE_PLANARFIGURE:
00366 return m_PlanarFigureHistogramVector[timeStep];
00367 }
00368 }
00369
00370
00371 const ImageStatisticsCalculator::Statistics &
00372 ImageStatisticsCalculator::GetStatistics( unsigned int timeStep ) const
00373 {
00374 if ( m_Image.IsNull() || (timeStep >= m_Image->GetTimeSteps()) )
00375 {
00376 return m_EmptyStatistics;
00377 }
00378
00379 switch ( m_MaskingMode )
00380 {
00381 case MASKING_MODE_NONE:
00382 default:
00383 return m_ImageStatisticsVector[timeStep];
00384
00385 case MASKING_MODE_IMAGE:
00386 return m_MaskedImageStatisticsVector[timeStep];
00387
00388 case MASKING_MODE_PLANARFIGURE:
00389 return m_PlanarFigureStatisticsVector[timeStep];
00390 }
00391 }
00392
00393
00394 void ImageStatisticsCalculator::ExtractImageAndMask( unsigned int timeStep )
00395 {
00396 if ( m_Image.IsNull() )
00397 {
00398 throw std::runtime_error( "Error: image empty!" );
00399 }
00400
00401 if ( timeStep >= m_Image->GetTimeSteps() )
00402 {
00403 throw std::runtime_error( "Error: invalid time step!" );
00404 }
00405
00406 ImageTimeSelector::Pointer imageTimeSelector = ImageTimeSelector::New();
00407 imageTimeSelector->SetInput( m_Image );
00408 imageTimeSelector->SetTimeNr( timeStep );
00409 imageTimeSelector->UpdateLargestPossibleRegion();
00410 mitk::Image *timeSliceImage = imageTimeSelector->GetOutput();
00411
00412
00413 switch ( m_MaskingMode )
00414 {
00415 case MASKING_MODE_NONE:
00416 {
00417 m_InternalImage = timeSliceImage;
00418 m_InternalImageMask2D = NULL;
00419 m_InternalImageMask3D = NULL;
00420 break;
00421 }
00422
00423 case MASKING_MODE_IMAGE:
00424 {
00425 if ( m_ImageMask.IsNotNull() && (m_ImageMask->GetReferenceCount() > 1) )
00426 {
00427 if ( timeStep < m_ImageMask->GetTimeSteps() )
00428 {
00429 ImageTimeSelector::Pointer maskedImageTimeSelector = ImageTimeSelector::New();
00430 maskedImageTimeSelector->SetInput( m_ImageMask );
00431 maskedImageTimeSelector->SetTimeNr( timeStep );
00432 maskedImageTimeSelector->UpdateLargestPossibleRegion();
00433 mitk::Image *timeSliceMaskedImage = maskedImageTimeSelector->GetOutput();
00434
00435 m_InternalImage = timeSliceImage;
00436 CastToItkImage( timeSliceMaskedImage, m_InternalImageMask3D );
00437 }
00438 else
00439 {
00440 throw std::runtime_error( "Error: image mask has not enough time steps!" );
00441 }
00442 }
00443 else
00444 {
00445 throw std::runtime_error( "Error: image mask empty!" );
00446 }
00447 break;
00448 }
00449
00450 case MASKING_MODE_PLANARFIGURE:
00451 {
00452 m_InternalImageMask2D = NULL;
00453
00454 if ( m_PlanarFigure.IsNull() )
00455 {
00456 throw std::runtime_error( "Error: planar figure empty!" );
00457 }
00458 if ( !m_PlanarFigure->IsClosed() )
00459 {
00460 throw std::runtime_error( "Masking not possible for non-closed figures" );
00461 }
00462
00463 const Geometry3D *imageGeometry = timeSliceImage->GetGeometry();
00464 if ( imageGeometry == NULL )
00465 {
00466 throw std::runtime_error( "Image geometry invalid!" );
00467 }
00468
00469 const Geometry2D *planarFigureGeometry2D = m_PlanarFigure->GetGeometry2D();
00470 if ( planarFigureGeometry2D == NULL )
00471 {
00472 throw std::runtime_error( "Planar-Figure not yet initialized!" );
00473 }
00474
00475 const PlaneGeometry *planarFigureGeometry =
00476 dynamic_cast< const PlaneGeometry * >( planarFigureGeometry2D );
00477 if ( planarFigureGeometry == NULL )
00478 {
00479 throw std::runtime_error( "Non-planar planar figures not supported!" );
00480 }
00481
00482
00483 unsigned int axis;
00484 if ( !this->GetPrincipalAxis( imageGeometry,
00485 planarFigureGeometry->GetNormal(), axis ) )
00486 {
00487 throw std::runtime_error( "Non-aligned planar figures not supported!" );
00488 }
00489
00490
00491
00492 MaskImage3DType::IndexType index;
00493 imageGeometry->WorldToIndex( planarFigureGeometry->GetOrigin(), index );
00494
00495 unsigned int slice = index[axis];
00496
00497
00498
00499 ExtractImageFilter::Pointer imageExtractor = ExtractImageFilter::New();
00500 imageExtractor->SetInput( timeSliceImage );
00501 imageExtractor->SetSliceDimension( axis );
00502 imageExtractor->SetSliceIndex( slice );
00503 imageExtractor->Update();
00504 m_InternalImage = imageExtractor->GetOutput();
00505
00506
00507
00508 AccessFixedDimensionByItk_1(
00509 m_InternalImage,
00510 InternalCalculateMaskFromPlanarFigure,
00511 2, axis );
00512 }
00513 }
00514 }
00515
00516
00517 bool ImageStatisticsCalculator::GetPrincipalAxis(
00518 const Geometry3D *geometry, Vector3D vector,
00519 unsigned int &axis )
00520 {
00521 vector.Normalize();
00522 for ( unsigned int i = 0; i < 3; ++i )
00523 {
00524 Vector3D axisVector = geometry->GetAxisVector( i );
00525 axisVector.Normalize();
00526
00527 if ( fabs( fabs( axisVector * vector ) - 1.0) < mitk::eps )
00528 {
00529 axis = i;
00530 return true;
00531 }
00532 }
00533
00534 return false;
00535 }
00536
00537
00538 template < typename TPixel, unsigned int VImageDimension >
00539 void ImageStatisticsCalculator::InternalCalculateStatisticsUnmasked(
00540 const itk::Image< TPixel, VImageDimension > *image,
00541 Statistics &statistics,
00542 typename HistogramType::ConstPointer *histogram )
00543 {
00544 typedef itk::Image< TPixel, VImageDimension > ImageType;
00545 typedef itk::Image< unsigned short, VImageDimension > MaskImageType;
00546 typedef typename ImageType::IndexType IndexType;
00547
00548 typedef itk::Statistics::ScalarImageToHistogramGenerator< ImageType >
00549 HistogramGeneratorType;
00550
00551
00552 typedef itk::SimpleMemberCommand< ImageStatisticsCalculator > ITKCommandType;
00553 ITKCommandType::Pointer progressListener;
00554 progressListener = ITKCommandType::New();
00555 progressListener->SetCallbackFunction( this,
00556 &ImageStatisticsCalculator::UnmaskedStatisticsProgressUpdate );
00557
00558
00559
00560
00561 this->InvokeEvent( itk::StartEvent() );
00562 for ( unsigned int i = 0; i < 100; ++i )
00563 {
00564 this->UnmaskedStatisticsProgressUpdate();
00565 }
00566
00567
00568 typename HistogramGeneratorType::Pointer histogramGenerator = HistogramGeneratorType::New();
00569 histogramGenerator->SetInput( image );
00570 histogramGenerator->SetMarginalScale( 100 );
00571 histogramGenerator->SetNumberOfBins( 768 );
00572 histogramGenerator->SetHistogramMin( -1024.0 );
00573 histogramGenerator->SetHistogramMax( 2048.0 );
00574 histogramGenerator->Compute();
00575 *histogram = histogramGenerator->GetOutput();
00576
00577
00578 typedef itk::StatisticsImageFilter< ImageType > StatisticsFilterType;
00579 typename StatisticsFilterType::Pointer statisticsFilter = StatisticsFilterType::New();
00580 statisticsFilter->SetInput( image );
00581 unsigned long observerTag = statisticsFilter->AddObserver(
00582 itk::ProgressEvent(), progressListener );
00583
00584 statisticsFilter->Update();
00585
00586 statisticsFilter->RemoveObserver( observerTag );
00587
00588
00589 this->InvokeEvent( itk::EndEvent() );
00590
00591 statistics.N = image->GetBufferedRegion().GetNumberOfPixels();
00592 statistics.Min = statisticsFilter->GetMinimum();
00593 statistics.Max = statisticsFilter->GetMaximum();
00594 statistics.Mean = statisticsFilter->GetMean();
00595 statistics.Median = 0.0;
00596 statistics.Sigma = statisticsFilter->GetSigma();
00597 statistics.RMS = sqrt( statistics.Mean * statistics.Mean
00598 + statistics.Sigma * statistics.Sigma );
00599 }
00600
00601
00602 template < typename TPixel, unsigned int VImageDimension >
00603 void ImageStatisticsCalculator::InternalCalculateStatisticsMasked(
00604 const itk::Image< TPixel, VImageDimension > *image,
00605 itk::Image< unsigned short, VImageDimension > *maskImage,
00606 Statistics &statistics,
00607 typename HistogramType::ConstPointer *histogram )
00608 {
00609 typedef itk::Image< TPixel, VImageDimension > ImageType;
00610 typedef itk::Image< unsigned short, VImageDimension > MaskImageType;
00611 typedef typename ImageType::IndexType IndexType;
00612
00613 typedef itk::LabelStatisticsImageFilter< ImageType, MaskImageType >
00614 LabelStatisticsFilterType;
00615
00616 typename LabelStatisticsFilterType::Pointer labelStatisticsFilter;
00617
00618 unsigned int i;
00619 bool maskNonEmpty = false;
00620 if ( maskImage != NULL )
00621 {
00622
00623 labelStatisticsFilter = LabelStatisticsFilterType::New();
00624 labelStatisticsFilter->SetInput( image );
00625 labelStatisticsFilter->SetLabelInput( maskImage );
00626 labelStatisticsFilter->UseHistogramsOn();
00627 labelStatisticsFilter->SetHistogramParameters( 384, -1024.0, 2048.0);
00628
00629
00630 typedef itk::SimpleMemberCommand< ImageStatisticsCalculator > ITKCommandType;
00631 ITKCommandType::Pointer progressListener;
00632 progressListener = ITKCommandType::New();
00633 progressListener->SetCallbackFunction( this,
00634 &ImageStatisticsCalculator::MaskedStatisticsProgressUpdate );
00635 unsigned long observerTag = labelStatisticsFilter->AddObserver(
00636 itk::ProgressEvent(), progressListener );
00637
00638
00639
00640 this->InvokeEvent( itk::StartEvent() );
00641
00642 labelStatisticsFilter->Update();
00643
00644 this->InvokeEvent( itk::EndEvent() );
00645
00646 labelStatisticsFilter->RemoveObserver( observerTag );
00647
00648
00649
00650 for ( i = 1; i < 4096; ++i )
00651 {
00652 if ( labelStatisticsFilter->HasLabel( i ) )
00653 {
00654 maskNonEmpty = true;
00655 break;
00656 }
00657 }
00658 }
00659
00660 if ( maskNonEmpty )
00661 {
00662 *histogram = labelStatisticsFilter->GetHistogram( i );
00663 statistics.N = labelStatisticsFilter->GetCount( i );
00664 statistics.Min = labelStatisticsFilter->GetMinimum( i );
00665 statistics.Max = labelStatisticsFilter->GetMaximum( i );
00666 statistics.Mean = labelStatisticsFilter->GetMean( i );
00667 statistics.Median = labelStatisticsFilter->GetMedian( i );
00668 statistics.Sigma = labelStatisticsFilter->GetSigma( i );
00669 statistics.RMS = sqrt( statistics.Mean * statistics.Mean
00670 + statistics.Sigma * statistics.Sigma );
00671 }
00672 else
00673 {
00674 *histogram = m_EmptyHistogram;
00675 statistics.Reset();
00676 }
00677 }
00678
00679
00680 template < typename TPixel, unsigned int VImageDimension >
00681 void ImageStatisticsCalculator::InternalCalculateMaskFromPlanarFigure(
00682 const itk::Image< TPixel, VImageDimension > *image, unsigned int axis )
00683 {
00684 typedef itk::Image< TPixel, VImageDimension > ImageType;
00685
00686 typedef itk::CastImageFilter< ImageType, MaskImage2DType > CastFilterType;
00687
00688
00689
00690 typename CastFilterType::Pointer castFilter = CastFilterType::New();
00691 castFilter->SetInput( image );
00692 castFilter->Update();
00693 castFilter->GetOutput()->FillBuffer( 1 );
00694
00695
00696
00697
00698
00699 const mitk::Geometry2D *planarFigureGeometry2D = m_PlanarFigure->GetGeometry2D();
00700 const typename PlanarFigure::VertexContainerType *planarFigurePolyline = m_PlanarFigure->GetPolyLine( 0 );
00701 const mitk::Geometry3D *imageGeometry3D = m_Image->GetGeometry( 0 );
00702
00703 vtkPolyData *polyline = vtkPolyData::New();
00704 polyline->Allocate( 1, 1 );
00705
00706
00707 int i0, i1;
00708 switch ( axis )
00709 {
00710 case 0:
00711 i0 = 1;
00712 i1 = 2;
00713 break;
00714
00715 case 1:
00716 i0 = 0;
00717 i1 = 2;
00718 break;
00719
00720 case 2:
00721 default:
00722 i0 = 0;
00723 i1 = 1;
00724 break;
00725 }
00726
00727
00728 bool outOfBounds = false;
00729 vtkPoints *points = vtkPoints::New();
00730 typename PlanarFigure::VertexContainerType::ConstIterator it;
00731 for ( it = planarFigurePolyline->Begin();
00732 it != planarFigurePolyline->End();
00733 ++it )
00734 {
00735 Point3D point3D;
00736
00737
00738
00739 planarFigureGeometry2D->Map( it->Value(), point3D );
00740
00741
00742
00743 if ( !imageGeometry3D->IsInside( point3D ) )
00744 {
00745 outOfBounds = true;
00746 }
00747
00748 imageGeometry3D->WorldToIndex( point3D, point3D );
00749
00750
00751 points->InsertNextPoint( point3D[i0] - 0.5, point3D[i1] - 0.5, -0.5 );
00752 }
00753 polyline->SetPoints( points );
00754 points->Delete();
00755
00756 if ( outOfBounds )
00757 {
00758 polyline->Delete();
00759 throw std::runtime_error( "Figure at least partially outside of image bounds!" );
00760 }
00761
00762 unsigned int numberOfPoints = planarFigurePolyline->Size();
00763 vtkIdType *ptIds = new vtkIdType[numberOfPoints];
00764 for ( vtkIdType i = 0; i < numberOfPoints; ++i )
00765 {
00766 ptIds[i] = i;
00767 }
00768 polyline->InsertNextCell( VTK_POLY_LINE, numberOfPoints, ptIds );
00769
00770
00771
00772 vtkLinearExtrusionFilter *extrudeFilter = vtkLinearExtrusionFilter::New();
00773 extrudeFilter->SetInput( polyline );
00774 extrudeFilter->SetScaleFactor( 1 );
00775 extrudeFilter->SetExtrusionTypeToNormalExtrusion();
00776 extrudeFilter->SetVector( 0.0, 0.0, 1.0 );
00777
00778
00779 vtkPolyDataToImageStencil *polyDataToImageStencil = vtkPolyDataToImageStencil::New();
00780 polyDataToImageStencil->SetInput( extrudeFilter->GetOutput() );
00781
00782
00783
00784
00785 typedef itk::VTKImageImport< MaskImage2DType > ImageImportType;
00786 typedef itk::VTKImageExport< MaskImage2DType > ImageExportType;
00787
00788 typename ImageExportType::Pointer itkExporter = ImageExportType::New();
00789 itkExporter->SetInput( castFilter->GetOutput() );
00790
00791 vtkImageImport *vtkImporter = vtkImageImport::New();
00792 this->ConnectPipelines( itkExporter, vtkImporter );
00793 vtkImporter->Update();
00794
00795
00796
00797 vtkImageStencil *imageStencilFilter = vtkImageStencil::New();
00798 imageStencilFilter->SetInput( vtkImporter->GetOutput() );
00799 imageStencilFilter->SetStencil( polyDataToImageStencil->GetOutput() );
00800 imageStencilFilter->ReverseStencilOff();
00801 imageStencilFilter->SetBackgroundValue( 0 );
00802 imageStencilFilter->Update();
00803
00804
00805
00806 vtkImageExport *vtkExporter = vtkImageExport::New();
00807 vtkExporter->SetInput( imageStencilFilter->GetOutput() );
00808 vtkExporter->Update();
00809
00810 typename ImageImportType::Pointer itkImporter = ImageImportType::New();
00811 this->ConnectPipelines( vtkExporter, itkImporter );
00812 itkImporter->Update();
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823 m_InternalImageMask2D = itkImporter->GetOutput();
00824
00825
00826
00827 polyline->Delete();
00828 extrudeFilter->Delete();
00829 polyDataToImageStencil->Delete();
00830 vtkImporter->Delete();
00831 imageStencilFilter->Delete();
00832
00833 delete[] ptIds;
00834 }
00835
00836
00837 void ImageStatisticsCalculator::UnmaskedStatisticsProgressUpdate()
00838 {
00839
00840
00841 static int updateCounter = 0;
00842 if ( updateCounter++ % 2 == 0 )
00843 {
00844 this->InvokeEvent( itk::ProgressEvent() );
00845 }
00846 }
00847
00848
00849 void ImageStatisticsCalculator::MaskedStatisticsProgressUpdate()
00850 {
00851 this->InvokeEvent( itk::ProgressEvent() );
00852 }
00853
00854
00855 }