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