SMIL  1.0.4
DMorphoFilter.hpp
1 /*
2  * Copyright (c) 2011-2016, Matthieu FAESSEL and ARMINES
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * * Neither the name of Matthieu FAESSEL, or ARMINES nor the
14  * names of its contributors may be used to endorse or promote products
15  * derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #ifndef _D_MORPHO_FILTER_HPP
31 #define _D_MORPHO_FILTER_HPP
32 
33 #include "Core/include/DImage.h"
34 #include "DMorphImageOperations.hxx"
35 
36 #include "Base/include/private/DImageArith.hpp"
37 #include "Morpho/include/DMorphoInstance.h"
38 #include "DHitOrMiss.hpp"
39 
40 namespace smil
41 {
69  template <class T>
70  RES_T close(const Image<T> &imIn, Image<T> &imOut,
71  const StrElt &se = DEFAULT_SE)
72  {
73  ASSERT_ALLOCATED(&imIn, &imOut);
74  ASSERT_SAME_SIZE(&imIn, &imOut);
75  ImageFreezer freeze(imOut);
76 
77  bool inplaceSafe = MorphImageFunction<T, supLine<T>>::isInplaceSafe(se);
78  Image<T> *imTmp;
79  if (inplaceSafe)
80  imTmp = &imOut;
81  else
82  imTmp = new Image<T>(imIn);
83 
84  ASSERT((dilate(imIn, *imTmp, se) == RES_OK));
85  ASSERT((erode(*imTmp, imOut, se) == RES_OK));
86 
87  if (!inplaceSafe)
88  delete imTmp;
89 
90  return RES_OK;
91  }
92 
107  template <class T>
108  RES_T close(const Image<T> &imIn, Image<T> &imOut, UINT seSize)
109  {
110  return close(imIn, imOut, DEFAULT_SE(seSize));
111  }
112 
122  template <class T>
123  RES_T open(const Image<T> &imIn, Image<T> &imOut,
124  const StrElt &se = DEFAULT_SE)
125  {
126  ASSERT_ALLOCATED(&imIn, &imOut);
127  ASSERT_SAME_SIZE(&imIn, &imOut);
128  ImageFreezer freeze(imOut);
129 
130  bool inplaceSafe = MorphImageFunction<T, supLine<T>>::isInplaceSafe(se);
131  Image<T> *imTmp;
132  if (inplaceSafe)
133  imTmp = &imOut;
134  else
135  imTmp = new Image<T>(imIn);
136 
137  ASSERT((erode(imIn, *imTmp, se) == RES_OK));
138  ASSERT((dilate(*imTmp, imOut, se) == RES_OK));
139 
140  if (!inplaceSafe)
141  delete imTmp;
142 
143  return RES_OK;
144  }
145 
160  template <class T>
161  RES_T open(const Image<T> &imIn, Image<T> &imOut, UINT seSize)
162  {
163  return open(imIn, imOut, DEFAULT_SE(seSize));
164  }
165 
166 
180  template <class T>
181  RES_T asfClose(const Image<T> &imIn, Image<T> &imOut,
182  const StrElt &se = DEFAULT_SE)
183  {
184  ASSERT_ALLOCATED(&imIn, &imOut);
185  ASSERT_SAME_SIZE(&imIn, &imOut);
186 
187  ImageFreezer freeze(imOut);
188 
189  Image<T> tmpIm(imIn, true); // clone
190  for (UINT i = 1; i <= se.size; i++) {
191  ASSERT((close(tmpIm, imOut, se(i)) == RES_OK));
192  ASSERT((open(imOut, tmpIm, se(i)) == RES_OK));
193  }
194  ASSERT((copy(tmpIm, imOut) == RES_OK));
195 
196  return RES_OK;
197  }
198 
210  template <class T>
211  RES_T asfOpen(const Image<T> &imIn, Image<T> &imOut,
212  const StrElt &se = DEFAULT_SE)
213  {
214  ASSERT_ALLOCATED(&imIn, &imOut);
215  ASSERT_SAME_SIZE(&imIn, &imOut);
216 
217  ImageFreezer freeze(imOut);
218 
219  Image<T> tmpIm(imIn, true); // clone
220  for (UINT i = 1; i <= se.size; i++) {
221  ASSERT((open(tmpIm, imOut, se(i)) == RES_OK));
222  ASSERT((close(imOut, tmpIm, se(i)) == RES_OK));
223  }
224  ASSERT((copy(tmpIm, imOut) == RES_OK));
225 
226  return RES_OK;
227  }
228 
230  template <class T> class meanFunct : public MorphImageFunctionBase<T, T>
231  {
232  public:
233  typedef MorphImageFunctionBase<T, T> parentClass;
234 
235  virtual inline void processPixel(size_t pointOffset,
236  vector<int> &dOffsetList)
237  {
238  double meanVal = 0;
239  vector<int>::iterator dOffset = dOffsetList.begin();
240  while (dOffset != dOffsetList.end()) {
241  meanVal += double(parentClass::pixelsIn[pointOffset + *dOffset]);
242  dOffset++;
243  }
244  parentClass::pixelsOut[pointOffset] =
245  T(meanVal / double(dOffsetList.size()));
246  }
247  };
257  template <class T>
258  RES_T mean(const Image<T> &imIn, Image<T> &imOut,
259  const StrElt &se = DEFAULT_SE)
260  {
261  ASSERT_ALLOCATED(&imIn, &imOut);
262  ASSERT_SAME_SIZE(&imIn, &imOut);
263 
264  meanFunct<T> f;
265 
266  ASSERT((f._exec(imIn, imOut, se) == RES_OK));
267 
268  return RES_OK;
269  }
270 
272  template <class T> class medianFunct : public MorphImageFunctionBase<T, T>
273  {
274  public:
275  typedef MorphImageFunctionBase<T, T> parentClass;
276 
277  virtual inline void processPixel(size_t pointOffset,
278  vector<int> &dOffsetList)
279  {
280  vector<T> vals;
281  vector<int>::iterator dOffset = dOffsetList.begin();
282  while (dOffset != dOffsetList.end()) {
283  vals.push_back(parentClass::pixelsIn[pointOffset + *dOffset]);
284  dOffset++;
285  }
286  sort(vals.begin(), vals.end());
287  parentClass::pixelsOut[pointOffset] = vals[dOffsetList.size() / 2];
288  }
289  };
299  template <class T>
300  RES_T median(const Image<T> &imIn, Image<T> &imOut,
301  const StrElt &se = DEFAULT_SE)
302  {
303  ASSERT_ALLOCATED(&imIn, &imOut);
304  ASSERT_SAME_SIZE(&imIn, &imOut);
305 
306  medianFunct<T> f;
307 
308  ASSERT((f._exec(imIn, imOut, se) == RES_OK));
309 
310  return RES_OK;
311  }
312 
314  template <class T> class rankFunct : public MorphImageFunctionBase<T, T>
315  {
316  public:
317  typedef MorphImageFunctionBase<T, T> parentClass;
318 
319  rankFunct(double per) : MorphImageFunctionBase<T, T>(), percentile(per)
320  {
321  }
322  virtual inline void processPixel(size_t pointOffset,
323  vector<int> &dOffsetList)
324  {
325  vector<T> vals;
326  vector<int>::iterator dOffset = dOffsetList.begin();
327  while (dOffset != dOffsetList.end()) {
328  vals.push_back(parentClass::pixelsIn[pointOffset + *dOffset]);
329  dOffset++;
330  }
331  sort(vals.begin(), vals.end());
332  parentClass::pixelsOut[pointOffset] =
333  vals[static_cast<int>(dOffsetList.size() * this->percentile)];
334  }
335 
336  private:
337  double percentile;
338  };
348  template <class T>
349  RES_T rank(const Image<T> &imIn, Image<T> &imOut, double percentile,
350  const StrElt &se = DEFAULT_SE)
351  {
352  ASSERT_ALLOCATED(&imIn, &imOut);
353  ASSERT_SAME_SIZE(&imIn, &imOut);
354 
355  rankFunct<T> f(percentile);
356 
357  ASSERT((f._exec(imIn, imOut, se) == RES_OK));
358 
359  return RES_OK;
360  }
361 
364 } // namespace smil
365 
366 #endif // _D_MORPHO_FILTER_HPP
Definition: DBaseImage.h:386
Main Image class.
Definition: DImage.hpp:57
Definition: DMorphImageOperations.hpp:145
Base structuring element.
Definition: DStructuringElement.h:68
RES_T median(const Image< T > &imIn, Image< T > &imOut, const StrElt &se=DEFAULT_SE)
Median filter.
Definition: DMorphoFilter.hpp:300
RES_T rank(const Image< T > &imIn, Image< T > &imOut, double percentile, const StrElt &se=DEFAULT_SE)
Rank filter.
Definition: DMorphoFilter.hpp:349
RES_T close(const Image< T > &imIn, Image< T > &imOut, UINT seSize)
close() - Morphological grayscale closing using the default structuring element but being able to set...
Definition: DMorphoFilter.hpp:108
RES_T asfOpen(const Image< T > &imIn, Image< T > &imOut, const StrElt &se=DEFAULT_SE)
Alternate Sequential Filter beginning by an opening.
Definition: DMorphoFilter.hpp:211
RES_T asfClose(const Image< T > &imIn, Image< T > &imOut, const StrElt &se=DEFAULT_SE)
Alternate Sequential Filter beginning by a closing.
Definition: DMorphoFilter.hpp:181
RES_T mean(const Image< T > &imIn, Image< T > &imOut, const StrElt &se=DEFAULT_SE)
Mean filter.
Definition: DMorphoFilter.hpp:258
RES_T open(const Image< T > &imIn, Image< T > &imOut, UINT seSize)
open() - Morphological grayscale opening using the default structuring element but being able to set ...
Definition: DMorphoFilter.hpp:161
Vector_double meanVal(const Image< T > &imIn, bool onlyNonZero=false)
meanVal() - Mean value and standard deviation
Definition: DMeasures.hpp:211
RES_T erode(const Image< T > &imIn, Image< T > &imOut, const StrElt &se=DEFAULT_SE, const T borderVal=ImDtTypes< T >::max())
erode() - Morphological grayscale erosion
Definition: DMorphoBase.hpp:112
RES_T dilate(const Image< T > &imIn, Image< T > &imOut, const StrElt &se=DEFAULT_SE, const T borderVal=ImDtTypes< T >::min())
dilate() - Morphological grayscale dilation
Definition: DMorphoBase.hpp:65
RES_T copy(const Image< T1 > &imIn, size_t startX, size_t startY, size_t startZ, size_t sizeX, size_t sizeY, size_t sizeZ, Image< T2 > &imOut, size_t outStartX=0, size_t outStartY=0, size_t outStartZ=0)
copy() - Copy image (or a zone) into an output image
Definition: DImageTransform.hpp:84