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"
27 //#include "itkPasteImageFilter.h"
29 //--------------------------------------------------------------------
30 template <class ImageType>
31 clitk::CropLikeImageFilter<ImageType>::
32 CropLikeImageFilter():itk::ImageToImageFilter<ImageType, ImageType>() {
33 this->SetNumberOfRequiredInputs(1);
35 m_LikeFilenameIsGiven = false;
36 this->SetBackgroundValue(0);
37 m_CropAlongThisDimension.resize(ImageType::ImageDimension);
38 for(uint i=0; i<ImageType::ImageDimension; i++)
39 m_CropAlongThisDimension[i] = true;
41 //--------------------------------------------------------------------
44 //--------------------------------------------------------------------
45 template <class ImageType>
47 clitk::CropLikeImageFilter<ImageType>::
48 SetCropLikeFilename(std::string f)
51 m_LikeFilenameIsGiven = true;
53 //--------------------------------------------------------------------
56 //--------------------------------------------------------------------
57 template <class ImageType>
59 clitk::CropLikeImageFilter<ImageType>::
60 SetCropLikeImage(const itk::ImageBase<ImageType::ImageDimension> * like)
64 //--------------------------------------------------------------------
67 //--------------------------------------------------------------------
68 template <class ImageType>
70 clitk::CropLikeImageFilter<ImageType>::
71 SetCropLikeImage(const itk::ImageBase<ImageType::ImageDimension> * like, int axe)
74 for(uint i=0; i<ImageType::ImageDimension; i++)
75 m_CropAlongThisDimension[i] = false;
76 m_CropAlongThisDimension[axe] = true;
78 //--------------------------------------------------------------------
81 //--------------------------------------------------------------------
82 template <class ImageType>
84 clitk::CropLikeImageFilter<ImageType>::
85 GenerateInputRequestedRegion() {
86 // Needed because output region can be larger than input
87 ImagePointer input = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
88 input->SetRequestedRegion(input->GetLargestPossibleRegion());
90 //--------------------------------------------------------------------
93 //--------------------------------------------------------------------
94 template <class ImageType>
96 clitk::CropLikeImageFilter<ImageType>::
97 GenerateOutputInformation() {
99 ImageConstPointer input = dynamic_cast<const ImageType*>(itk::ProcessObject::GetInput(0));
101 // Get output pointer
102 ImagePointer output = this->GetOutput(0);
105 typename ImageType::SizeType likeSize;
106 typename ImageType::IndexType likeStart;
107 typename ImageType::PointType likeOrigin;
108 typename ImageType::SpacingType likeSpacing;
110 likeSize = m_LikeImage->GetLargestPossibleRegion().GetSize();
111 likeStart = m_LikeImage->GetLargestPossibleRegion().GetIndex();
112 likeOrigin = m_LikeImage->GetOrigin();
113 likeSpacing = m_LikeImage->GetSpacing();
114 output->CopyInformation(m_LikeImage);
117 // Only load the header (allows to use 'like' with any image type)
118 if (m_LikeFilenameIsGiven) {
119 itk::ImageIOBase::Pointer header = readImageHeader(m_LikeFilename);
120 for(unsigned int i=0; i<ImageType::ImageDimension; i++) {
121 likeSize[i] = header->GetDimensions(i);
122 likeStart[i] = 0;//header->GetIORegion().GetIndex()[i];
123 likeOrigin[i] = header->GetOrigin(i);
124 likeSpacing[i] = header->GetSpacing(i);
128 clitkExceptionMacro("You should provide SetCropLikeFilename or SetCropLike to CropLikeImageFilter");
133 for(unsigned int i=0; i<ImageType::ImageDimension; i++) {
134 if (likeSpacing[i] != input->GetSpacing()[i]) {
135 clitkExceptionMacro("Images must have the same spacing, but input's spacing(" << i
136 <<") is " << input->GetSpacing()[i] << " while the spacing(" << i
137 << ") of 'like' is " << likeSpacing[i] << ".");
141 // Check that we must crop along each dimension. If not, we use the
142 // size of the input image
143 for(unsigned int i=0; i<ImageType::ImageDimension; i++) {
144 if (m_CropAlongThisDimension[i] == false) {
145 likeStart[i] = input->GetLargestPossibleRegion().GetIndex()[i];
146 likeSize[i] = input->GetLargestPossibleRegion().GetSize()[i];
150 // Define output region
151 m_OutputRegion.SetIndex(likeStart);
152 m_OutputRegion.SetSize(likeSize);
153 output->SetRegions(m_OutputRegion);
154 output->SetRequestedRegion(m_OutputRegion);
155 output->SetBufferedRegion(m_OutputRegion);
156 output->SetSpacing(likeSpacing);
157 output->SetOrigin(likeOrigin);
158 output->Allocate(); // Needed ?
160 // get startpoint source/dest
162 // if source < dest -> start from dest, compute in source
163 // if source > dest -> start from source, compute in dest
164 m_StartDestIndex = output->GetLargestPossibleRegion().GetIndex();
165 m_StartSourceIndex = input->GetLargestPossibleRegion().GetIndex();
166 PointType m_StartPointInSource;
167 PointType m_StartPointInDest;
168 m_StartSourceIndex = input->GetLargestPossibleRegion().GetIndex();
169 input->TransformIndexToPhysicalPoint(m_StartSourceIndex, m_StartPointInSource);
170 m_StartDestIndex = output->GetLargestPossibleRegion().GetIndex();
171 output->TransformIndexToPhysicalPoint(m_StartDestIndex, m_StartPointInDest);
172 IndexType startDestInSource;
173 IndexType startSourceInDest;
174 input->TransformPhysicalPointToIndex(m_StartPointInDest, startDestInSource);
175 output->TransformPhysicalPointToIndex(m_StartPointInSource, startSourceInDest);
176 for(int i=0; i<ImageType::ImageDimension; i++) {
177 if (m_StartPointInSource[i] < m_StartPointInDest[i]) {
178 m_StartSourceIndex[i] = startDestInSource[i];
181 m_StartDestIndex[i] = startSourceInDest[i];
184 m_Region.SetIndex(m_StartSourceIndex);
187 m_StopSourceIndex = input->GetLargestPossibleRegion().GetIndex()+
188 input->GetLargestPossibleRegion().GetSize();
189 m_StopDestIndex = output->GetLargestPossibleRegion().GetIndex()+
190 output->GetLargestPossibleRegion().GetSize();
191 PointType m_StopPointInSource;
192 PointType m_StopPointInDest;
193 input->TransformIndexToPhysicalPoint(m_StopSourceIndex, m_StopPointInSource);
194 output->TransformIndexToPhysicalPoint(m_StopDestIndex, m_StopPointInDest);
195 IndexType stopDestInSource;
196 IndexType stopSourceInDest;
197 input->TransformPhysicalPointToIndex(m_StopPointInDest, stopDestInSource);
198 output->TransformPhysicalPointToIndex(m_StopPointInSource, stopSourceInDest);
200 for(int i=0; i<ImageType::ImageDimension; i++) {
201 if (m_StopPointInSource[i] > m_StopPointInDest[i]) {
202 m_StopSourceIndex[i] = stopDestInSource[i];
205 m_StopDestIndex[i] = stopSourceInDest[i];
209 // Set size to the region we want to paste
211 for(int i=0; i<ImageType::ImageDimension; i++)
212 s[i] = m_StopSourceIndex[i]-m_StartSourceIndex[i];
216 //--------------------------------------------------------------------
218 //--------------------------------------------------------------------
219 template <class ImageType>
221 clitk::CropLikeImageFilter<ImageType>::
223 // Get input pointers
224 ImageConstPointer input = dynamic_cast<const ImageType*>(itk::ProcessObject::GetInput(0));
226 // Get output pointer, fill with Background
227 ImagePointer output = this->GetOutput(0);
229 output->FillBuffer(GetBackgroundValue());
231 // Paste image inside
232 typedef clitk::PasteImageFilter<ImageType,ImageType> PasteFilterType;
233 typename PasteFilterType::Pointer pasteFilter = PasteFilterType::New();
234 //pasteFilter->ReleaseDataFlagOn(); // change nothing ?
235 // pasteFilter->InPlaceOn(); // makt it seg fault
236 pasteFilter->SetSourceImage(input);
237 pasteFilter->SetDestinationImage(output);
238 pasteFilter->SetDestinationIndex(m_StartDestIndex);
239 pasteFilter->SetSourceRegion(m_Region);
240 pasteFilter->Update();
242 // Get (graft) output (SetNthOutput does not fit here because of Origin).
243 this->GraftOutput(pasteFilter->GetOutput());
245 //--------------------------------------------------------------------
248 #endif //#define CLITKAUTOCROPFILTER