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://oncora1.lyon.fnclcc.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 ======================================================================-====*/
20 #include "clitkSetBackgroundImageFilter.h"
23 #include <itkConnectedComponentImageFilter.h>
24 #include <itkRelabelComponentImageFilter.h>
25 #include <itkBinaryThresholdImageFilter.h>
26 #include <itkPasteImageFilter.h>
28 //--------------------------------------------------------------------
29 template<class ImageType>
30 void clitk::ComputeBBFromImageRegion(typename ImageType::Pointer image,
31 typename ImageType::RegionType region,
32 typename itk::BoundingBox<unsigned long,
33 ImageType::ImageDimension>::Pointer bb) {
34 typedef typename ImageType::IndexType IndexType;
37 for(unsigned int i=0; i<image->GetImageDimension(); i++) {
38 firstIndex[i] = region.GetIndex()[i];
39 lastIndex[i] = firstIndex[i]+region.GetSize()[i];
42 typedef itk::BoundingBox<unsigned long,
43 ImageType::ImageDimension> BBType;
44 typedef typename BBType::PointType PointType;
47 image->TransformIndexToPhysicalPoint(firstIndex, firstPoint);
48 image->TransformIndexToPhysicalPoint(lastIndex, lastPoint);
50 bb->SetMaximum(lastPoint);
51 bb->SetMinimum(firstPoint);
53 //--------------------------------------------------------------------
56 //--------------------------------------------------------------------
57 template<int Dimension>
58 void clitk::ComputeBBIntersection(typename itk::BoundingBox<unsigned long, Dimension>::Pointer bbo,
59 typename itk::BoundingBox<unsigned long, Dimension>::Pointer bbi1,
60 typename itk::BoundingBox<unsigned long, Dimension>::Pointer bbi2) {
62 typedef itk::BoundingBox<unsigned long, Dimension> BBType;
63 typedef typename BBType::PointType PointType;
67 for(unsigned int i=0; i<Dimension; i++) {
68 firstPoint[i] = std::max(bbi1->GetMinimum()[i],
69 bbi2->GetMinimum()[i]);
70 lastPoint[i] = std::min(bbi1->GetMaximum()[i],
71 bbi2->GetMaximum()[i]);
74 bbo->SetMaximum(lastPoint);
75 bbo->SetMinimum(firstPoint);
77 //--------------------------------------------------------------------
80 //--------------------------------------------------------------------
81 template<class ImageType>
82 void clitk::ComputeRegionFromBB(typename ImageType::Pointer image,
83 const typename itk::BoundingBox<unsigned long,
84 ImageType::ImageDimension>::Pointer bb,
85 typename ImageType::RegionType & region) {
87 typedef typename ImageType::IndexType IndexType;
88 typedef typename ImageType::PointType PointType;
89 typedef typename ImageType::RegionType RegionType;
90 typedef typename ImageType::SizeType SizeType;
92 // Region starting point
93 IndexType regionStart;
94 PointType start = bb->GetMinimum();
95 image->TransformPhysicalPointToIndex(start, regionStart);
99 PointType maxs = bb->GetMaximum();
100 PointType mins = bb->GetMinimum();
101 for(unsigned int i=0; i<ImageType::ImageDimension; i++) {
104 // DD((maxs[i] - mins[i])/image->GetSpacing()[i]);
105 regionSize[i] = lrint((maxs[i] - mins[i])/image->GetSpacing()[i]);
106 // DD(regionSize[i]);
110 region.SetIndex(regionStart);
111 region.SetSize(regionSize);
113 //--------------------------------------------------------------------
115 //--------------------------------------------------------------------
116 template<class ImageType, class TMaskImageType>
117 typename ImageType::Pointer
118 clitk::SetBackground(//typename ImageType::ConstPointer input,
119 const ImageType * input,
120 const TMaskImageType * mask,
121 typename TMaskImageType::PixelType maskBG,
122 typename ImageType::PixelType outValue) {
123 typedef clitk::SetBackgroundImageFilter<ImageType, TMaskImageType, ImageType> SetBackgroundImageFilterType;
124 typename SetBackgroundImageFilterType::Pointer setBackgroundFilter = SetBackgroundImageFilterType::New();
125 setBackgroundFilter->SetInput(input);
126 setBackgroundFilter->SetInput2(mask);
127 setBackgroundFilter->SetMaskValue(maskBG);
128 setBackgroundFilter->SetOutsideValue(outValue);
129 setBackgroundFilter->Update();
130 return setBackgroundFilter->GetOutput();
132 //--------------------------------------------------------------------
135 //--------------------------------------------------------------------
136 template<class ImageType>
137 int clitk::GetNumberOfConnectedComponentLabels(typename ImageType::Pointer input,
138 typename ImageType::PixelType BG,
139 bool isFullyConnected) {
140 // Connected Component label
141 typedef itk::ConnectedComponentImageFilter<ImageType, ImageType> ConnectFilterType;
142 typename ConnectFilterType::Pointer connectFilter = ConnectFilterType::New();
143 connectFilter->SetInput(input);
144 connectFilter->SetBackgroundValue(BG);
145 connectFilter->SetFullyConnected(isFullyConnected);
146 connectFilter->Update();
149 return connectFilter->GetObjectCount();
151 //--------------------------------------------------------------------
153 //--------------------------------------------------------------------
154 template<class ImageType>
155 typename ImageType::Pointer
156 clitk::Labelize(typename ImageType::Pointer input,
157 typename ImageType::PixelType BG,
158 bool isFullyConnected,
159 int minimalComponentSize) {
160 // InternalImageType for storing large number of component
161 typedef itk::Image<int, ImageType::ImageDimension> InternalImageType;
163 // Connected Component label
164 typedef itk::ConnectedComponentImageFilter<ImageType, InternalImageType> ConnectFilterType;
165 typename ConnectFilterType::Pointer connectFilter = ConnectFilterType::New();
166 connectFilter->SetInput(input);
167 connectFilter->SetBackgroundValue(BG);
168 connectFilter->SetFullyConnected(isFullyConnected);
170 // Sort by size and remove too small area.
171 typedef itk::RelabelComponentImageFilter<InternalImageType, ImageType> RelabelFilterType;
172 typename RelabelFilterType::Pointer relabelFilter = RelabelFilterType::New();
173 relabelFilter->InPlaceOn();
174 relabelFilter->SetInput(connectFilter->GetOutput());
175 relabelFilter->SetMinimumObjectSize(minimalComponentSize);
176 relabelFilter->Update();
179 return relabelFilter->GetOutput();
181 //--------------------------------------------------------------------
184 //--------------------------------------------------------------------
185 template<class ImageType>
186 typename ImageType::Pointer
187 clitk::RemoveLabels(typename ImageType::Pointer input,
188 typename ImageType::PixelType BG,
189 std::vector<typename ImageType::PixelType> & labelsToRemove) {
190 typename ImageType::Pointer working_image = input;
191 for (unsigned int i=0; i <labelsToRemove.size(); i++) {
192 typedef clitk::SetBackgroundImageFilter<ImageType, ImageType> SetBackgroundImageFilterType;
193 typename SetBackgroundImageFilterType::Pointer setBackgroundFilter = SetBackgroundImageFilterType::New();
194 setBackgroundFilter->SetInput(input);
195 setBackgroundFilter->SetInput2(input);
196 setBackgroundFilter->SetMaskValue(labelsToRemove[i]);
197 setBackgroundFilter->SetOutsideValue(BG);
198 setBackgroundFilter->Update();
199 working_image = setBackgroundFilter->GetOutput();
201 return working_image;
203 //--------------------------------------------------------------------
206 //--------------------------------------------------------------------
207 template<class ImageType>
208 typename ImageType::Pointer
209 clitk::KeepLabels(typename ImageType::Pointer input,
210 typename ImageType::PixelType BG,
211 typename ImageType::PixelType FG,
212 typename ImageType::PixelType firstKeep,
213 typename ImageType::PixelType lastKeep,
215 typedef itk::BinaryThresholdImageFilter<ImageType, ImageType> BinarizeFilterType;
216 typename BinarizeFilterType::Pointer binarizeFilter = BinarizeFilterType::New();
217 binarizeFilter->SetInput(input);
218 binarizeFilter->SetLowerThreshold(firstKeep);
219 if (useLastKeep) binarizeFilter->SetUpperThreshold(lastKeep);
220 binarizeFilter->SetInsideValue(FG);
221 binarizeFilter->SetOutsideValue(BG);
222 binarizeFilter->Update();
223 return binarizeFilter->GetOutput();
225 //--------------------------------------------------------------------
228 //--------------------------------------------------------------------
229 template<class ImageType>
230 typename ImageType::Pointer
231 clitk::LabelizeAndSelectLabels(typename ImageType::Pointer input,
232 typename ImageType::PixelType BG,
233 typename ImageType::PixelType FG,
234 bool isFullyConnected,
235 int minimalComponentSize,
236 LabelizeParameters<typename ImageType::PixelType> * param)
238 typename ImageType::Pointer working_image;
239 working_image = Labelize<ImageType>(input, BG, isFullyConnected, minimalComponentSize);
240 working_image = RemoveLabels<ImageType>(working_image, BG, param->GetLabelsToRemove());
241 working_image = KeepLabels<ImageType>(working_image,
243 param->GetFirstKeep(),
244 param->GetLastKeep(),
245 param->GetUseLastKeep());
246 return working_image;
248 //--------------------------------------------------------------------
251 //--------------------------------------------------------------------
252 template<class ImageType>
253 typename ImageType::Pointer
254 clitk::EnlargeImageLike(typename ImageType::Pointer input,
255 typename ImageType::Pointer like,
256 typename ImageType::PixelType backgroundValue)
258 if (!HaveSameSpacing<ImageType, ImageType>(input, like)) {
259 FATAL("Images must have the same spacing");
262 typename ImageType::Pointer output = ImageType::New();
263 typename ImageType::SizeType size;
264 for(unsigned int i=0; i<ImageType::ImageDimension; i++) {
265 size[i] = lrint((like->GetLargestPossibleRegion().GetSize()[i]*like->GetSpacing()[i])/
266 (double)like->GetSpacing()[i]);
269 typename ImageType::RegionType region;
270 region.SetSize(size);
271 output->SetRegions(region);
272 output->SetSpacing(like->GetSpacing());
273 output->SetOrigin(like->GetOrigin());
275 output->FillBuffer(backgroundValue);
276 typedef itk::PasteImageFilter<ImageType,ImageType> PasteFilterType;
277 typename PasteFilterType::Pointer pasteFilter = PasteFilterType::New();
278 typename PasteFilterType::InputImageIndexType index;
279 for(unsigned int i=0; i<ImageType::ImageDimension; i++) {
280 index[i] = lrint((input->GetOrigin()[i] - like->GetOrigin()[i])/(double)input->GetSpacing()[i]);
283 pasteFilter->SetSourceImage(input);
284 pasteFilter->SetDestinationImage(output);
285 pasteFilter->SetDestinationIndex(index);
286 pasteFilter->SetSourceRegion(input->GetLargestPossibleRegion());
287 pasteFilter->Update();
288 return pasteFilter->GetOutput();
290 //--------------------------------------------------------------------