]> Creatis software - clitk.git/blob - itk/clitkCropLikeImageFilter.txx
Ensure compatibility with VTK6 for Image2DicomRTStruct tool
[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   if (m_LikeImage) {   
107     likeSize = m_LikeImage->GetLargestPossibleRegion().GetSize();
108     likeStart = m_LikeImage->GetLargestPossibleRegion().GetIndex();
109     likeOrigin = m_LikeImage->GetOrigin();
110     likeSpacing = m_LikeImage->GetSpacing();
111     output->CopyInformation(m_LikeImage);
112   }
113   else {
114     // Only load the header (allows to use 'like' with any image type)
115     if (m_LikeFilenameIsGiven) {
116       itk::ImageIOBase::Pointer header = readImageHeader(m_LikeFilename);
117       for(unsigned int i=0; i<ImageType::ImageDimension; i++) {
118         likeSize[i] = header->GetDimensions(i);
119         likeStart[i] = 0;//header->GetIORegion().GetIndex()[i];
120         likeOrigin[i] = header->GetOrigin(i);
121         likeSpacing[i] = header->GetSpacing(i);
122       }
123     }
124     else {
125       clitkExceptionMacro("You should provide SetCropLikeFilename or SetCropLike to CropLikeImageFilter");
126     }
127   }
128
129   // Check spacing
130   for(unsigned int i=0; i<ImageType::ImageDimension; i++) {
131     if (likeSpacing[i] != input->GetSpacing()[i]) {
132       clitkExceptionMacro("Images must have the same spacing, but input's spacing(" << i
133                           <<") is " << input->GetSpacing()[i] << " while the spacing(" << i 
134                           << ") of 'like' is " << likeSpacing[i] << ".");
135     }
136   }
137
138   // Check that we must crop along each dimension. If not, we use the
139   // size of the input image
140   for(unsigned int i=0; i<ImageType::ImageDimension; i++) {
141     if (m_CropAlongThisDimension[i] == false) {
142       likeStart[i] = input->GetLargestPossibleRegion().GetIndex()[i];
143       likeSize[i] = input->GetLargestPossibleRegion().GetSize()[i];
144     }
145   }
146
147   // Define output region 
148   m_OutputRegion.SetIndex(likeStart);
149   m_OutputRegion.SetSize(likeSize);
150   output->SetRegions(m_OutputRegion);
151   output->SetRequestedRegion(m_OutputRegion);
152   output->SetBufferedRegion(m_OutputRegion);
153   output->SetSpacing(likeSpacing);  
154   output->SetOrigin(likeOrigin);
155   output->Allocate(); // Needed ?
156
157   // get startpoint source/dest
158   // for each dim
159   // if source < dest -> start from dest, compute in source
160   // if source > dest -> start from source, compute in dest
161   m_StartDestIndex = output->GetLargestPossibleRegion().GetIndex();
162   m_StartSourceIndex = input->GetLargestPossibleRegion().GetIndex();
163   PointType m_StartPointInSource;
164   PointType m_StartPointInDest;
165   m_StartSourceIndex = input->GetLargestPossibleRegion().GetIndex();
166   input->TransformIndexToPhysicalPoint(m_StartSourceIndex, m_StartPointInSource);
167   m_StartDestIndex = output->GetLargestPossibleRegion().GetIndex();
168   output->TransformIndexToPhysicalPoint(m_StartDestIndex, m_StartPointInDest);
169   IndexType startDestInSource;
170   IndexType startSourceInDest;
171   input->TransformPhysicalPointToIndex(m_StartPointInDest, startDestInSource);
172   output->TransformPhysicalPointToIndex(m_StartPointInSource, startSourceInDest);
173   for(int i=0; i<ImageType::ImageDimension; i++) {
174     if (m_StartPointInSource[i] < m_StartPointInDest[i]) {
175       m_StartSourceIndex[i] = startDestInSource[i];
176     }
177     else {
178       m_StartDestIndex[i] = startSourceInDest[i];
179     }
180   }
181   m_Region.SetIndex(m_StartSourceIndex);
182
183   // Stop index
184   m_StopSourceIndex = input->GetLargestPossibleRegion().GetIndex()+
185     input->GetLargestPossibleRegion().GetSize();
186   m_StopDestIndex = output->GetLargestPossibleRegion().GetIndex()+
187     output->GetLargestPossibleRegion().GetSize();
188   PointType m_StopPointInSource;
189   PointType m_StopPointInDest;
190   input->TransformIndexToPhysicalPoint(m_StopSourceIndex, m_StopPointInSource);
191   output->TransformIndexToPhysicalPoint(m_StopDestIndex, m_StopPointInDest);
192   IndexType stopDestInSource;
193   IndexType stopSourceInDest;
194   input->TransformPhysicalPointToIndex(m_StopPointInDest, stopDestInSource);
195   output->TransformPhysicalPointToIndex(m_StopPointInSource, stopSourceInDest);
196
197   for(int i=0; i<ImageType::ImageDimension; i++) {
198     if (m_StopPointInSource[i] > m_StopPointInDest[i]) {
199       m_StopSourceIndex[i] = stopDestInSource[i];
200     }
201     else {
202       m_StopDestIndex[i] = stopSourceInDest[i];
203     }
204   }
205
206   // Set size to the region we want to paste
207   SizeType s;
208   for(int i=0; i<ImageType::ImageDimension; i++)
209     s[i] = m_StopSourceIndex[i]-m_StartSourceIndex[i];
210   m_Region.SetSize(s);
211
212 }
213 //--------------------------------------------------------------------
214    
215 //--------------------------------------------------------------------
216 template <class ImageType>
217 void 
218 clitk::CropLikeImageFilter<ImageType>::
219 GenerateData() {
220   // Get input pointers
221   ImageConstPointer input = dynamic_cast<const ImageType*>(itk::ProcessObject::GetInput(0));
222
223   // Get output pointer, fill with Background
224   ImagePointer output = this->GetOutput(0);
225   
226   output->FillBuffer(GetBackgroundValue());
227   
228   // Paste image inside
229   typedef clitk::PasteImageFilter<ImageType,ImageType> PasteFilterType;
230   typename PasteFilterType::Pointer pasteFilter = PasteFilterType::New();
231   //pasteFilter->ReleaseDataFlagOn(); // change nothing ?
232   //  pasteFilter->InPlaceOn(); // makt it seg fault
233   pasteFilter->SetSourceImage(input);
234   pasteFilter->SetDestinationImage(output);
235   pasteFilter->SetDestinationIndex(m_StartDestIndex);
236   pasteFilter->SetSourceRegion(m_Region);
237   pasteFilter->Update();
238
239   // Get (graft) output (SetNthOutput does not fit here because of Origin).
240   this->GraftOutput(pasteFilter->GetOutput());
241 }
242 //--------------------------------------------------------------------
243    
244
245 //--------------------------------------------------------------------
246 template<class ImageType>
247 typename ImageType::Pointer
248 clitk::ResizeImageLike(const ImageType * input,                       
249                        const itk::ImageBase<ImageType::ImageDimension> * like, 
250                        typename ImageType::PixelType backgroundValue) 
251 {
252   typedef clitk::CropLikeImageFilter<ImageType> CropFilterType;
253   typename CropFilterType::Pointer cropFilter = CropFilterType::New();
254   cropFilter->SetInput(input);
255   cropFilter->SetCropLikeImage(like);
256   cropFilter->SetBackgroundValue(backgroundValue);
257   cropFilter->Update();
258   return cropFilter->GetOutput();  
259 }
260 //--------------------------------------------------------------------
261
262
263 //--------------------------------------------------------------------
264 template<class ImageType>
265 typename ImageType::Pointer
266 clitk::ResizeImageLike(const ImageType * input,                       
267                        typename itk::ImageBase<ImageType::ImageDimension>::RegionType * region, 
268                        typename ImageType::PixelType backgroundValue) 
269 {
270   typename ImageType::Pointer output = ImageType::New();
271   output->CopyInformation(input);
272   typename ImageType::RegionType reg;
273   reg.SetIndex(region->GetIndex());
274   reg.SetSize(region->GetSize());
275   output->SetRegions(reg);
276   output->Allocate();
277   return clitk::ResizeImageLike<ImageType>(input, output, backgroundValue);
278 }
279 //--------------------------------------------------------------------
280
281
282 //--------------------------------------------------------------------
283 template<class ImageType>
284 typename ImageType::Pointer
285 clitk::ResizeImageLike(const ImageType * input, 
286                        typename itk::BoundingBox<unsigned long, ImageType::ImageDimension>::Pointer bb, 
287                        typename ImageType::PixelType BG)
288 {
289   typename ImageType::RegionType region;
290   clitk::ComputeRegionFromBB<ImageType>(input, bb, region);
291   typename ImageType::Pointer output = ImageType::New();
292   output->CopyInformation(input);
293   output->SetRegions(region);
294   output->Allocate();
295   return clitk::ResizeImageLike<ImageType>(input, output, BG);   
296 }
297 //--------------------------------------------------------------------
298
299 #endif //#define CLITKCROPLIKEIMAGEFILTER_TXX