1 #include <QApplication>
3 #include <itkWarpImageFilter.h>
4 #include <itkVectorResampleImageFilter.h>
6 #include "vvMidPosition.h"
7 #include "clitkCommon.h"
10 #include "clitkInvertVFFilter.h"
12 vvMidPosition::vvMidPosition() :
13 slicer_manager(0), error(false),
14 reference_image_index(0),
15 p_bar("Computing mid-position...","Cancel", 0,6),
20 void vvMidPosition::Update()
23 while (this->isRunning())
26 this->update_progress();
27 qApp->processEvents();
32 typedef itk::Vector<float,3> VFPixelType;
33 typedef itk::Image<VFPixelType,4> VFType;
34 typedef itk::Image<VFPixelType,3> OutputVFType;
38 ///This function averages a vector field along the temporal dimension
39 // the progress parameter is a reference to a counter used to update the progress dialog
40 itk::Image<itk::Vector<float,3>,3>::Pointer AverageField(itk::Image<itk::Vector<float,3>,4>::ConstPointer vf,int &progress);
41 ///Warps an image frame using the vf passed in parameter
42 template<class ImagePixelType> vvImage::Pointer WarpRefImage(OutputVFType::Pointer vf,vvImage::Pointer image,int reference_image_index);
44 void vvMidPosition::run()
47 if(slicer_manager->GetImage()->GetNumberOfDimensions() != 4)
48 error_message="Computation of midposition is only supported for 4D image sequences.";
49 else if (!slicer_manager->GetVF())
50 error_message="A VF is required for midposition computation";
51 else if (slicer_manager->GetVF()->GetScalarTypeAsString() != "float")
52 error_message="Please use a vector field of type float.";
55 VFType::ConstPointer vf = vvImageToITK<VFType>(slicer_manager->GetVF());
56 OutputVFType::Pointer avg_vf=AverageField(vf,this->progress);
57 clitk::InvertVFFilter<OutputVFType,OutputVFType>::Pointer inv_filter=
58 clitk::InvertVFFilter<OutputVFType,OutputVFType>::New();
59 inv_filter->SetInput(avg_vf);
62 if (slicer_manager->GetImage()->GetScalarTypeAsString() == "short")
63 this->output=WarpRefImage<short>(inv_filter->GetOutput(),slicer_manager->GetImage(),reference_image_index);
66 error_message="Unsupported image pixel type.";
74 template<class ImagePixelType>
75 vvImage::Pointer WarpRefImage(OutputVFType::Pointer vf,vvImage::Pointer image,int reference_image_index)
77 typedef itk::Image<ImagePixelType,3> ImageType;
78 typedef itk::WarpImageFilter<ImageType,ImageType,itk::Image<VFPixelType,3> > FilterType;
80 typename ImageType::ConstPointer input = vvSingleFrameToITK<3,ImagePixelType>(image,reference_image_index);
82 //We resample the VF because itk's warp filter doesn't like it when the vf and the image have
84 typename itk::VectorResampleImageFilter<OutputVFType, OutputVFType >::Pointer
85 resampler =itk::VectorResampleImageFilter<OutputVFType, OutputVFType >::New();
86 resampler->SetInput(vf);
87 resampler->SetOutputSpacing(input->GetSpacing());
88 resampler->SetOutputOrigin(vf->GetOrigin());
89 //Calculate the new size so that it contains the vf
90 typename ImageType::SizeType newSize;
91 for (unsigned int i=0 ; i <3; i++)
92 newSize[i]=(unsigned int) (vf->GetLargestPossibleRegion().GetSize()[i]*vf->GetSpacing()[i]/input->GetSpacing()[i]);
93 resampler->SetSize( newSize);
95 typename FilterType::Pointer warp_filter = FilterType::New();
96 warp_filter->SetInput(input);
97 warp_filter->SetDeformationField(resampler->GetOutput());
98 warp_filter->SetOutputSpacing(input->GetSpacing());
99 warp_filter->SetOutputOrigin(input->GetOrigin());
100 warp_filter->SetOutputSize(input->GetLargestPossibleRegion().GetSize());
101 warp_filter->SetEdgePaddingValue(-1000);
102 warp_filter->Update();
103 return vvImageFromITK<3,ImagePixelType>(warp_filter->GetOutput());
106 itk::Image<itk::Vector<float,3>,3>::Pointer AverageField(itk::Image<itk::Vector<float,3>,4>::ConstPointer vf, int& progress)
110 VFType::RegionType region4D=vf->GetLargestPossibleRegion();
111 VFType::RegionType::SizeType size4D=region4D.GetSize();
112 VFType::IndexType index4D=region4D.GetIndex();
113 VFType::SpacingType spacing4D=vf->GetSpacing();
114 VFType::PointType origin4D=vf->GetOrigin();
116 OutputVFType::RegionType region;
117 OutputVFType::RegionType::SizeType size;
118 OutputVFType::IndexType index;
119 OutputVFType::SpacingType spacing;
120 OutputVFType::PointType origin;
121 for (unsigned int i=0; i< 3; i++)
125 spacing[i]=spacing4D[i];
126 origin[i]=origin4D[i];
128 region.SetSize(size);
129 region.SetIndex(index);
130 OutputVFType::Pointer output= OutputVFType::New();
131 output->SetRegions(region);
132 output->SetSpacing(spacing);
133 output->SetOrigin(origin);
139 typedef itk::ImageRegionConstIterator<VFType> IteratorType;
140 std::vector<IteratorType> iterators(size4D[3]);
141 for (unsigned int i=0; i< size4D[3]; i++)
143 VFType::RegionType regionIt=region4D;
144 VFType::RegionType::SizeType sizeIt=regionIt.GetSize();
146 regionIt.SetSize(sizeIt);
147 VFType::IndexType indexIt=regionIt.GetIndex();
149 regionIt.SetIndex(indexIt);
150 iterators[i]=IteratorType(vf, regionIt);
154 typedef itk::ImageRegionIterator<OutputVFType> OutputIteratorType;
155 OutputIteratorType avIt(output, output->GetLargestPossibleRegion());
159 VFPixelType zeroVector=itk::NumericTraits<VFPixelType>::Zero;
161 while (!(iterators[0]).IsAtEnd())
164 for (unsigned int i=0; i<size4D[3]; i++)
166 vector+=iterators[i].Get();
178 void vvMidPosition::update_progress()
180 p_bar.setValue(progress);