]> Creatis software - clitk.git/blob - itk/clitkCropLikeImageFilter.txx
Set Directions to CropImage Like
[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 //--------------------------------------------------------------------
27 template <class ImageType>
28 clitk::CropLikeImageFilter<ImageType>::
29 CropLikeImageFilter():itk::ImageToImageFilter<ImageType, ImageType>() {
30   this->SetNumberOfRequiredInputs(1);
31   m_LikeImage = NULL;
32   m_LikeFilenameIsGiven = false;
33   this->SetBackgroundValue(typename PixelTraits<typename ImageType::PixelType>::ValueType(0));
34   m_CropAlongThisDimension.resize(ImageType::ImageDimension);
35   for(uint i=0; i<ImageType::ImageDimension; i++)
36     m_CropAlongThisDimension[i] = true;
37 }
38 //--------------------------------------------------------------------
39
40
41 //--------------------------------------------------------------------
42 template <class ImageType>
43 void 
44 clitk::CropLikeImageFilter<ImageType>::
45 SetCropLikeFilename(std::string f) 
46 {
47   m_LikeFilename = f;
48   m_LikeFilenameIsGiven = true;
49 }
50 //--------------------------------------------------------------------
51   
52
53 //--------------------------------------------------------------------
54 template <class ImageType>
55 void 
56 clitk::CropLikeImageFilter<ImageType>::
57 SetCropLikeImage(const itk::ImageBase<ImageType::ImageDimension> * like)
58 {
59   m_LikeImage = like;
60 }
61 //--------------------------------------------------------------------
62   
63
64 //--------------------------------------------------------------------
65 template <class ImageType>
66 void 
67 clitk::CropLikeImageFilter<ImageType>::
68 SetCropLikeImage(const itk::ImageBase<ImageType::ImageDimension> * like, int axe)
69 {
70   m_LikeImage = like;
71   for(uint i=0; i<ImageType::ImageDimension; i++)
72     m_CropAlongThisDimension[i] = false;
73   m_CropAlongThisDimension[axe] = true;
74 }
75 //--------------------------------------------------------------------
76   
77
78 //--------------------------------------------------------------------
79 template <class ImageType>
80 void 
81 clitk::CropLikeImageFilter<ImageType>::
82 GenerateInputRequestedRegion() {
83   // Needed because output region can be larger than input
84   ImagePointer input = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
85   input->SetRequestedRegion(input->GetLargestPossibleRegion());
86 }
87 //--------------------------------------------------------------------
88
89
90 //--------------------------------------------------------------------
91 template <class ImageType>
92 void 
93 clitk::CropLikeImageFilter<ImageType>::
94 GenerateOutputInformation() {   
95   // Get input pointers
96   ImageConstPointer input = dynamic_cast<const ImageType*>(itk::ProcessObject::GetInput(0));
97     
98   // Get output pointer
99   ImagePointer output = this->GetOutput(0);
100
101   // Get input info
102   typename ImageType::SizeType likeSize;
103   typename ImageType::IndexType likeStart;
104   typename ImageType::PointType likeOrigin;  
105   typename ImageType::SpacingType likeSpacing;  
106   typename ImageType::DirectionType likeDirection;
107   typename ImageType::DirectionType like_invDirection;
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     likeDirection = m_LikeImage->GetDirection();
114     //I don't know really why I need the inverse...
115     like_invDirection = likeDirection.GetInverse();
116     //output->CopyInformation(m_LikeImage);
117   }
118   else {
119     // Only load the header (allows to use 'like' with any image type)
120     if (m_LikeFilenameIsGiven) {
121       itk::ImageIOBase::Pointer header = readImageHeader(m_LikeFilename);
122       for(unsigned int i=0; i<ImageType::ImageDimension; i++) {
123         likeSize[i] = header->GetDimensions(i);
124         likeStart[i] = 0;//header->GetIORegion().GetIndex()[i];
125         likeOrigin[i] = header->GetOrigin(i);
126         likeSpacing[i] = header->GetSpacing(i);
127         for(unsigned int j=0; j<ImageType::ImageDimension; j++)
128             likeDirection[i][j] = header->GetDirection(i)[j];
129        }
130       //I don't know really why I need the inverse...
131       like_invDirection = likeDirection.GetInverse();
132       }
133     else {
134       clitkExceptionMacro("You should provide SetCropLikeFilename or SetCropLike to CropLikeImageFilter");
135     }
136   }
137
138   // Check spacing
139   for(unsigned int i=0; i<ImageType::ImageDimension; i++) {
140     if (likeSpacing[i] != input->GetSpacing()[i]) {
141       clitkExceptionMacro("Images must have the same spacing, but input's spacing(" << i
142                           <<") is " << input->GetSpacing()[i] << " while the spacing(" << i 
143                           << ") of 'like' is " << likeSpacing[i] << ".");
144     }
145   }
146
147   // Check that we must crop along each dimension. If not, we use the
148   // size of the input image
149   for(unsigned int i=0; i<ImageType::ImageDimension; i++) {
150     if (m_CropAlongThisDimension[i] == false) {
151       likeStart[i] = input->GetLargestPossibleRegion().GetIndex()[i];
152       likeSize[i] = input->GetLargestPossibleRegion().GetSize()[i];
153     }
154   }
155
156   // Define output region 
157   m_OutputRegion.SetIndex(likeStart);
158   m_OutputRegion.SetSize(likeSize);
159   output->SetRegions(m_OutputRegion);
160   output->SetRequestedRegion(m_OutputRegion);
161   output->SetBufferedRegion(m_OutputRegion);
162   output->SetSpacing(likeSpacing);  
163   output->SetOrigin(likeOrigin);
164   output->SetDirection(like_invDirection);
165   output->Allocate(); // Needed ?
166
167   // get startpoint source/dest
168   // for each dim
169   // if source < dest -> start from dest, compute in source
170   // if source > dest -> start from source, compute in dest
171   m_StartDestIndex = output->GetLargestPossibleRegion().GetIndex();
172   m_StartSourceIndex = input->GetLargestPossibleRegion().GetIndex();
173   PointType m_StartPointInSource;
174   PointType m_StartPointInDest;
175   m_StartSourceIndex = input->GetLargestPossibleRegion().GetIndex();
176   input->TransformIndexToPhysicalPoint(m_StartSourceIndex, m_StartPointInSource);
177   m_StartDestIndex = output->GetLargestPossibleRegion().GetIndex();
178   output->TransformIndexToPhysicalPoint(m_StartDestIndex, m_StartPointInDest);
179   IndexType startDestInSource;
180   IndexType startSourceInDest;
181   input->TransformPhysicalPointToIndex(m_StartPointInDest, startDestInSource);
182   output->TransformPhysicalPointToIndex(m_StartPointInSource, startSourceInDest);
183   for(int i=0; i<ImageType::ImageDimension; i++) {
184     if (m_StartPointInSource[i] < m_StartPointInDest[i]) {
185       m_StartSourceIndex[i] = startDestInSource[i];
186     }
187     else {
188       m_StartDestIndex[i] = startSourceInDest[i];
189     }
190   }
191   m_Region.SetIndex(m_StartSourceIndex);
192
193   // Stop index
194   m_StopSourceIndex = input->GetLargestPossibleRegion().GetIndex()+
195     input->GetLargestPossibleRegion().GetSize();
196   m_StopDestIndex = output->GetLargestPossibleRegion().GetIndex()+
197     output->GetLargestPossibleRegion().GetSize();
198   PointType m_StopPointInSource;
199   PointType m_StopPointInDest;
200   input->TransformIndexToPhysicalPoint(m_StopSourceIndex, m_StopPointInSource);
201   output->TransformIndexToPhysicalPoint(m_StopDestIndex, m_StopPointInDest);
202   IndexType stopDestInSource;
203   IndexType stopSourceInDest;
204   input->TransformPhysicalPointToIndex(m_StopPointInDest, stopDestInSource);
205   output->TransformPhysicalPointToIndex(m_StopPointInSource, stopSourceInDest);
206
207   for(int i=0; i<ImageType::ImageDimension; i++) {
208     if (m_StopPointInSource[i] > m_StopPointInDest[i]) {
209       m_StopSourceIndex[i] = stopDestInSource[i];
210     }
211     else {
212       m_StopDestIndex[i] = stopSourceInDest[i];
213     }
214   }
215
216   // Set size to the region we want to paste
217   SizeType s;
218   for(int i=0; i<ImageType::ImageDimension; i++)
219     s[i] = m_StopSourceIndex[i]-m_StartSourceIndex[i];
220   m_Region.SetSize(s);
221
222 }
223 //--------------------------------------------------------------------
224    
225 //--------------------------------------------------------------------
226 template <class ImageType>
227 void 
228 clitk::CropLikeImageFilter<ImageType>::
229 GenerateData() {
230   // Get input pointers
231   ImageConstPointer input = dynamic_cast<const ImageType*>(itk::ProcessObject::GetInput(0));
232
233   // Get output pointer, fill with Background
234   ImagePointer output = this->GetOutput(0);
235   
236   output->FillBuffer(GetBackgroundValue());
237   
238   // Paste image inside
239   typedef clitk::PasteImageFilter<ImageType,ImageType> PasteFilterType;
240   typename PasteFilterType::Pointer pasteFilter = PasteFilterType::New();
241   //pasteFilter->ReleaseDataFlagOn(); // change nothing ?
242   //  pasteFilter->InPlaceOn(); // makt it seg fault
243   pasteFilter->SetSourceImage(input);
244   pasteFilter->SetDestinationImage(output);
245   pasteFilter->SetDestinationIndex(m_StartDestIndex);
246   pasteFilter->SetSourceRegion(m_Region);
247   pasteFilter->Update();
248
249   // Get (graft) output (SetNthOutput does not fit here because of Origin).
250   this->GraftOutput(pasteFilter->GetOutput());
251 }
252 //--------------------------------------------------------------------
253    
254
255 //--------------------------------------------------------------------
256 template<class ImageType>
257 typename ImageType::Pointer
258 clitk::ResizeImageLike(const ImageType * input,                       
259                        const itk::ImageBase<ImageType::ImageDimension> * like, 
260                        typename ImageType::PixelType backgroundValue) 
261 {
262   typedef clitk::CropLikeImageFilter<ImageType> CropFilterType;
263   typename CropFilterType::Pointer cropFilter = CropFilterType::New();
264   cropFilter->SetInput(input);
265   cropFilter->SetCropLikeImage(like);
266   cropFilter->SetBackgroundValue(backgroundValue);
267   cropFilter->Update();
268   return cropFilter->GetOutput();  
269 }
270 //--------------------------------------------------------------------
271
272
273 //--------------------------------------------------------------------
274 template<class ImageType>
275 typename ImageType::Pointer
276 clitk::ResizeImageLike(const ImageType * input,                       
277                        typename itk::ImageBase<ImageType::ImageDimension>::RegionType * region, 
278                        typename ImageType::PixelType backgroundValue) 
279 {
280   typename ImageType::Pointer output = ImageType::New();
281   output->CopyInformation(input);
282   typename ImageType::RegionType reg;
283   reg.SetIndex(region->GetIndex());
284   reg.SetSize(region->GetSize());
285   output->SetRegions(reg);
286   output->Allocate();
287   return clitk::ResizeImageLike<ImageType>(input, output, backgroundValue);
288 }
289 //--------------------------------------------------------------------
290
291
292 //--------------------------------------------------------------------
293 template<class ImageType>
294 typename ImageType::Pointer
295 clitk::ResizeImageLike(const ImageType * input, 
296                        typename itk::BoundingBox<unsigned long, ImageType::ImageDimension>::Pointer bb, 
297                        typename ImageType::PixelType BG)
298 {
299   typename ImageType::RegionType region;
300   clitk::ComputeRegionFromBB<ImageType>(input, bb, region);
301   typename ImageType::Pointer output = ImageType::New();
302   output->CopyInformation(input);
303   output->SetRegions(region);
304   output->Allocate();
305   return clitk::ResizeImageLike<ImageType>(input, output, BG);   
306 }
307 //--------------------------------------------------------------------
308
309 #endif //#define CLITKCROPLIKEIMAGEFILTER_TXX