]> Creatis software - clitk.git/blob - itk/clitkCropLikeImageFilter.txx
Merge commit '488f24aa984ae24adc9458bf5fbf3b2351415742'
[clitk.git] / itk / clitkCropLikeImageFilter.txx
1 /*=========================================================================
2   Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
3
4   Authors belong to: 
5   - University of LYON              http://www.universite-lyon.fr/
6   - Léon Bérard cancer center       http://www.centreleonberard.fr
7   - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
8
9   This software is distributed WITHOUT ANY WARRANTY; without even
10   the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11   PURPOSE.  See the copyright notices for more information.
12
13   It is distributed under dual licence
14
15   - BSD        See included LICENSE.txt file
16   - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
17   ===========================================================================**/
18
19 #ifndef CLITKCROPLIKEIMAGEFILTER_TXX
20 #define CLITKCROPLIKEIMAGEFILTER_TXX
21
22 // clitk
23 #include "clitkCommon.h"
24
25 // itk
26 #include "itkPasteImageFilter.h"
27
28 //--------------------------------------------------------------------
29 template <class ImageType>
30 clitk::CropLikeImageFilter<ImageType>::
31 CropLikeImageFilter():itk::ImageToImageFilter<ImageType, ImageType>() {
32   this->SetNumberOfRequiredInputs(1);
33   m_LikeImage = NULL;
34   m_LikeFilenameIsGiven = false;
35   this->SetBackgroundValue(0);
36   m_CropAlongThisDimension.resize(ImageType::ImageDimension);
37   for(uint i=0; i<ImageType::ImageDimension; i++)
38     m_CropAlongThisDimension[i] = true;
39 }
40 //--------------------------------------------------------------------
41
42
43 //--------------------------------------------------------------------
44 template <class ImageType>
45 void 
46 clitk::CropLikeImageFilter<ImageType>::
47 SetCropLikeFilename(std::string f) 
48 {
49   m_LikeFilename = f;
50   m_LikeFilenameIsGiven = true;
51 }
52 //--------------------------------------------------------------------
53   
54
55 //--------------------------------------------------------------------
56 template <class ImageType>
57 void 
58 clitk::CropLikeImageFilter<ImageType>::
59 SetCropLikeImage(const itk::ImageBase<ImageType::ImageDimension> * like)
60 {
61   m_LikeImage = like;
62 }
63 //--------------------------------------------------------------------
64   
65
66 //--------------------------------------------------------------------
67 template <class ImageType>
68 void 
69 clitk::CropLikeImageFilter<ImageType>::
70 SetCropLikeImage(const itk::ImageBase<ImageType::ImageDimension> * like, int axe)
71 {
72   m_LikeImage = like;
73   for(uint i=0; i<ImageType::ImageDimension; i++)
74     m_CropAlongThisDimension[i] = false;
75   m_CropAlongThisDimension[axe] = true;
76 }
77 //--------------------------------------------------------------------
78   
79
80 //--------------------------------------------------------------------
81 template <class ImageType>
82 void 
83 clitk::CropLikeImageFilter<ImageType>::
84 GenerateInputRequestedRegion() {
85   // Needed because output region can be larger than input
86   ImagePointer input = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
87   input->SetRequestedRegion(input->GetLargestPossibleRegion());
88 }
89 //--------------------------------------------------------------------
90
91
92 //--------------------------------------------------------------------
93 template <class ImageType>
94 void 
95 clitk::CropLikeImageFilter<ImageType>::
96 GenerateOutputInformation() {   
97   // Get input pointers
98   ImageConstPointer input = dynamic_cast<const ImageType*>(itk::ProcessObject::GetInput(0));
99     
100   // Get output pointer
101   ImagePointer output = this->GetOutput(0);
102
103   // Get input info
104   typename ImageType::SizeType likeSize;
105   typename ImageType::IndexType likeStart;
106   typename ImageType::PointType likeOrigin;  
107   typename ImageType::SpacingType likeSpacing;  
108   if (m_LikeImage) {   
109     likeSize = m_LikeImage->GetLargestPossibleRegion().GetSize();
110     likeStart = m_LikeImage->GetLargestPossibleRegion().GetIndex();
111     likeOrigin = m_LikeImage->GetOrigin();
112     likeSpacing = m_LikeImage->GetSpacing();
113     output->CopyInformation(m_LikeImage);
114   }
115   else {
116     // Only load the header (allows to use 'like' with any image type)
117     if (m_LikeFilenameIsGiven) {
118       itk::ImageIOBase::Pointer header = readImageHeader(m_LikeFilename);
119       for(unsigned int i=0; i<ImageType::ImageDimension; i++) {
120         likeSize[i] = header->GetDimensions(i);
121         likeStart[i] = 0;//header->GetIORegion().GetIndex()[i];
122         likeOrigin[i] = header->GetOrigin(i);
123         likeSpacing[i] = header->GetSpacing(i);
124       }
125     }
126     else {
127       clitkExceptionMacro("You should provide SetCropLikeFilename or SetCropLike to CropLikeImageFilter");
128     }
129   }
130
131   // Check spacing
132   for(unsigned int i=0; i<ImageType::ImageDimension; i++) {
133     if (likeSpacing[i] != input->GetSpacing()[i]) {
134       clitkExceptionMacro("Images must have the same spacing, but input's spacing(" << i
135                           <<") is " << input->GetSpacing()[i] << " while the spacing(" << i 
136                           << ") of 'like' is " << likeSpacing[i] << ".");
137     }
138   }
139
140   // Check that we must crop along each dimension. If not, we use the
141   // size of the input image
142   for(unsigned int i=0; i<ImageType::ImageDimension; i++) {
143     if (m_CropAlongThisDimension[i] == false) {
144       likeStart[i] = input->GetLargestPossibleRegion().GetIndex()[i];
145       likeSize[i] = input->GetLargestPossibleRegion().GetSize()[i];
146     }
147   }
148
149   // Define output region 
150   m_OutputRegion.SetIndex(likeStart);
151   m_OutputRegion.SetSize(likeSize);
152   output->SetRegions(m_OutputRegion);
153   output->SetRequestedRegion(m_OutputRegion);
154   output->SetBufferedRegion(m_OutputRegion);
155   output->SetSpacing(likeSpacing);  
156   output->SetOrigin(likeOrigin);
157   output->Allocate(); // Needed ?
158
159   // get startpoint source/dest
160   // for each dim
161   // if source < dest -> start from dest, compute in source
162   // if source > dest -> start from source, compute in dest
163   m_StartDestIndex = output->GetLargestPossibleRegion().GetIndex();
164   m_StartSourceIndex = input->GetLargestPossibleRegion().GetIndex();
165   PointType m_StartPointInSource;
166   PointType m_StartPointInDest;
167   m_StartSourceIndex = input->GetLargestPossibleRegion().GetIndex();
168   input->TransformIndexToPhysicalPoint(m_StartSourceIndex, m_StartPointInSource);
169   m_StartDestIndex = output->GetLargestPossibleRegion().GetIndex();
170   output->TransformIndexToPhysicalPoint(m_StartDestIndex, m_StartPointInDest);
171   IndexType startDestInSource;
172   IndexType startSourceInDest;
173   input->TransformPhysicalPointToIndex(m_StartPointInDest, startDestInSource);
174   output->TransformPhysicalPointToIndex(m_StartPointInSource, startSourceInDest);
175   for(int i=0; i<ImageType::ImageDimension; i++) {
176     if (m_StartPointInSource[i] < m_StartPointInDest[i]) {
177       m_StartSourceIndex[i] = startDestInSource[i];
178     }
179     else {
180       m_StartDestIndex[i] = startSourceInDest[i];
181     }
182   }
183   m_Region.SetIndex(m_StartSourceIndex);
184
185   // Stop index
186   m_StopSourceIndex = input->GetLargestPossibleRegion().GetIndex()+
187     input->GetLargestPossibleRegion().GetSize();
188   m_StopDestIndex = output->GetLargestPossibleRegion().GetIndex()+
189     output->GetLargestPossibleRegion().GetSize();
190   PointType m_StopPointInSource;
191   PointType m_StopPointInDest;
192   input->TransformIndexToPhysicalPoint(m_StopSourceIndex, m_StopPointInSource);
193   output->TransformIndexToPhysicalPoint(m_StopDestIndex, m_StopPointInDest);
194   IndexType stopDestInSource;
195   IndexType stopSourceInDest;
196   input->TransformPhysicalPointToIndex(m_StopPointInDest, stopDestInSource);
197   output->TransformPhysicalPointToIndex(m_StopPointInSource, stopSourceInDest);
198
199   for(int i=0; i<ImageType::ImageDimension; i++) {
200     if (m_StopPointInSource[i] > m_StopPointInDest[i]) {
201       m_StopSourceIndex[i] = stopDestInSource[i];
202     }
203     else {
204       m_StopDestIndex[i] = stopSourceInDest[i];
205     }
206   }
207
208   // Set size to the region we want to paste
209   SizeType s;
210   for(int i=0; i<ImageType::ImageDimension; i++)
211     s[i] = m_StopSourceIndex[i]-m_StartSourceIndex[i];
212   m_Region.SetSize(s);
213
214 }
215 //--------------------------------------------------------------------
216    
217 //--------------------------------------------------------------------
218 template <class ImageType>
219 void 
220 clitk::CropLikeImageFilter<ImageType>::
221 GenerateData() {
222   // Get input pointers
223   ImageConstPointer input = dynamic_cast<const ImageType*>(itk::ProcessObject::GetInput(0));
224
225   // Get output pointer, fill with Background
226   ImagePointer output = this->GetOutput(0);
227   
228   output->FillBuffer(GetBackgroundValue());
229   
230   // Paste image inside
231   typedef itk::PasteImageFilter<ImageType,ImageType> PasteFilterType;
232   typename PasteFilterType::Pointer pasteFilter = PasteFilterType::New();
233   //pasteFilter->ReleaseDataFlagOn(); // change nothing ?
234   //  pasteFilter->InPlaceOn(); // makt it seg fault
235   pasteFilter->SetSourceImage(input);
236   pasteFilter->SetDestinationImage(output);
237   pasteFilter->SetDestinationIndex(m_StartDestIndex);
238   pasteFilter->SetSourceRegion(m_Region);
239   pasteFilter->Update();
240
241   // Get (graft) output (SetNthOutput does not fit here because of Origin).
242   this->GraftOutput(pasteFilter->GetOutput());
243 }
244 //--------------------------------------------------------------------
245    
246  
247 #endif //#define CLITKAUTOCROPFILTER