00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "mitkOverwriteSliceImageFilter.h"
00019 #include "mitkImageCast.h"
00020 #include "mitkSegmentationInterpolationController.h"
00021 #include "mitkApplyDiffImageOperation.h"
00022 #include "mitkOperationEvent.h"
00023 #include "mitkInteractionConst.h"
00024 #include "mitkUndoController.h"
00025 #include "mitkDiffImageApplier.h"
00026 #include "mitkImageTimeSelector.h"
00027
00028 #include <itkImageSliceIteratorWithIndex.h>
00029 #include <itkImageRegionIterator.h>
00030
00031 mitk::OverwriteSliceImageFilter::OverwriteSliceImageFilter()
00032 :m_SliceIndex(0),
00033 m_SliceDimension(0),
00034 m_TimeStep(0),
00035 m_Dimension0(0),
00036 m_Dimension1(1),
00037 m_CreateUndoInformation(false)
00038 {
00039 }
00040
00041 mitk::OverwriteSliceImageFilter::~OverwriteSliceImageFilter()
00042 {
00043 }
00044
00045 void mitk::OverwriteSliceImageFilter::GenerateData()
00046 {
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 Image::ConstPointer input = ImageToImageFilter::GetInput(0);
00060 Image::ConstPointer input3D = input;
00061
00062 Image::ConstPointer slice = m_SliceImage;
00063
00064 if ( input.IsNull() || slice.IsNull() ) return;
00065
00066 switch (m_SliceDimension)
00067 {
00068 default:
00069 case 2:
00070 m_Dimension0 = 0;
00071 m_Dimension1 = 1;
00072 break;
00073 case 1:
00074 m_Dimension0 = 0;
00075 m_Dimension1 = 2;
00076 break;
00077 case 0:
00078 m_Dimension0 = 1;
00079 m_Dimension1 = 2;
00080 break;
00081 }
00082
00083 if ( slice->GetDimension() < 2 || input->GetDimension() > 4 ||
00084 slice->GetDimension(0) != input->GetDimension(m_Dimension0) ||
00085 slice->GetDimension(1) != input->GetDimension(m_Dimension1) ||
00086 m_SliceIndex >= input->GetDimension(m_SliceDimension)
00087 )
00088 {
00089 itkExceptionMacro("Slice and image dimensions differ or slice index is too large. Sorry, cannot work like this.");
00090 return;
00091 }
00092
00093 if ( input->GetDimension() == 4 )
00094 {
00095 ImageTimeSelector::Pointer timeSelector = ImageTimeSelector::New();
00096 timeSelector->SetInput( input );
00097 timeSelector->SetTimeNr( m_TimeStep );
00098 timeSelector->UpdateLargestPossibleRegion();
00099 input3D = timeSelector->GetOutput();
00100 }
00101
00102 if ( m_SliceDifferenceImage.IsNull() ||
00103 m_SliceDifferenceImage->GetDimension(0) != m_SliceImage->GetDimension(0) ||
00104 m_SliceDifferenceImage->GetDimension(1) != m_SliceImage->GetDimension(1) )
00105 {
00106 m_SliceDifferenceImage = mitk::Image::New();
00107 mitk::PixelType pixelType( typeid(short signed int) );
00108 m_SliceDifferenceImage->Initialize( pixelType, 2, m_SliceImage->GetDimensions() );
00109 }
00110
00111
00112
00113 AccessFixedDimensionByItk( input3D, ItkImageSwitch, 3 );
00114
00115 SegmentationInterpolationController* interpolator = SegmentationInterpolationController::InterpolatorForImage( input );
00116 if (interpolator)
00117 {
00118 interpolator->BlockModified(true);
00119 interpolator->SetChangedSlice( m_SliceDifferenceImage, m_SliceDimension, m_SliceIndex, m_TimeStep );
00120 }
00121
00122 if ( m_CreateUndoInformation )
00123 {
00124
00125 ApplyDiffImageOperation* doOp = new ApplyDiffImageOperation( OpTEST, const_cast<Image*>(input.GetPointer()), m_SliceDifferenceImage, m_TimeStep, m_SliceDimension, m_SliceIndex );
00126 ApplyDiffImageOperation* undoOp = new ApplyDiffImageOperation( OpTEST, const_cast<Image*>(input.GetPointer()), m_SliceDifferenceImage, m_TimeStep, m_SliceDimension, m_SliceIndex );
00127 undoOp->SetFactor( -1.0 );
00128 OperationEvent* undoStackItem = new OperationEvent( DiffImageApplier::GetInstanceForUndo(), doOp, undoOp, this->EventDescription(m_SliceDimension, m_SliceIndex, m_TimeStep) );
00129 UndoController::GetCurrentUndoModel()->SetOperationEvent( undoStackItem );
00130 }
00131
00132
00133 input->Modified();
00134
00135 if (interpolator)
00136 {
00137 interpolator->BlockModified(false);
00138 }
00139 }
00140
00141
00142 #define myMITKOverwriteSliceImageFilterAccessByItk(mitkImage, itkImageTypeFunction, pixeltype, dimension, itkimage2) \
00143 if ( typeId == typeid(pixeltype) ) \
00144 { \
00145 typedef itk::Image<pixeltype, dimension> ImageType; \
00146 typedef mitk::ImageToItk<ImageType> ImageToItkType; \
00147 itk::SmartPointer<ImageToItkType> imagetoitk = ImageToItkType::New(); \
00148 imagetoitk->SetInput(mitkImage); \
00149 imagetoitk->Update(); \
00150 itkImageTypeFunction(imagetoitk->GetOutput(), itkimage2); \
00151 }
00152
00153 #define myMITKOverwriteSliceImageFilterAccessAllTypesByItk(mitkImage, itkImageTypeFunction, dimension, itkimage2) \
00154 { \
00155 myMITKOverwriteSliceImageFilterAccessByItk(mitkImage, itkImageTypeFunction, double, dimension, itkimage2) else \
00156 myMITKOverwriteSliceImageFilterAccessByItk(mitkImage, itkImageTypeFunction, float, dimension, itkimage2) else \
00157 myMITKOverwriteSliceImageFilterAccessByItk(mitkImage, itkImageTypeFunction, int, dimension, itkimage2) else \
00158 myMITKOverwriteSliceImageFilterAccessByItk(mitkImage, itkImageTypeFunction, unsigned int, dimension, itkimage2) else \
00159 myMITKOverwriteSliceImageFilterAccessByItk(mitkImage, itkImageTypeFunction, short, dimension, itkimage2) else \
00160 myMITKOverwriteSliceImageFilterAccessByItk(mitkImage, itkImageTypeFunction, unsigned short, dimension, itkimage2) else \
00161 myMITKOverwriteSliceImageFilterAccessByItk(mitkImage, itkImageTypeFunction, char, dimension, itkimage2) else \
00162 myMITKOverwriteSliceImageFilterAccessByItk(mitkImage, itkImageTypeFunction, unsigned char, dimension, itkimage2) \
00163 }
00164
00165
00166 template<typename TPixel, unsigned int VImageDimension>
00167 void mitk::OverwriteSliceImageFilter::ItkImageSwitch( itk::Image<TPixel,VImageDimension>* itkImage )
00168 {
00169 const std::type_info& typeId=*(m_SliceImage->GetPixelType().GetTypeId());
00170
00171 myMITKOverwriteSliceImageFilterAccessAllTypesByItk( m_SliceImage, ItkImageProcessing, 2, itkImage );
00172 }
00173
00174 template<typename TPixel1, unsigned int VImageDimension1, typename TPixel2, unsigned int VImageDimension2>
00175 void mitk::OverwriteSliceImageFilter::ItkImageProcessing( itk::Image<TPixel1,VImageDimension1>* inputImage, itk::Image<TPixel2,VImageDimension2>* outputImage )
00176 {
00177 typedef itk::Image<TPixel1, VImageDimension1> SliceImageType;
00178 typedef itk::Image<short signed int, VImageDimension1> DiffImageType;
00179 typedef itk::Image<TPixel2, VImageDimension2> VolumeImageType;
00180
00181 typedef itk::ImageSliceIteratorWithIndex< VolumeImageType > OutputSliceIteratorType;
00182 typedef itk::ImageRegionConstIterator< SliceImageType > InputSliceIteratorType;
00183 typedef itk::ImageRegionIterator< DiffImageType > DiffSliceIteratorType;
00184
00185 typename VolumeImageType::RegionType sliceInVolumeRegion;
00186
00187 sliceInVolumeRegion = outputImage->GetLargestPossibleRegion();
00188 sliceInVolumeRegion.SetSize( m_SliceDimension, 1 );
00189 sliceInVolumeRegion.SetIndex( m_SliceDimension, m_SliceIndex );
00190
00191 OutputSliceIteratorType outputIterator( outputImage, sliceInVolumeRegion );
00192 outputIterator.SetFirstDirection(m_Dimension0);
00193 outputIterator.SetSecondDirection(m_Dimension1);
00194
00195 InputSliceIteratorType inputIterator( inputImage, inputImage->GetLargestPossibleRegion() );
00196
00197 typename DiffImageType::Pointer diffImage;
00198 CastToItkImage( m_SliceDifferenceImage, diffImage );
00199 DiffSliceIteratorType diffIterator( diffImage, diffImage->GetLargestPossibleRegion() );
00200
00201
00202 outputIterator.GoToBegin();
00203 inputIterator.GoToBegin();
00204 diffIterator.GoToBegin();
00205 while ( !outputIterator.IsAtEnd() )
00206 {
00207 while ( !outputIterator.IsAtEndOfSlice() )
00208 {
00209 while ( !outputIterator.IsAtEndOfLine() )
00210 {
00211 diffIterator.Set( static_cast<short signed int>(inputIterator.Get() - outputIterator.Get()) );
00212 outputIterator.Set( (TPixel2) inputIterator.Get() );
00213 ++outputIterator;
00214 ++inputIterator;
00215 ++diffIterator;
00216 }
00217 outputIterator.NextLine();
00218 }
00219 outputIterator.NextSlice();
00220 }
00221 }
00222
00223 std::string mitk::OverwriteSliceImageFilter::EventDescription( unsigned int sliceDimension, unsigned int sliceIndex, unsigned int timeStep )
00224 {
00225 std::stringstream s;
00226
00227 s << "Changed slice (";
00228
00229 switch (sliceDimension)
00230 {
00231 default:
00232 case 2:
00233 s << "T";
00234 break;
00235 case 1:
00236 s << "C";
00237 break;
00238 case 0:
00239 s << "S";
00240 break;
00241 }
00242
00243 s << " " << sliceIndex << " " << timeStep << ")";
00244
00245 return s.str();
00246 }