]> Creatis software - clitk.git/blob - itk/clitkCropLikeImageFilter.txx
c92591256a6054414a249c46bb7743384f25227a
[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://oncora1.lyon.fnclcc.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   // Define output region 
140   m_OutputRegion.SetIndex(likeStart);
141   m_OutputRegion.SetSize(likeSize);
142   output->SetRegions(m_OutputRegion);
143   output->SetRequestedRegion(m_OutputRegion);
144   output->SetBufferedRegion(m_OutputRegion);
145   output->SetSpacing(likeSpacing);  
146   output->SetOrigin(likeOrigin);
147   output->Allocate(); // Needed ?
148
149   // get startpoint source/dest
150   // for each dim
151   // if source < dest -> start from dest, compute in source
152   // if source > dest -> start from source, compute in dest
153   m_StartDestIndex = output->GetLargestPossibleRegion().GetIndex();
154   m_StartSourceIndex = input->GetLargestPossibleRegion().GetIndex();
155   PointType m_StartPointInSource;
156   PointType m_StartPointInDest;
157   m_StartSourceIndex = input->GetLargestPossibleRegion().GetIndex();
158   input->TransformIndexToPhysicalPoint(m_StartSourceIndex, m_StartPointInSource);
159   m_StartDestIndex = output->GetLargestPossibleRegion().GetIndex();
160   output->TransformIndexToPhysicalPoint(m_StartDestIndex, m_StartPointInDest);
161   IndexType startDestInSource;
162   IndexType startSourceInDest;
163   input->TransformPhysicalPointToIndex(m_StartPointInDest, startDestInSource);
164   output->TransformPhysicalPointToIndex(m_StartPointInSource, startSourceInDest);
165   for(int i=0; i<ImageType::ImageDimension; i++) {
166     if (m_StartPointInSource[i] < m_StartPointInDest[i]) {
167       m_StartSourceIndex[i] = startDestInSource[i];
168     }
169     else {
170       m_StartDestIndex[i] = startSourceInDest[i];
171     }
172   }
173   m_Region.SetIndex(m_StartSourceIndex);
174
175   // Stop index
176   m_StopSourceIndex = input->GetLargestPossibleRegion().GetIndex()+
177     input->GetLargestPossibleRegion().GetSize();
178   m_StopDestIndex = output->GetLargestPossibleRegion().GetIndex()+
179     output->GetLargestPossibleRegion().GetSize();
180   PointType m_StopPointInSource;
181   PointType m_StopPointInDest;
182   input->TransformIndexToPhysicalPoint(m_StopSourceIndex, m_StopPointInSource);
183   output->TransformIndexToPhysicalPoint(m_StopDestIndex, m_StopPointInDest);
184   IndexType stopDestInSource;
185   IndexType stopSourceInDest;
186   input->TransformPhysicalPointToIndex(m_StopPointInDest, stopDestInSource);
187   output->TransformPhysicalPointToIndex(m_StopPointInSource, stopSourceInDest);
188
189   for(int i=0; i<ImageType::ImageDimension; i++) {
190     if (m_StopPointInSource[i] > m_StopPointInDest[i]) {
191       m_StopSourceIndex[i] = stopDestInSource[i];
192     }
193     else {
194       m_StopDestIndex[i] = stopSourceInDest[i];
195     }
196   }
197
198   // Set size to the region we want to paste
199   SizeType s;
200   for(int i=0; i<ImageType::ImageDimension; i++)
201     s[i] = m_StopSourceIndex[i]-m_StartSourceIndex[i];
202   m_Region.SetSize(s);
203
204 }
205 //--------------------------------------------------------------------
206    
207 //--------------------------------------------------------------------
208 template <class ImageType>
209 void 
210 clitk::CropLikeImageFilter<ImageType>::
211 GenerateData() {
212   // Get input pointers
213   ImageConstPointer input = dynamic_cast<const ImageType*>(itk::ProcessObject::GetInput(0));
214
215   // Get output pointer, fill with Background
216   ImagePointer output = this->GetOutput(0);
217   
218   output->FillBuffer(GetBackgroundValue());
219   
220   // Paste image inside
221   typedef itk::PasteImageFilter<ImageType,ImageType> PasteFilterType;
222   typename PasteFilterType::Pointer pasteFilter = PasteFilterType::New();
223   //pasteFilter->ReleaseDataFlagOn(); // change nothing ?
224   //  pasteFilter->InPlaceOn(); // makt it seg fault
225   pasteFilter->SetSourceImage(input);
226   pasteFilter->SetDestinationImage(output);
227   pasteFilter->SetDestinationIndex(m_StartDestIndex);
228   pasteFilter->SetSourceRegion(m_Region);
229   pasteFilter->Update();
230
231   // Get (graft) output (SetNthOutput does not fit here because of Origin).
232   this->GraftOutput(pasteFilter->GetOutput());
233 }
234 //--------------------------------------------------------------------
235    
236  
237 #endif //#define CLITKAUTOCROPFILTER