1 /*=========================================================================
2  *
3  *  Copyright Insight Software Consortium
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at
8  *
9  *         http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  *=========================================================================*/
18 
19 #ifndef itkBinaryImageToLevelSetImageAdaptor_h
20 #define itkBinaryImageToLevelSetImageAdaptor_h
21 
22 #include "itkBinaryImageToLevelSetImageAdaptorBase.h"
23 
24 #include "itkLevelSetDenseImage.h"
25 #include "itkImageToImageFilter.h"
26 
27 #include "itkWhitakerSparseLevelSetImage.h"
28 #include "itkImageRegionIteratorWithIndex.h"
29 #include "itkShapedNeighborhoodIterator.h"
30 
31 #include "itkShiSparseLevelSetImage.h"
32 #include "itkMalcolmSparseLevelSetImage.h"
33 
34 namespace itk
35 {
36 /** \class BinaryImageToLevelSetImageAdator
37  *  \brief Converts one binary image to the appropriate level-set type
38  *  provided by the template argument TLevelSet.
39  *
40  *  \tparam TInputImage Binary Input Image Type
41  *  \tparam TLevelSet   Output Level-Set Type
42  *
43  *  \note TLevelSet must inherits from LevelSetImage
44  *
45  *  \sa LevelSetImage
46  *
47  *  \ingroup ITKLevelSetsv4
48  */
49 template< typename TInputImage, typename TLevelSet >
50 class ITK_TEMPLATE_EXPORT BinaryImageToLevelSetImageAdaptor
51 {};
52 
53 
54 /** \brief Partial template specialization for LevelSetDenseImage
55  */
56 template< typename TInputImage, typename TLevelSetImage >
57 class ITK_TEMPLATE_EXPORT BinaryImageToLevelSetImageAdaptor<
58     TInputImage,
59     LevelSetDenseImage< TLevelSetImage > > :
60 public BinaryImageToLevelSetImageAdaptorBase<
61     TInputImage,
62     LevelSetDenseImage< TLevelSetImage > >
63 {
64 public:
65   ITK_DISALLOW_COPY_AND_ASSIGN(BinaryImageToLevelSetImageAdaptor);
66 
67   using LevelSetType = LevelSetDenseImage< TLevelSetImage >;
68 
69   using Self = BinaryImageToLevelSetImageAdaptor;
70   using Pointer = SmartPointer< Self >;
71   using ConstPointer = SmartPointer< const Self >;
72   using Superclass = BinaryImageToLevelSetImageAdaptorBase<
73     TInputImage, LevelSetType >;
74 
75   /** Method for creation through object factory */
76   itkNewMacro( Self );
77 
78   /** Run-time type information */
79   itkTypeMacro( BinaryImageToLevelSetImageAdaptorBase, Object );
80 
81   using InputImageType = TInputImage;
82   using InputImagePixelType = typename InputImageType::PixelType;
83   using InputImageIndexType = typename InputImageType::IndexType;
84   using InputImagePointer = typename InputImageType::Pointer;
85   using InputImageRegionType = typename InputImageType::RegionType;
86   using InputPixelRealType = typename NumericTraits<InputImagePixelType>::RealType;
87 
88   static constexpr unsigned int ImageDimension = InputImageType::ImageDimension;
89 
90   using LevelSetPointer = typename LevelSetType::Pointer;
91   using LevelSetImageType = typename LevelSetType::ImageType;
92 
93   using SignedDistanceTransformFilterType = ImageToImageFilter< InputImageType, LevelSetImageType >;
94   using SignedDistanceTransformFilterPointer = typename SignedDistanceTransformFilterType::Pointer;
95 
96   /** Set the signed distance image filter.  Defaults to a
97    * SignedMaurerDistanceMapImageFilter. */
98   itkSetObjectMacro( SignedDistanceTransformFilter, SignedDistanceTransformFilterType );
99   itkGetModifiableObjectMacro(SignedDistanceTransformFilter, SignedDistanceTransformFilterType );
100 
101   /**
102    * Input is a binary image m_InputImage
103    * Output is a WhitakerSparseLevelSetImagePointer  */
104   void Initialize() override;
105 
106 protected:
107   /** Constructor */
108   BinaryImageToLevelSetImageAdaptor();
109 
110   /** Destructor */
111   ~BinaryImageToLevelSetImageAdaptor() override;
112 
113 private:
114   SignedDistanceTransformFilterPointer   m_SignedDistanceTransformFilter;
115 };
116 
117 ////////////////////////////////////////////////////////////////////////////////
118 
119 /** \class BinaryImageToSparseLevelSetImageAdaptorBase
120  *  \brief Abstract class for converting binary image to sparse level-set
121  *
122  *  \ingroup ITKLevelSetsv4
123  */
124 template< typename TInput, typename TOutput >
125 class ITK_TEMPLATE_EXPORT BinaryImageToSparseLevelSetImageAdaptorBase :
126     public BinaryImageToLevelSetImageAdaptorBase< TInput, TOutput >
127 {
128 public:
129   ITK_DISALLOW_COPY_AND_ASSIGN(BinaryImageToSparseLevelSetImageAdaptorBase);
130 
131   using Self = BinaryImageToSparseLevelSetImageAdaptorBase;
132   using Pointer = SmartPointer< Self >;
133   using ConstPointer = SmartPointer< const Self >;
134   using Superclass =
135       BinaryImageToLevelSetImageAdaptorBase< TInput, TOutput >;
136 
137   /** Run-time type information */
138   itkTypeMacro( BinaryImageToSparseLevelSetImageAdaptorBase,
139                 BinaryImageToLevelSetImageAdaptorBase );
140 
141   using InputImageType = typename Superclass::InputImageType;
142   using InputImagePixelType = typename Superclass::InputImagePixelType;
143   using InputImageIndexType = typename Superclass::InputImageIndexType;
144   using InputImagePointer = typename Superclass::InputImagePointer;
145   using InputImageRegionType = typename Superclass::InputImageRegionType;
146   using InputPixelRealType = typename Superclass::InputPixelRealType;
147 
148   static constexpr unsigned int ImageDimension = InputImageType::ImageDimension;
149 
150   using LevelSetType = typename Superclass::LevelSetType;
151   using LevelSetPointer = typename Superclass::LevelSetPointer;
152 
153   using LevelSetInputType = typename LevelSetType::InputType;
154   using LevelSetOutputType = typename LevelSetType::OutputType;
155 
156   using LevelSetLabelObjectType = typename LevelSetType::LabelObjectType;
157   using LayerIdType = typename LevelSetLabelObjectType::LabelType;
158   using LevelSetLabelObjectPointer = typename LevelSetType::LabelObjectPointer;
159   using LevelSetLabelObjectLengthType = typename LevelSetType::LabelObjectLengthType;
160   using LevelSetLabelObjectLineType = typename LevelSetType::LabelObjectLineType;
161 
162   using LevelSetLabelMapType = typename LevelSetType::LabelMapType;
163   using LevelSetLabelMapPointer = typename LevelSetType::LabelMapPointer;
164 
165   using LevelSetLayerType = typename LevelSetType::LayerType;
166   using LevelSetLayerIterator = typename LevelSetType::LayerIterator;
167   using LevelSetLayerConstIterator = typename LevelSetType::LayerConstIterator;
168 
169   using InternalImageType = Image< signed char, ImageDimension >;
170   using InternalImagePointer = typename InternalImageType::Pointer;
171 
172   using LayerPairType = std::pair< LevelSetInputType, LevelSetOutputType >;
173 
174   using InputIteratorType = ImageRegionIteratorWithIndex< InputImageType >;
175   using InternalIteratorType = ImageRegionIteratorWithIndex< InternalImageType >;
176 
177   using NeighborhoodIteratorType = ShapedNeighborhoodIterator< InternalImageType >;
178 
179 protected:
BinaryImageToSparseLevelSetImageAdaptorBase()180   BinaryImageToSparseLevelSetImageAdaptorBase() : Superclass() {}
181   ~BinaryImageToSparseLevelSetImageAdaptorBase() override = default;
182 
183   LevelSetLabelMapPointer m_LabelMap;
184 
185   InternalImagePointer m_InternalImage;
186 };
187 
188 ////////////////////////////////////////////////////////////////////////////////
189 /** \brief Partial template specialization for WhitakerSparseLevelSetImage
190  */
191 template< typename TInput, typename TOutput >
192 class ITK_TEMPLATE_EXPORT BinaryImageToLevelSetImageAdaptor<
193     TInput,
194     WhitakerSparseLevelSetImage< TOutput, TInput::ImageDimension > > :
195   public BinaryImageToSparseLevelSetImageAdaptorBase<
196       TInput,
197       WhitakerSparseLevelSetImage< TOutput, TInput::ImageDimension > >
198   {
199 public:
200   ITK_DISALLOW_COPY_AND_ASSIGN(BinaryImageToLevelSetImageAdaptor);
201 
202   using LevelSetType =
203       WhitakerSparseLevelSetImage< TOutput, TInput::ImageDimension >;
204 
205   using Self = BinaryImageToLevelSetImageAdaptor;
206   using Pointer = SmartPointer< Self >;
207   using ConstPointer = SmartPointer< const Self >;
208   using Superclass = BinaryImageToSparseLevelSetImageAdaptorBase<
209     TInput, LevelSetType >;
210 
211 
212   /** Method for creation through object factory */
213   itkNewMacro( Self );
214 
215   /** Run-time type information */
216   itkTypeMacro( BinaryImageToLevelSetImageAdaptor,
217                 BinaryImageToSparseLevelSetImageAdaptorBase );
218 
219   using InputImageType = typename Superclass::InputImageType;
220   using InputImagePixelType = typename Superclass::InputImagePixelType;
221   using InputImageIndexType = typename Superclass::InputImageIndexType;
222   using InputImagePointer = typename Superclass::InputImagePointer;
223   using InputImageRegionType = typename Superclass::InputImageRegionType;
224   using InputPixelRealType = typename Superclass::InputPixelRealType;
225 
226   static constexpr unsigned int ImageDimension = InputImageType::ImageDimension;
227 
228   using LevelSetPointer = typename Superclass::LevelSetPointer;
229 
230   using LevelSetInputType = typename Superclass::LevelSetInputType;
231   using LevelSetOutputType = typename Superclass::LevelSetOutputType;
232 
233   using LevelSetLabelObjectType = typename Superclass::LevelSetLabelObjectType;
234   using LayerIdType = typename Superclass::LayerIdType;
235   using LevelSetLabelObjectPointer = typename Superclass::LevelSetLabelObjectPointer;
236   using LevelSetLabelObjectLengthType = typename Superclass::LevelSetLabelObjectLengthType;
237   using LevelSetLabelObjectLineType = typename Superclass::LevelSetLabelObjectLineType;
238 
239   using LevelSetLabelMapType = typename Superclass::LevelSetLabelMapType;
240   using LevelSetLabelMapPointer = typename Superclass::LevelSetLabelMapPointer;
241 
242   using LevelSetLayerType = typename Superclass::LevelSetLayerType;
243   using LevelSetLayerIterator = typename Superclass::LevelSetLayerIterator;
244   using LevelSetLayerConstIterator = typename Superclass::LevelSetLayerConstIterator;
245 
246   using InternalImageType = typename Superclass::InternalImageType;
247   using InternalImagePointer = typename Superclass::InternalImagePointer;
248 
249   using LayerPairType = typename Superclass::LayerPairType;
250 
251   using InputIteratorType = typename Superclass::InputIteratorType;
252   using InternalIteratorType = typename Superclass::InternalIteratorType;
253 
254   using NeighborhoodIteratorType = typename Superclass::NeighborhoodIteratorType;
255 
256   void Initialize() override;
257 
258 protected:
259   /** Constructor */
260   BinaryImageToLevelSetImageAdaptor();
261 
262   /** Destructor */
263   ~BinaryImageToLevelSetImageAdaptor() override;
264 
265 private:
266 
267   /** Fill layer adjacent (OutputLayer) to the layer (LayerToBeScanned) */
268   void PropagateToOuterLayers( LayerIdType LayerToBeScanned, LayerIdType OutputLayer, LayerIdType TestValue );
269 
270   /** Fill the layer corresponding to zero level set */
271   void FindActiveLayer();
272 
273   /** Fill layers adjacent to the zero level set (i.e. layer -1 and +1 )*/
274   void FindPlusOneMinusOneLayer();
275 
276 };
277 
278 ////////////////////////////////////////////////////////////////////////////////
279 /** \brief Partial template specialization for ShiSparseLevelSetImage
280  */
281 template< typename TInput >
282 class ITK_TEMPLATE_EXPORT BinaryImageToLevelSetImageAdaptor<
283     TInput,
284     ShiSparseLevelSetImage< TInput::ImageDimension > > :
285 public BinaryImageToSparseLevelSetImageAdaptorBase<
286     TInput,
287     ShiSparseLevelSetImage< TInput::ImageDimension > >
288 {
289 public:
290   ITK_DISALLOW_COPY_AND_ASSIGN(BinaryImageToLevelSetImageAdaptor);
291 
292   using LevelSetType = ShiSparseLevelSetImage< TInput::ImageDimension >;
293 
294   using Self = BinaryImageToLevelSetImageAdaptor;
295   using Pointer = SmartPointer< Self >;
296   using ConstPointer = SmartPointer< const Self >;
297   using Superclass = BinaryImageToSparseLevelSetImageAdaptorBase<
298     TInput, LevelSetType >;
299 
300   /** Method for creation through object factory */
301   itkNewMacro( Self );
302 
303   /** Run-time type information */
304   itkTypeMacro( BinaryImageToLevelSetImageAdaptor,
305                 BinaryImageToSparseLevelSetImageAdaptorBase );
306 
307   using InputImageType = typename Superclass::InputImageType;
308 
309   using InputImagePixelType = typename Superclass::InputImagePixelType;
310   using InputImageIndexType = typename Superclass::InputImageIndexType;
311   using InputImagePointer = typename Superclass::InputImagePointer;
312   using InputImageRegionType = typename Superclass::InputImageRegionType;
313   using InputPixelRealType = typename Superclass::InputPixelRealType;
314 
315   static constexpr unsigned int ImageDimension = InputImageType::ImageDimension;
316 
317 //  using LevelSetType = typename Superclass::LevelSetType;
318   using LevelSetPointer = typename Superclass::LevelSetPointer;
319 
320   using LevelSetInputType = typename Superclass::LevelSetInputType;
321   using LevelSetOutputType = typename Superclass::LevelSetOutputType;
322 
323   using LevelSetLabelObjectType = typename Superclass::LevelSetLabelObjectType;
324   using LayerIdType = typename Superclass::LayerIdType;
325   using LevelSetLabelObjectPointer = typename Superclass::LevelSetLabelObjectPointer;
326   using LevelSetLabelObjectLengthType = typename Superclass::LevelSetLabelObjectLengthType;
327   using LevelSetLabelObjectLineType = typename Superclass::LevelSetLabelObjectLineType;
328 
329   using LevelSetLabelMapType = typename Superclass::LevelSetLabelMapType;
330   using LevelSetLabelMapPointer = typename Superclass::LevelSetLabelMapPointer;
331 
332   using LevelSetLayerType = typename Superclass::LevelSetLayerType;
333   using LevelSetLayerIterator = typename Superclass::LevelSetLayerIterator;
334   using LevelSetLayerConstIterator = typename Superclass::LevelSetLayerConstIterator;
335 
336   using InternalImageType = typename Superclass::InternalImageType;
337   using InternalImagePointer = typename Superclass::InternalImagePointer;
338 
339   using LayerPairType = typename Superclass::LayerPairType;
340 
341   using InputIteratorType = typename Superclass::InputIteratorType;
342   using InternalIteratorType = typename Superclass::InternalIteratorType;
343 
344   using NeighborhoodIteratorType = typename Superclass::NeighborhoodIteratorType;
345 
346   void Initialize() override;
347 
348 protected:
349   /** Constructor */
350   BinaryImageToLevelSetImageAdaptor();
351 
352   /** Destructor */
353   ~BinaryImageToLevelSetImageAdaptor() override;
354 
355   /** Find the active layer separating the foreground and background regions */
356   void FindActiveLayer();
357 
358 private:
359 
360 };
361 
362 
363 ////////////////////////////////////////////////////////////////////////////////
364 /** \brief Partial template specialization for MalcolmSparseLevelSetImage
365  */
366 template< typename TInput >
367 class ITK_TEMPLATE_EXPORT BinaryImageToLevelSetImageAdaptor<
368     TInput,
369     MalcolmSparseLevelSetImage< TInput::ImageDimension > > :
370   public BinaryImageToSparseLevelSetImageAdaptorBase< TInput, MalcolmSparseLevelSetImage< TInput::ImageDimension > >
371 {
372 public:
373   ITK_DISALLOW_COPY_AND_ASSIGN(BinaryImageToLevelSetImageAdaptor);
374 
375   using LevelSetType = MalcolmSparseLevelSetImage< TInput::ImageDimension >;
376 
377   using Self = BinaryImageToLevelSetImageAdaptor;
378   using Pointer = SmartPointer< Self >;
379   using ConstPointer = SmartPointer< const Self >;
380   using Superclass = BinaryImageToSparseLevelSetImageAdaptorBase<
381     TInput, LevelSetType >;
382 
383 
384   /** Method for creation through object factory */
385   itkNewMacro( Self );
386 
387   /** Run-time type information */
388   itkTypeMacro( BinaryImageToLevelSetImageAdaptor,
389                 BinaryImageToSparseLevelSetImageAdaptorBase );
390 
391   using InputImageType = typename Superclass::InputImageType;
392 
393   using InputImagePixelType = typename Superclass::InputImagePixelType;
394   using InputImageIndexType = typename Superclass::InputImageIndexType;
395   using InputImagePointer = typename Superclass::InputImagePointer;
396   using InputImageRegionType = typename Superclass::InputImageRegionType;
397   using InputPixelRealType = typename Superclass::InputPixelRealType;
398 
399   static constexpr unsigned int ImageDimension = InputImageType::ImageDimension;
400 
401 
402   using LevelSetPointer = typename Superclass::LevelSetPointer;
403   using LevelSetInputType = typename Superclass::LevelSetInputType;
404   using LevelSetOutputType = typename Superclass::LevelSetOutputType;
405 
406   using LevelSetLabelObjectType = typename Superclass::LevelSetLabelObjectType;
407   using LayerIdType = typename Superclass::LayerIdType;
408   using LevelSetLabelObjectPointer = typename Superclass::LevelSetLabelObjectPointer;
409   using LevelSetLabelObjectLengthType = typename Superclass::LevelSetLabelObjectLengthType;
410   using LevelSetLabelObjectLineType = typename Superclass::LevelSetLabelObjectLineType;
411 
412   using LevelSetLabelMapType = typename Superclass::LevelSetLabelMapType;
413   using LevelSetLabelMapPointer = typename Superclass::LevelSetLabelMapPointer;
414 
415   using LevelSetLayerType = typename Superclass::LevelSetLayerType;
416   using LevelSetLayerIterator = typename Superclass::LevelSetLayerIterator;
417   using LevelSetLayerConstIterator = typename Superclass::LevelSetLayerConstIterator;
418 
419   using InternalImageType = typename Superclass::InternalImageType;
420   using InternalImagePointer = typename Superclass::InternalImagePointer;
421 
422   using LayerPairType = typename Superclass::LayerPairType;
423 
424   using InputIteratorType = typename Superclass::InputIteratorType;
425   using InternalIteratorType = typename Superclass::InternalIteratorType;
426 
427   using NeighborhoodIteratorType = typename Superclass::NeighborhoodIteratorType;
428 
429   void Initialize() override;
430 
431 protected:
432   /** Constructor */
433   BinaryImageToLevelSetImageAdaptor();
434 
435   /** Destructor */
436   ~BinaryImageToLevelSetImageAdaptor() override;
437 
438   /** Find the active layer separating the foreground and background regions */
439   void FindActiveLayer();
440 
441   /** Ensure that the 0 level set layer is only of single pixel thickness */
442   void CreateMinimalInterface();
443 };
444 
445 }
446 
447 #ifndef ITK_MANUAL_INSTANTIATION
448 #include "itkBinaryImageToLevelSetImageAdaptor.hxx"
449 #endif
450 #endif // itkBinaryImageToLevelSetImageAdaptorBase_h
451