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 #ifndef itkMovingHistogramImageFilter_h
19 #define itkMovingHistogramImageFilter_h
20 
21 #include "itkMovingHistogramImageFilterBase.h"
22 #include "itkLexicographicCompare.h"
23 
24 namespace itk
25 {
26 /**
27  * \class MovingHistogramImageFilter
28  * \brief Implements a generic moving histogram algorithm
29  *
30  * This filter is a base class to implement efficiently many neighborhood
31  * filters. Instead of visiting all the neighbors of a pixel, the set
32  * of pixels in the neighborhood is updated when the filter is moving
33  * to a new pixel. The number of pixels read for each pixel can be very
34  * smaller than the number of pixels read by a basic algorithm.
35  *
36  * This filter moves the neighborhood over all the pixels of the output requested region,
37  * and pass the pixel added and removed of the neighborhood to the an
38  * histogram class. This filter doesn't implement the histogram class - it
39  * must be implement and passed as template parameter. The histogram class
40  * is not necessary a real histogram. It can be implemented in many ways,
41  * and only has to provide the methods described below.
42  *
43  * This filter takes 4 template parameters: the input and output image type,
44  * the structuring element (or kernel) type, and the histogram type.
45  * The input and output image must have the same number of dimension.
46  *
47  * The histogram type is a class which has to implements six methods:
48  * + a default constructor which takes no parameter.
49  * + void AddPixel( const InputPixelType &p ) is called when a new pixel
50  * is added to the histogram.
51  * + void RemovePixel( const InputPixelType &p ) is called when a pixel
52  * is removed of the histogram.
53  * + void AddBoundary() is called when a pixel outside the image is added.
54  * No value is provided: it's the responsibility to the histogram class to
55  * get it if needed. This method can be kept empty to ignore the boundary
56  * pixels.
57  * + void RemoveBoundary() is called to when a pixel outside the image is removed.
58  * No value is provided: it's the responsibility to the histogram class to
59  * get it if needed. This method can be kept empty to ignore the boundary
60  * pixels.
61  * + AType GetValue() is called to set the value of the output image. AType
62  * must be the output pixel type, or a type castable to the output pixel type.
63  *
64  * MovingHistogramImageFilter add the new pixels before removing the old ones,
65  * so, if AddBoundary() is implemented and/or the kernel is symetric, it is safe
66  * to consider that the histogram will never be empty.
67  *
68  * One histogram is created for each thread by the method NewHistogram().
69  * The NewHistogram() method can be overiden to pass some parameters to the
70  * histogram.
71  *
72  * The neighborhood is defined by a structuring element, and must a
73  * itk::Neighborhood object or a subclass.
74  * The structuring element is assumed to be composed of binary
75  * values (zero or one). Only elements of the structuring element
76  * having values > 0 are candidates for affecting the center pixel.
77  *
78  * \sa MovingWindowMeanImageFilter, RankImageFilter, MaskedMovingHistogramImageFilter,
79  * \sa MovingHistogramMorphologicalGradientImageFilter
80  * \ingroup ImageEnhancement  MathematicalMorphologyImageFilters
81  *
82  * \author Gaetan Lehmann
83  * \author Richard Beare
84  * \ingroup ITKImageFilterBase
85  */
86 
87 template< typename TInputImage, typename TOutputImage, typename TKernel, typename THistogram >
88 class ITK_TEMPLATE_EXPORT MovingHistogramImageFilter:
89   public MovingHistogramImageFilterBase< TInputImage, TOutputImage, TKernel >
90 {
91 public:
92   ITK_DISALLOW_COPY_AND_ASSIGN(MovingHistogramImageFilter);
93 
94   /** Standard class type aliases. */
95   using Self = MovingHistogramImageFilter;
96   using Superclass = MovingHistogramImageFilterBase< TInputImage, TOutputImage, TKernel >;
97   using Pointer = SmartPointer< Self >;
98   using ConstPointer = SmartPointer< const Self >;
99 
100   /** Standard New method. */
101   itkNewMacro(Self);
102 
103   /** Runtime information support. */
104   itkTypeMacro(MovingHistogramImageFilter,
105                MovingHistogramImageFilter);
106 
107   /** Image related type alias. */
108   using InputImageType = TInputImage;
109   using OutputImageType = TOutputImage;
110   using RegionType = typename TInputImage::RegionType;
111   using SizeType = typename TInputImage::SizeType;
112   using IndexType = typename TInputImage::IndexType;
113   using PixelType = typename TInputImage::PixelType;
114   using OffsetType = typename TInputImage::OffsetType;
115   using OutputImageRegionType = typename Superclass::OutputImageRegionType;
116   using OutputPixelType = typename TOutputImage::PixelType;
117 
118   /** Image related type alias. */
119   static constexpr unsigned int ImageDimension = TInputImage::ImageDimension;
120 
121   /** Kernel type alias. */
122   using KernelType = TKernel;
123 
124   /** Kernel (structuring element) iterator. */
125   using KernelIteratorType = typename KernelType::ConstIterator;
126 
127   /** n-dimensional Kernel radius. */
128   using RadiusType = typename KernelType::SizeType;
129 
130   using OffsetListType = typename std::list< OffsetType >;
131 
132   using OffsetMapType = typename std::map< OffsetType, OffsetListType, Functor::LexicographicCompare >;
133 
134   /** Configure the histogram.
135    *  Subclasses must override this method. */
ConfigureHistogram(THistogram &)136   virtual void ConfigureHistogram(THistogram &) {}
137 
138 protected:
139   MovingHistogramImageFilter();
140   ~MovingHistogramImageFilter() override = default;
141 
142   /** Multi-thread version of GenerateData. */
143   void DynamicThreadedGenerateData(const OutputImageRegionType & outputRegionForThread) override;
144 
145 
146   // declare the type used to store the histogram
147   using HistogramType = THistogram;
148 
149   void PushHistogram(HistogramType & histogram,
150                      const OffsetListType *addedList,
151                      const OffsetListType *removedList,
152                      const RegionType & inputRegion,
153                      const RegionType & kernRegion,
154                      const InputImageType *inputImage,
155                      const IndexType currentIdx);
156 };                                          // end of class
157 } // end namespace itk
158 
159 #ifndef ITK_MANUAL_INSTANTIATION
160 #include "itkMovingHistogramImageFilter.hxx"
161 #endif
162 
163 #endif
164