00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "mitkDiffImageApplier.h"
00019
00020 #include "mitkImageCast.h"
00021 #include "mitkApplyDiffImageOperation.h"
00022 #include "mitkRenderingManager.h"
00023 #include "mitkSegmentationInterpolationController.h"
00024 #include "mitkImageTimeSelector.h"
00025
00026 #include <itkImageSliceIteratorWithIndex.h>
00027 #include <itkImageRegionConstIterator.h>
00028
00029 mitk::DiffImageApplier::DiffImageApplier()
00030 {
00031 }
00032
00033 mitk::DiffImageApplier::~DiffImageApplier()
00034 {
00035 }
00036
00037 void mitk::DiffImageApplier::ExecuteOperation( Operation* operation )
00038 {
00039 ApplyDiffImageOperation* imageOperation = dynamic_cast<ApplyDiffImageOperation*>( operation );
00040 if ( imageOperation
00041 && imageOperation->IsImageStillValid() )
00042 {
00043 m_Image = imageOperation->GetImage();
00044 Image::Pointer image3D = m_Image;
00045
00046 m_SliceDifferenceImage = imageOperation->GetDiffImage();
00047 m_TimeStep = imageOperation->GetTimeStep();
00048
00049 m_Factor = imageOperation->GetFactor();
00050
00051 if ( m_SliceDifferenceImage->GetDimension() == 2 )
00052 {
00053 m_SliceIndex = imageOperation->GetSliceIndex();
00054 m_SliceDimension = imageOperation->GetSliceDimension();
00055 switch (m_SliceDimension)
00056 {
00057 default:
00058 case 2:
00059 m_Dimension0 = 0;
00060 m_Dimension1 = 1;
00061 break;
00062 case 1:
00063 m_Dimension0 = 0;
00064 m_Dimension1 = 2;
00065 break;
00066 case 0:
00067 m_Dimension0 = 1;
00068 m_Dimension1 = 2;
00069 break;
00070 }
00071
00072 if ( m_SliceDifferenceImage->GetDimension() != 2 || (m_Image->GetDimension() < 3 || m_Image->GetDimension() > 4) ||
00073 m_SliceDifferenceImage->GetDimension(0) != m_Image->GetDimension(m_Dimension0) ||
00074 m_SliceDifferenceImage->GetDimension(1) != m_Image->GetDimension(m_Dimension1) ||
00075 m_SliceIndex >= m_Image->GetDimension(m_SliceDimension)
00076 )
00077 {
00078 itkExceptionMacro("Slice and image dimensions differ or slice index is too large. Sorry, cannot work like this.");
00079 return;
00080 }
00081
00082 if ( m_Image->GetDimension() == 4 )
00083 {
00084 ImageTimeSelector::Pointer timeSelector = ImageTimeSelector::New();
00085 timeSelector->SetInput( m_Image );
00086 timeSelector->SetTimeNr( m_TimeStep );
00087 timeSelector->UpdateLargestPossibleRegion();
00088 image3D = timeSelector->GetOutput();
00089 }
00090
00091
00092 AccessFixedDimensionByItk( image3D, ItkImageSwitch2DDiff, 3 );
00093
00094 if ( m_Factor == 1 || m_Factor == -1 )
00095 {
00096 if ( m_Factor == -1 )
00097 {
00098
00099 AccessFixedDimensionByItk( m_SliceDifferenceImage, ItkInvertPixelValues, 2 );
00100 }
00101
00102
00103 SegmentationInterpolationController* interpolator = SegmentationInterpolationController::InterpolatorForImage( m_Image );
00104 if (interpolator)
00105 {
00106 interpolator->BlockModified(true);
00107 interpolator->SetChangedSlice( m_SliceDifferenceImage, m_SliceDimension, m_SliceIndex, m_TimeStep );
00108 }
00109
00110 m_Image->Modified();
00111
00112 if (interpolator)
00113 {
00114 interpolator->BlockModified(false);
00115 }
00116
00117 if ( m_Factor == -1 )
00118 {
00119 AccessFixedDimensionByItk( m_SliceDifferenceImage, ItkInvertPixelValues, 2 );
00120 }
00121 }
00122 else
00123 {
00124 m_Image->Modified();
00125 }
00126
00127 RenderingManager::GetInstance()->RequestUpdateAll();
00128 }
00129 else if ( m_SliceDifferenceImage->GetDimension() == 3 )
00130 {
00131
00132 if ( m_SliceDifferenceImage->GetDimension(0) != m_Image->GetDimension(0) ||
00133 m_SliceDifferenceImage->GetDimension(1) != m_Image->GetDimension(1) ||
00134 m_SliceDifferenceImage->GetDimension(2) != m_Image->GetDimension(2) ||
00135 m_TimeStep >= m_Image->GetDimension(3)
00136 )
00137 {
00138 itkExceptionMacro("Diff image size differs from original image size. Sorry, cannot work like this.");
00139 return;
00140 }
00141
00142 if ( m_Image->GetDimension() == 4 )
00143 {
00144 ImageTimeSelector::Pointer timeSelector = ImageTimeSelector::New();
00145 timeSelector->SetInput( m_Image );
00146 timeSelector->SetTimeNr( m_TimeStep );
00147 timeSelector->UpdateLargestPossibleRegion();
00148 image3D = timeSelector->GetOutput();
00149 }
00150
00151
00152 AccessFixedDimensionByItk( image3D, ItkImageSwitch3DDiff, 3 );
00153
00154 if ( m_Factor == 1 || m_Factor == -1 )
00155 {
00156 if ( m_Factor == -1 )
00157 {
00158
00159 AccessFixedDimensionByItk( m_SliceDifferenceImage, ItkInvertPixelValues, 3 );
00160 }
00161
00162
00163 SegmentationInterpolationController* interpolator = SegmentationInterpolationController::InterpolatorForImage( m_Image );
00164 if (interpolator)
00165 {
00166 interpolator->BlockModified(true);
00167 interpolator->SetChangedVolume( m_SliceDifferenceImage, m_TimeStep );
00168 }
00169
00170 m_Image->Modified();
00171
00172 if (interpolator)
00173 {
00174 interpolator->BlockModified(false);
00175 }
00176
00177 if ( m_Factor == -1 )
00178 {
00179 AccessFixedDimensionByItk( m_SliceDifferenceImage, ItkInvertPixelValues, 3 );
00180 }
00181 }
00182 else
00183 {
00184 m_Image->Modified();
00185 }
00186
00187 RenderingManager::GetInstance()->RequestUpdateAll();
00188 }
00189 else
00190 {
00191 itkExceptionMacro("Diff image must be 2D or 3D. Sorry, cannot work like this.");
00192 return;
00193 }
00194 }
00195
00196 m_Image = NULL;
00197 m_SliceDifferenceImage = NULL;
00198 }
00199
00200 mitk::DiffImageApplier* mitk::DiffImageApplier::GetInstanceForUndo()
00201 {
00202 static DiffImageApplier::Pointer s_Instance = DiffImageApplier::New();
00203
00204 return s_Instance;
00205 }
00206
00207
00208 #define myMITKDiffImageApplierFilterAccessByItk(mitkImage, itkImageTypeFunction, pixeltype, dimension, itkimage2) \
00209 if ( typeId == typeid(pixeltype) ) \
00210 { \
00211 typedef itk::Image<pixeltype, dimension> ImageType; \
00212 typedef mitk::ImageToItk<ImageType> ImageToItkType; \
00213 itk::SmartPointer<ImageToItkType> imagetoitk = ImageToItkType::New(); \
00214 imagetoitk->SetInput(mitkImage); \
00215 imagetoitk->Update(); \
00216 itkImageTypeFunction(imagetoitk->GetOutput(), itkimage2); \
00217 }
00218
00219
00220 #define myMITKDiffImageApplierFilterAccessAllTypesByItk(mitkImage, itkImageTypeFunction, dimension, itkimage2) \
00221 { \
00222 myMITKDiffImageApplierFilterAccessByItk(mitkImage, itkImageTypeFunction, double, dimension, itkimage2) else \
00223 myMITKDiffImageApplierFilterAccessByItk(mitkImage, itkImageTypeFunction, float, dimension, itkimage2) else \
00224 myMITKDiffImageApplierFilterAccessByItk(mitkImage, itkImageTypeFunction, int, dimension, itkimage2) else \
00225 myMITKDiffImageApplierFilterAccessByItk(mitkImage, itkImageTypeFunction, unsigned int, dimension, itkimage2) else \
00226 myMITKDiffImageApplierFilterAccessByItk(mitkImage, itkImageTypeFunction, short, dimension, itkimage2) else \
00227 myMITKDiffImageApplierFilterAccessByItk(mitkImage, itkImageTypeFunction, unsigned short, dimension, itkimage2) else \
00228 myMITKDiffImageApplierFilterAccessByItk(mitkImage, itkImageTypeFunction, char, dimension, itkimage2) else \
00229 myMITKDiffImageApplierFilterAccessByItk(mitkImage, itkImageTypeFunction, unsigned char, dimension, itkimage2) \
00230 }
00231
00232 template<typename TPixel, unsigned int VImageDimension>
00233 void mitk::DiffImageApplier::ItkImageSwitch2DDiff( itk::Image<TPixel,VImageDimension>* itkImage )
00234 {
00235 const std::type_info& typeId=*(m_SliceDifferenceImage->GetPixelType().GetTypeId());
00236
00237 myMITKDiffImageApplierFilterAccessAllTypesByItk( m_SliceDifferenceImage, ItkImageProcessing2DDiff, 2, itkImage );
00238 }
00239
00240
00241 template<typename TPixel, unsigned int VImageDimension>
00242 void mitk::DiffImageApplier::ItkImageSwitch3DDiff( itk::Image<TPixel,VImageDimension>* itkImage )
00243 {
00244 const std::type_info& typeId=*(m_SliceDifferenceImage->GetPixelType().GetTypeId());
00245
00246 myMITKDiffImageApplierFilterAccessAllTypesByItk( m_SliceDifferenceImage, ItkImageProcessing3DDiff, 3, itkImage );
00247 }
00248
00249 template<typename TPixel1, unsigned int VImageDimension1, typename TPixel2, unsigned int VImageDimension2>
00250 void mitk::DiffImageApplier::ItkImageProcessing2DDiff( itk::Image<TPixel1,VImageDimension1>* diffImage, itk::Image<TPixel2,VImageDimension2>* outputImage )
00251 {
00252 typedef itk::Image<TPixel1, VImageDimension1> DiffImageType;
00253 typedef itk::Image<TPixel2, VImageDimension2> VolumeImageType;
00254
00255 typedef itk::ImageSliceIteratorWithIndex< VolumeImageType > OutputSliceIteratorType;
00256 typedef itk::ImageRegionConstIterator< DiffImageType > DiffSliceIteratorType;
00257
00258 typename VolumeImageType::RegionType sliceInVolumeRegion;
00259
00260 sliceInVolumeRegion = outputImage->GetLargestPossibleRegion();
00261 sliceInVolumeRegion.SetSize( m_SliceDimension, 1 );
00262 sliceInVolumeRegion.SetIndex( m_SliceDimension, m_SliceIndex );
00263
00264 OutputSliceIteratorType outputIterator( outputImage, sliceInVolumeRegion );
00265 outputIterator.SetFirstDirection(m_Dimension0);
00266 outputIterator.SetSecondDirection(m_Dimension1);
00267
00268 DiffSliceIteratorType diffIterator( diffImage, diffImage->GetLargestPossibleRegion() );
00269
00270
00271 outputIterator.GoToBegin();
00272 diffIterator.GoToBegin();
00273 while ( !outputIterator.IsAtEnd() )
00274 {
00275 while ( !outputIterator.IsAtEndOfSlice() )
00276 {
00277 while ( !outputIterator.IsAtEndOfLine() )
00278 {
00279 TPixel2 newValue = outputIterator.Get() + (TPixel2) ((double)diffIterator.Get() * m_Factor);
00280 outputIterator.Set( newValue );
00281 ++outputIterator;
00282 ++diffIterator;
00283 }
00284 outputIterator.NextLine();
00285 }
00286 outputIterator.NextSlice();
00287 }
00288 }
00289
00290
00291 template<typename TPixel1, unsigned int VImageDimension1, typename TPixel2, unsigned int VImageDimension2>
00292 void mitk::DiffImageApplier::ItkImageProcessing3DDiff( itk::Image<TPixel1,VImageDimension1>* diffImage, itk::Image<TPixel2,VImageDimension2>* outputImage )
00293 {
00294 typedef itk::Image<TPixel1, VImageDimension1> DiffImageType;
00295 typedef itk::Image<TPixel2, VImageDimension2> VolumeImageType;
00296
00297 typedef itk::ImageRegionIterator< VolumeImageType > OutputSliceIteratorType;
00298 typedef itk::ImageRegionConstIterator< DiffImageType > DiffSliceIteratorType;
00299
00300 OutputSliceIteratorType outputIterator( outputImage, outputImage->GetLargestPossibleRegion() );
00301 DiffSliceIteratorType diffIterator( diffImage, diffImage->GetLargestPossibleRegion() );
00302
00303
00304 outputIterator.GoToBegin();
00305 diffIterator.GoToBegin();
00306 while ( !outputIterator.IsAtEnd() )
00307 {
00308 TPixel2 newValue = outputIterator.Get() + (TPixel2) ((double)diffIterator.Get() * m_Factor);
00309 outputIterator.Set( newValue );
00310 ++outputIterator;
00311 ++diffIterator;
00312 }
00313 }
00314
00315 template<typename TPixel, unsigned int VImageDimension>
00316 void mitk::DiffImageApplier::ItkInvertPixelValues( itk::Image<TPixel,VImageDimension>* itkImage )
00317 {
00318 typedef itk::ImageRegionIterator< itk::Image<TPixel,VImageDimension> > IteratorType;
00319 IteratorType iter( itkImage, itkImage->GetLargestPossibleRegion() );
00320
00321 iter.GoToBegin();
00322 while ( !iter.IsAtEnd() )
00323 {
00324 iter.Set( -( iter.Get() ) );
00325 ++iter;
00326 }
00327 }
00328