SMIL  0.9.1
DMorphoExtrema.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'' AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 
30 #ifndef _D_MORPHO_EXTREMA_HPP
31 #define _D_MORPHO_EXTREMA_HPP
32 
33 #include "DMorphoGeodesic.hpp"
34 #include "DMorphoArrow.hpp"
35 
36 namespace smil
37 {
44  // Extrema
45 
46 
50  template <class T>
51  RES_T minima(const Image<T> &imIn, Image<T> &imOut, const StrElt &se=DEFAULT_SE)
52  {
53  ASSERT_ALLOCATED(&imIn, &imOut);
54  ASSERT_SAME_SIZE(&imIn, &imOut);
55 
56  if (&imIn==&imOut)
57  {
58  Image<T> tmpIm(imIn);
59  return minima(tmpIm, imOut, se);
60  }
61 
62  ImageFreezer freeze(imOut);
63 
64  ASSERT((add(imIn, T(1), imOut)==RES_OK));
65  ASSERT((dualBuild(imOut, imIn, imOut, se)==RES_OK));
66  ASSERT((low(imIn, imOut, imOut)==RES_OK));
67 
68  return RES_OK;
69  }
70 
74  template <class T>
75  RES_T maxima(const Image<T> &imIn, Image<T> &imOut, const StrElt &se=DEFAULT_SE)
76  {
77  ASSERT_ALLOCATED(&imIn, &imOut);
78  ASSERT_SAME_SIZE(&imIn, &imOut);
79 
80  if (&imIn==&imOut)
81  {
82  Image<T> tmpIm(imIn);
83  return maxima(tmpIm, imOut, se);
84  }
85 
86  ImageFreezer freeze(imOut);
87 
88  ASSERT((sub(imIn, T(1), imOut)==RES_OK));
89  ASSERT((build(imOut, imIn, imOut, se)==RES_OK));
90  ASSERT((grt(imIn, imOut, imOut)==RES_OK));
91 
92  return RES_OK;
93  }
94 
98  template <class T1, class T2>
99  RES_T minimaLabeled(const Image<T1> &imIn, Image<T2> &imOut, const StrElt &se=DEFAULT_SE)
100  {
101  ASSERT_ALLOCATED(&imIn, &imOut);
102  ASSERT_SAME_SIZE(&imIn, &imOut);
103 
104  ImageFreezer freeze(imOut);
105 
106  Image<T1> imMinima(imIn);
107  minima(imIn, imMinima, se);
108  label(imMinima, imOut, se);
109 
110  return RES_OK;
111  }
112 
116  template <class T1, class T2>
117  RES_T maximaLabeled(const Image<T1> &imIn, Image<T2> &imOut, const StrElt &se=DEFAULT_SE)
118  {
119  ASSERT_ALLOCATED(&imIn, &imOut);
120  ASSERT_SAME_SIZE(&imIn, &imOut);
121 
122  ImageFreezer freeze(imOut);
123 
124  Image<T1> imMaxima(imIn);
125  maxima(imIn, imMaxima, se);
126  label(imMaxima, imOut, se);
127 
128  return RES_OK;
129  }
130 
134  template <class T>
135  RES_T hMinima(const Image<T> &imIn, const T &height, Image<T> &imOut, const StrElt &se=DEFAULT_SE)
136  {
137  ASSERT_ALLOCATED(&imIn, &imOut);
138  ASSERT_SAME_SIZE(&imIn, &imOut);
139 
140  ImageFreezer freeze(imOut);
141 
142  Image<T> tmpIm(imIn);
143 
144  ASSERT(hDualBuild(imIn, height, tmpIm, se)==RES_OK);
145  ASSERT(minima(tmpIm, imOut, se)==RES_OK);
146 
147  return RES_OK;
148  }
149 
153  template <class T1, class T2>
154  RES_T hMinimaLabeled(const Image<T1> &imIn, const T1 &height, Image<T2> &imOut, const StrElt &se=DEFAULT_SE)
155  {
156  ASSERT_ALLOCATED(&imIn, &imOut);
157  ASSERT_SAME_SIZE(&imIn, &imOut);
158 
159  ImageFreezer freeze(imOut);
160 
161  Image<T1> imMinima(imIn);
162  hMinima(imIn, height, imMinima, se);
163  label(imMinima, imOut, se);
164 
165  return RES_OK;
166  }
167 
171  template <class T>
172  RES_T hMaxima(const Image<T> &imIn, const T &height, Image<T> &imOut, const StrElt &se=DEFAULT_SE)
173  {
174  ASSERT_ALLOCATED(&imIn, &imOut);
175  ASSERT_SAME_SIZE(&imIn, &imOut);
176 
177  Image<T> tmpIm(imIn);
178 
179  ImageFreezer freeze(imOut);
180 
181  ASSERT(hBuild(imIn, height, tmpIm, se)==RES_OK);
182  ASSERT(maxima(tmpIm, imOut, se)==RES_OK);
183 
184  return RES_OK;
185  }
186 
190  template <class T1, class T2>
191  RES_T hMaximaLabeled(const Image<T1> &imIn, const T1 &height, Image<T2> &imOut, const StrElt &se=DEFAULT_SE)
192  {
193  ASSERT_ALLOCATED(&imIn, &imOut);
194  ASSERT_SAME_SIZE(&imIn, &imOut);
195 
196  ImageFreezer freeze(imOut);
197 
198  Image<T1> imMaxima(imIn);
199  hMaxima(imIn, height, imMaxima, se);
200  label(imMaxima, imOut, se);
201 
202  return RES_OK;
203  }
204 
205  template <class T>
206  RES_T fastExtrema (const Image<T> &imIn, Image<T> &imOut, const StrElt &se, const char *operation, const T& border_value) {
207 
208  // Typedefs
209  // typedef Image<T> inT;
210  typedef Image<T> outT;
211  typedef Image<T> arrowT;
212  typedef typename outT::lineType outLineT;
213  typedef typename arrowT::lineType arrowLineT;
214  // typedef typename inT::volType inVolT;
215  typedef typename outT::volType outVolT;
216  typedef typename arrowT::volType arrowVolT;
217 
218  // Initialisation.
219  arrowT arrows(imIn);
220  StrElt cpSe = se.noCenter();
221  fill(imOut, T(0));
222 
223  // Processing vars.
224  size_t size[3]; imIn.getSize(size);
225  UINT sePtsNumber = cpSe.points.size();
226  if (sePtsNumber == 0) return RES_OK;
227  // Images related.
228  // inVolT inSlices = imIn.getSlices();
229  outVolT outSlices = imOut.getSlices();
230  arrowVolT arrowSlices = arrows.getSlices();
231  outLineT* outLines;
232  arrowLineT* arrowLines;
233  outLineT outP = imOut.getPixels();
234  arrowLineT arrowP = arrows.getPixels();
235  // Buffers.
236  arrowLineT cstBuf = ImDtTypes<T>::createLine(size[0]);
237  fillLine<T>(cstBuf, size[0], T(0));
238  outLineT cstBuf2 = ImDtTypes<T>::createLine(size[0]);
239  fillLine<T>(cstBuf2, size[0], ImDtTypes<T>::max());
240 
241  equLine<T> equOp;
242  rightShiftLine<T> shiftOp;
243  testLine<T, T> testOp;
244 
245  // Storing steep in imOut.
246  #ifdef USE_OPEN_MP
247  #pragma omp parallel
248  #endif // USE_OPEN_MP
249  {
250  size_t offset;
251  arrowPropagate <T, T, T> funcPropagation;
252  funcPropagation.propagationValue = T(1);
253 
254  // Storing greater in out.
255  arrow (imIn, operation, arrows, cpSe, border_value);
256 
257  for (size_t s=0; s<size[2]; ++s)
258  {
259  arrowLines = arrowSlices[s];
260  outLines = outSlices[s];
261 
262  #ifdef USE_OPEN_MP
263  #pragma omp for
264  #endif // USE_OPEN_MP
265  for (size_t l=0; l<size[1]; ++l)
266  {
267  equOp._exec(arrowLines[l], cstBuf, size[0], outLines[l]);
268  }
269  }
270 
271  // Detecting plateaus and 1-pixel minimas.
272  arrowEqu (imIn, arrows, cpSe);
273  for (size_t s=0; s<size[2]; ++s)
274  {
275  #ifdef USE_OPEN_MP
276  #pragma omp for
277  #endif // USE_OPEN_MP
278  for (size_t l=0; l<size[1]; ++l)
279  {
280  for (size_t p=0; p<size[0]; ++p)
281  {
282  offset = p+l*size[0]+s*size[1]*size[0];
283  if (outP[offset] == 0 && arrowP[offset] > 0)
284  {
285  funcPropagation (arrows, imOut, cpSe, offset);
286  }
287  }
288  }
289  }
290  // Values of minimas back to max value.
291  for (size_t s=0; s<size[2]; ++s)
292  {
293  outLines = outSlices[s];
294  #ifdef USE_OPEN_MP
295  #pragma omp for
296  #endif // USE_OPEN_MP
297  for (size_t l=0; l<size[1]; ++l)
298  {
299  shiftOp._exec (outLines[l], 1, size[0], outLines[l]) ;
300  testOp._exec (outLines[l], cstBuf2, outLines[l], size[0], outLines[l]) ;
301  }
302  }
303 
304  }
305 
306  return RES_OK ;
307  }
308 
312  template <class T>
313  inline RES_T fastMinima (const Image<T> &imIn, Image<T> &imOut, const StrElt &se)
314  {
315  return fastExtrema (imIn, imOut, se, ">", numeric_limits<T>::max()) ;
316  }
317 
321  template <class T>
322  inline RES_T fastMaxima (const Image<T> &imIn, Image<T> &imOut, const StrElt &se)
323  {
324  return fastExtrema (imIn, imOut, se, "<", numeric_limits<T>::min()) ;
325  }
326 
329 } // namespace smil
330 
331 
332 #endif // _D_MORPHO_EXTREMA_HPP
333 
RES_T build(const Image< T > &imIn, const Image< T > &imMask, Image< T > &imOut, const StrElt &se=DEFAULT_SE)
Reconstruction (using hierarchical queues).
Definition: DMorphoGeodesic.hpp:326
RES_T minimaLabeled(const Image< T1 > &imIn, Image< T2 > &imOut, const StrElt &se=DEFAULT_SE)
Calculate the minima and labelize them.
Definition: DMorphoExtrema.hpp:99
RES_T minima(const Image< T > &imIn, Image< T > &imOut, const StrElt &se=DEFAULT_SE)
Minima.
Definition: DMorphoExtrema.hpp:51
RES_T fastMaxima(const Image< T > &imIn, Image< T > &imOut, const StrElt &se)
Regional maxima computation based on arrowing graphs.
Definition: DMorphoExtrema.hpp:322
Definition: DColorConvert.h:38
RES_T sub(const Image< T > &imIn1, const Image< T > &imIn2, Image< T > &imOut)
Subtraction.
Definition: DImageArith.hpp:446
Definition: DLineArith.hpp:545
RES_T grt(const Image< T > &imIn1, const Image< T > &imIn2, Image< T > &imOut)
Greater operator.
Definition: DImageArith.hpp:650
Definition: DBaseImage.h:235
vector< IntPoint > points
List of neighbor points.
Definition: DStructuringElement.h:125
lineType getPixels() const
Get the pixels as a 1D array.
Definition: DImage.hpp:110
RES_T hDualBuild(const Image< T > &imIn, const T &height, Image< T > &imOut, const StrElt &se=DEFAULT_SE)
Dual h-Reconstuction.
Definition: DMorphoGeodesic.hpp:445
RES_T fill(Image< T > &imOut, const T &value)
Fill an image with a given value.
Definition: DImageArith.hpp:62
RES_T add(const Image< T > &imIn1, const Image< T > &imIn2, Image< T > &imOut)
Addition.
Definition: DImageArith.hpp:393
RES_T arrow(const Image< T_in > &imIn, const char *operation, Image< T_out > &imOut, const StrElt &se=DEFAULT_SE, T_in borderValue=numeric_limits< T_in >::min())
Arrow operator.
Definition: DMorphoArrow.hpp:206
RES_T maximaLabeled(const Image< T1 > &imIn, Image< T2 > &imOut, const StrElt &se=DEFAULT_SE)
Calculate the maxima and labelize them.
Definition: DMorphoExtrema.hpp:117
RES_T maxima(const Image< T > &imIn, Image< T > &imOut, const StrElt &se=DEFAULT_SE)
Maxima.
Definition: DMorphoExtrema.hpp:75
Definition: DBaseImageOperations.hxx:39
RES_T low(const Image< T > &imIn1, const Image< T > &imIn2, Image< T > &imOut)
Lower operator.
Definition: DImageArith.hpp:692
RES_T hBuild(const Image< T > &imIn, const T &height, Image< T > &imOut, const StrElt &se=DEFAULT_SE)
Reconstruction (using hierarchical queues).
Definition: DMorphoGeodesic.hpp:420
Base structuring element.
Definition: DStructuringElement.h:51
RES_T fastMinima(const Image< T > &imIn, Image< T > &imOut, const StrElt &se)
Regional minima computation based on arrowing graphs.
Definition: DMorphoExtrema.hpp:313
Propagation Functor on a Arrow Image.
Definition: DMorphoArrow.hpp:227
size_t label(const Image< T1 > &imIn, Image< T2 > &imOut, const StrElt &se=DEFAULT_SE)
Image labelization.
Definition: DMorphoLabel.hpp:503
RES_T hMinimaLabeled(const Image< T1 > &imIn, const T1 &height, Image< T2 > &imOut, const StrElt &se=DEFAULT_SE)
Calculate the h-minima and labelize them.
Definition: DMorphoExtrema.hpp:154
RES_T hMaxima(const Image< T > &imIn, const T &height, Image< T > &imOut, const StrElt &se=DEFAULT_SE)
h-Maxima
Definition: DMorphoExtrema.hpp:172
Definition: DTypes.hpp:78
RES_T dualBuild(const Image< T > &imIn, const Image< T > &imMask, Image< T > &imOut, const StrElt &se=DEFAULT_SE)
Dual reconstruction (using hierarchical queues).
Definition: DMorphoGeodesic.hpp:296
Definition: DLineArith.hpp:558
Main Image class.
Definition: DQVtkViewer.hpp:44
Definition: DLineArith.hpp:337
StrElt noCenter() const
Return the SE with no center.
Definition: DStructuringElement.cpp:127
RES_T hMinima(const Image< T > &imIn, const T &height, Image< T > &imOut, const StrElt &se=DEFAULT_SE)
h-Minima
Definition: DMorphoExtrema.hpp:135
RES_T hMaximaLabeled(const Image< T1 > &imIn, const T1 &height, Image< T2 > &imOut, const StrElt &se=DEFAULT_SE)
Calculate the h-maxima and labelize them.
Definition: DMorphoExtrema.hpp:191
volType getSlices() const
Get an array containing the start offset of each slice.
Definition: DImage.hpp:118