]> Creatis software - clitk.git/blob - itk/clitkCropLikeImageFilter.txx
add missing "allocate"
[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   }
114   else {
115     // Only load the header (allows to use 'like' with any image type)
116     if (m_LikeFilenameIsGiven) {
117       itk::ImageIOBase::Pointer header = readImageHeader(m_LikeFilename);
118       for(unsigned int i=0; i<ImageType::ImageDimension; i++) {
119         likeSize[i] = header->GetDimensions(i);
120         likeStart[i] = 0;//header->GetIORegion().GetIndex()[i];
121         likeOrigin[i] = header->GetOrigin(i);
122         likeSpacing[i] = header->GetSpacing(i);
123       }
124     }
125     else {
126       clitkExceptionMacro("You should provide SetCropLikeFilename or SetCropLike to CropLikeImageFilter");
127     }
128   }
129
130   // Check spacing
131   for(unsigned int i=0; i<ImageType::ImageDimension; i++) {
132     if (likeSpacing[i] != input->GetSpacing()[i]) {
133       clitkExceptionMacro("Images must have the same spacing, but input's spacing(" << i
134                           <<") is " << input->GetSpacing()[i] << " while the spacing(" << i 
135                           << ") of 'like' is " << likeSpacing[i] << ".");
136     }
137   }
138   // Define output region 
139   m_OutputRegion.SetIndex(likeStart);
140   m_OutputRegion.SetSize(likeSize);
141   output->SetRegions(m_OutputRegion);
142   output->SetRequestedRegion(m_OutputRegion);
143   output->SetBufferedRegion(m_OutputRegion);
144   output->SetSpacing(likeSpacing);  
145   output->SetOrigin(likeOrigin);
146   output->Allocate(); // Needed ?
147
148   // get startpoint source/dest
149   // for each dim
150   // if source < dest -> start from dest, compute in source
151   // if source > dest -> start from source, compute in dest
152   m_StartDestIndex = output->GetLargestPossibleRegion().GetIndex();
153   m_StartSourceIndex = input->GetLargestPossibleRegion().GetIndex();
154   PointType m_StartPointInSource;
155   PointType m_StartPointInDest;
156   m_StartSourceIndex = input->GetLargestPossibleRegion().GetIndex();
157   input->TransformIndexToPhysicalPoint(m_StartSourceIndex, m_StartPointInSource);
158   m_StartDestIndex = output->GetLargestPossibleRegion().GetIndex();
159   output->TransformIndexToPhysicalPoint(m_StartDestIndex, m_StartPointInDest);
160   IndexType startDestInSource;
161   IndexType startSourceInDest;
162   input->TransformPhysicalPointToIndex(m_StartPointInDest, startDestInSource);
163   output->TransformPhysicalPointToIndex(m_StartPointInSource, startSourceInDest);
164   for(int i=0; i<ImageType::ImageDimension; i++) {
165     if (m_StartPointInSource[i] < m_StartPointInDest[i]) {
166       m_StartSourceIndex[i] = startDestInSource[i];
167     }
168     else {
169       m_StartDestIndex[i] = startSourceInDest[i];
170     }
171   }
172   m_Region.SetIndex(m_StartSourceIndex);
173
174   // Stop index
175   m_StopSourceIndex = input->GetLargestPossibleRegion().GetIndex()+
176     input->GetLargestPossibleRegion().GetSize();
177   m_StopDestIndex = output->GetLargestPossibleRegion().GetIndex()+
178     output->GetLargestPossibleRegion().GetSize();
179   PointType m_StopPointInSource;
180   PointType m_StopPointInDest;
181   input->TransformIndexToPhysicalPoint(m_StopSourceIndex, m_StopPointInSource);
182   output->TransformIndexToPhysicalPoint(m_StopDestIndex, m_StopPointInDest);
183   IndexType stopDestInSource;
184   IndexType stopSourceInDest;
185   input->TransformPhysicalPointToIndex(m_StopPointInDest, stopDestInSource);
186   output->TransformPhysicalPointToIndex(m_StopPointInSource, stopSourceInDest);
187
188   for(int i=0; i<ImageType::ImageDimension; i++) {
189     if (m_StopPointInSource[i] > m_StopPointInDest[i]) {
190       m_StopSourceIndex[i] = stopDestInSource[i];
191     }
192     else {
193       m_StopDestIndex[i] = stopSourceInDest[i];
194     }
195   }
196
197   // Set size to the region we want to paste
198   SizeType s;
199   for(int i=0; i<ImageType::ImageDimension; i++)
200     s[i] = m_StopSourceIndex[i]-m_StartSourceIndex[i];
201   m_Region.SetSize(s);
202
203 }
204 //--------------------------------------------------------------------
205    
206 //--------------------------------------------------------------------
207 template <class ImageType>
208 void 
209 clitk::CropLikeImageFilter<ImageType>::
210 GenerateData() {
211   // Get input pointers
212   ImageConstPointer input = dynamic_cast<const ImageType*>(itk::ProcessObject::GetInput(0));
213
214   // Get output pointer, fill with Background
215   ImagePointer output = this->GetOutput(0);
216   
217   output->FillBuffer(GetBackgroundValue());
218   
219   // Paste image inside
220   typedef itk::PasteImageFilter<ImageType,ImageType> PasteFilterType;
221   typename PasteFilterType::Pointer pasteFilter = PasteFilterType::New();
222   //pasteFilter->ReleaseDataFlagOn(); // change nothing ?
223   //  pasteFilter->InPlaceOn(); // makt it seg fault
224   pasteFilter->SetSourceImage(input);
225   pasteFilter->SetDestinationImage(output);
226   pasteFilter->SetDestinationIndex(m_StartDestIndex);
227   pasteFilter->SetSourceRegion(m_Region);
228   pasteFilter->Update();
229
230   // Get (graft) output (SetNthOutput does not fit here because of Origin).
231   this->GraftOutput(pasteFilter->GetOutput());
232 }
233 //--------------------------------------------------------------------
234    
235  
236 #endif //#define CLITKAUTOCROPFILTER