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"
26 #include "itkPasteImageFilter.h"
28 //--------------------------------------------------------------------
29 template <class ImageType>
30 clitk::CropLikeImageFilter<ImageType>::
31 CropLikeImageFilter():itk::ImageToImageFilter<ImageType, ImageType>() {
32 this->SetNumberOfRequiredInputs(1);
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;
40 //--------------------------------------------------------------------
43 //--------------------------------------------------------------------
44 template <class ImageType>
46 clitk::CropLikeImageFilter<ImageType>::
47 SetCropLikeFilename(std::string f)
50 m_LikeFilenameIsGiven = true;
52 //--------------------------------------------------------------------
55 //--------------------------------------------------------------------
56 template <class ImageType>
58 clitk::CropLikeImageFilter<ImageType>::
59 SetCropLikeImage(const itk::ImageBase<ImageType::ImageDimension> * like)
63 //--------------------------------------------------------------------
66 //--------------------------------------------------------------------
67 template <class ImageType>
69 clitk::CropLikeImageFilter<ImageType>::
70 SetCropLikeImage(const itk::ImageBase<ImageType::ImageDimension> * like, int axe)
73 for(uint i=0; i<ImageType::ImageDimension; i++)
74 m_CropAlongThisDimension[i] = false;
75 m_CropAlongThisDimension[axe] = true;
77 //--------------------------------------------------------------------
80 //--------------------------------------------------------------------
81 template <class ImageType>
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());
89 //--------------------------------------------------------------------
92 //--------------------------------------------------------------------
93 template <class ImageType>
95 clitk::CropLikeImageFilter<ImageType>::
96 GenerateOutputInformation() {
98 ImageConstPointer input = dynamic_cast<const ImageType*>(itk::ProcessObject::GetInput(0));
100 // Get output pointer
101 ImagePointer output = this->GetOutput(0);
104 typename ImageType::SizeType likeSize;
105 typename ImageType::IndexType likeStart;
106 typename ImageType::PointType likeOrigin;
107 typename ImageType::SpacingType likeSpacing;
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);
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);
127 clitkExceptionMacro("You should provide SetCropLikeFilename or SetCropLike to CropLikeImageFilter");
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] << ".");
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 ?
149 // get startpoint source/dest
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];
170 m_StartDestIndex[i] = startSourceInDest[i];
173 m_Region.SetIndex(m_StartSourceIndex);
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);
189 for(int i=0; i<ImageType::ImageDimension; i++) {
190 if (m_StopPointInSource[i] > m_StopPointInDest[i]) {
191 m_StopSourceIndex[i] = stopDestInSource[i];
194 m_StopDestIndex[i] = stopSourceInDest[i];
198 // Set size to the region we want to paste
200 for(int i=0; i<ImageType::ImageDimension; i++)
201 s[i] = m_StopSourceIndex[i]-m_StartSourceIndex[i];
205 //--------------------------------------------------------------------
207 //--------------------------------------------------------------------
208 template <class ImageType>
210 clitk::CropLikeImageFilter<ImageType>::
212 // Get input pointers
213 ImageConstPointer input = dynamic_cast<const ImageType*>(itk::ProcessObject::GetInput(0));
215 // Get output pointer, fill with Background
216 ImagePointer output = this->GetOutput(0);
218 output->FillBuffer(GetBackgroundValue());
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();
231 // Get (graft) output (SetNthOutput does not fit here because of Origin).
232 this->GraftOutput(pasteFilter->GetOutput());
234 //--------------------------------------------------------------------
237 #endif //#define CLITKAUTOCROPFILTER