1 /*=========================================================================
2 Program: vv http://www.creatis.insa-lyon.fr/rio/vv
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
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.
13 It is distributed under dual licence
15 - BSD See included LICENSE.txt file
16 - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
17 ===========================================================================**/
19 #ifndef CLITKCROPLIKEIMAGEFILTER_TXX
20 #define CLITKCROPLIKEIMAGEFILTER_TXX
23 #include "clitkCommon.h"
24 #include "clitkPasteImageFilter.h"
26 //--------------------------------------------------------------------
27 template <class ImageType>
28 clitk::CropLikeImageFilter<ImageType>::
29 CropLikeImageFilter():itk::ImageToImageFilter<ImageType, ImageType>() {
30 this->SetNumberOfRequiredInputs(1);
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;
38 //--------------------------------------------------------------------
41 //--------------------------------------------------------------------
42 template <class ImageType>
44 clitk::CropLikeImageFilter<ImageType>::
45 SetCropLikeFilename(std::string f)
48 m_LikeFilenameIsGiven = true;
50 //--------------------------------------------------------------------
53 //--------------------------------------------------------------------
54 template <class ImageType>
56 clitk::CropLikeImageFilter<ImageType>::
57 SetCropLikeImage(const itk::ImageBase<ImageType::ImageDimension> * like)
61 //--------------------------------------------------------------------
64 //--------------------------------------------------------------------
65 template <class ImageType>
67 clitk::CropLikeImageFilter<ImageType>::
68 SetCropLikeImage(const itk::ImageBase<ImageType::ImageDimension> * like, int axe)
71 for(uint i=0; i<ImageType::ImageDimension; i++)
72 m_CropAlongThisDimension[i] = false;
73 m_CropAlongThisDimension[axe] = true;
75 //--------------------------------------------------------------------
78 //--------------------------------------------------------------------
79 template <class ImageType>
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());
87 //--------------------------------------------------------------------
90 //--------------------------------------------------------------------
91 template <class ImageType>
93 clitk::CropLikeImageFilter<ImageType>::
94 GenerateOutputInformation() {
96 ImageConstPointer input = dynamic_cast<const ImageType*>(itk::ProcessObject::GetInput(0));
99 ImagePointer output = this->GetOutput(0);
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;
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);
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];
130 //I don't know really why I need the inverse...
131 like_invDirection = likeDirection.GetInverse();
134 clitkExceptionMacro("You should provide SetCropLikeFilename or SetCropLike to CropLikeImageFilter");
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] << ".");
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];
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 ?
167 // get startpoint source/dest
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];
188 m_StartDestIndex[i] = startSourceInDest[i];
191 m_Region.SetIndex(m_StartSourceIndex);
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);
207 for(int i=0; i<ImageType::ImageDimension; i++) {
208 if (m_StopPointInSource[i] > m_StopPointInDest[i]) {
209 m_StopSourceIndex[i] = stopDestInSource[i];
212 m_StopDestIndex[i] = stopSourceInDest[i];
216 // Set size to the region we want to paste
218 for(int i=0; i<ImageType::ImageDimension; i++)
219 s[i] = m_StopSourceIndex[i]-m_StartSourceIndex[i];
223 //--------------------------------------------------------------------
225 //--------------------------------------------------------------------
226 template <class ImageType>
228 clitk::CropLikeImageFilter<ImageType>::
230 // Get input pointers
231 ImageConstPointer input = dynamic_cast<const ImageType*>(itk::ProcessObject::GetInput(0));
233 // Get output pointer, fill with Background
234 ImagePointer output = this->GetOutput(0);
236 output->FillBuffer(GetBackgroundValue());
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();
249 // Get (graft) output (SetNthOutput does not fit here because of Origin).
250 this->GraftOutput(pasteFilter->GetOutput());
252 //--------------------------------------------------------------------
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)
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();
270 //--------------------------------------------------------------------
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)
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);
287 return clitk::ResizeImageLike<ImageType>(input, output, backgroundValue);
289 //--------------------------------------------------------------------
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)
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);
305 return clitk::ResizeImageLike<ImageType>(input, output, BG);
307 //--------------------------------------------------------------------
309 #endif //#define CLITKCROPLIKEIMAGEFILTER_TXX