]> Creatis software - clitk.git/blob - itk/clitkCropLikeImageFilter.txx
new crop like (allow to enlarge image)
[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   DD("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   }
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 like's spacing(" << i 
136                           << ") 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
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 template <class ImageType>
207 void 
208 clitk::CropLikeImageFilter<ImageType>::
209 GenerateData() {
210   // Get input pointers
211   ImageConstPointer input = dynamic_cast<const ImageType*>(itk::ProcessObject::GetInput(0));
212
213   // Get output pointer, fill with Background
214   ImagePointer output = this->GetOutput(0);
215   output->Allocate();
216   output->FillBuffer(GetBackgroundValue());
217   
218   // Paste image inside
219   typedef itk::PasteImageFilter<ImageType,ImageType> PasteFilterType;
220   typename PasteFilterType::Pointer pasteFilter = PasteFilterType::New();
221   pasteFilter->SetSourceImage(input);
222   pasteFilter->SetDestinationImage(output);
223   pasteFilter->SetDestinationIndex(m_StartDestIndex);
224   pasteFilter->SetSourceRegion(m_Region);
225   pasteFilter->Update();
226
227   // Get (graft) output (SetNthOutput does not fit here because of Origin).
228   //  this->GraftOutput(cropFilter->GetOutput());
229   this->GraftOutput(pasteFilter->GetOutput());
230 }
231 //--------------------------------------------------------------------
232    
233  
234 #endif //#define CLITKAUTOCROPFILTER