SMIL  0.9.1
DMorphImageOperations.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 _MORPH_IMAGE_OPERATIONS_HPP
31 #define _MORPH_IMAGE_OPERATIONS_HPP
32 
33 #include "Core/include/DCore.h"
34 #include "Morpho/include/DStructuringElement.h"
35 #include "Morpho/include/DMorphoInstance.h"
36 
37 #ifdef USE_OPEN_MP
38 #include <omp.h>
39 #endif // USE_OPEN_MP
40 
41 namespace smil
42 {
53  template <class T_in, class T_out=T_in>
55 #ifndef SWIG
56  : public imageFunctionBase<T_in>
57 #endif // SWIG
58  {
59  public:
60  typedef Image<T_in> imageInType;
61  typedef typename ImDtTypes<T_in>::lineType lineInType;
62  typedef typename ImDtTypes<T_in>::sliceType sliceInType;
63  typedef typename ImDtTypes<T_in>::volType volInType;
64 
65  typedef Image<T_out> imageOutType;
66  typedef typename ImDtTypes<T_out>::lineType lineOutType;
67  typedef typename ImDtTypes<T_out>::sliceType sliceOutType;
68  typedef typename ImDtTypes<T_out>::volType volOutType;
69 
70  MorphImageFunctionBase(T_in _borderValue = ImDtTypes<T_in>::min(), T_out _initialValue = ImDtTypes<T_out>::min())
71  : initialValue(_initialValue),
72  borderValue(_borderValue)
73  {
74  }
75 
76  virtual ~MorphImageFunctionBase()
77  {
78  }
79 
80 
81  RES_T operator()(const imageInType &imIn, imageOutType &imOut, const StrElt &se=DEFAULT_SE)
82  {
83  return this->_exec(imIn, imOut, se);
84  }
85  RES_T operator()(const imageInType &imIn, const StrElt &se=DEFAULT_SE)
86  {
87  return this->_exec(imIn, se);
88  }
89 
90  virtual RES_T initialize(const imageInType &imIn, imageOutType &imOut, const StrElt &se);
91  virtual RES_T finalize(const imageInType &imIn, imageOutType &imOut, const StrElt &se);
92  virtual RES_T _exec(const imageInType &imIn, imageOutType &imOut, const StrElt &se);
93  virtual RES_T _exec(const imageInType &imIn, const StrElt &se);
94 
95  virtual RES_T processImage(const imageInType &imIn, imageOutType &imOut, const StrElt &se);
96  virtual inline void processSlice(sliceInType linesIn, sliceOutType linesOut, size_t &lineNbr, const StrElt &se);
97  virtual inline void processLine(lineInType pixIn, lineOutType pixOut, size_t &pixNbr, const StrElt &se);
98  virtual inline void processPixel(size_t pointOffset, vector<int> &dOffsets);
99 
100  static bool isInplaceSafe(const StrElt &/*se*/) { return false; }
101 
102  const Image<T_in> *imageIn;
103  Image<T_out> *imageOut;
104 
105  protected:
106  size_t imSize[3];
107  volInType slicesIn;
108  volOutType slicesOut;
109  lineInType pixelsIn;
110  lineOutType pixelsOut;
111 
112  vector<IntPoint> sePoints;
113  UINT sePointNbr;
114  vector<int> relativeOffsets;
115 
116  int se_xmin;
117  int se_xmax;
118  int se_ymin;
119  int se_ymax;
120  int se_zmin;
121  int se_zmax;
122 
123  bool oddSe;
124  public:
125  T_out initialValue;
126  T_in borderValue;
127  };
128 
129 
130 
131 
132  template <class T_in, class lineFunction_T, class T_out=T_in, bool Enable=IS_SAME(T_in, T_out) >
133  class MorphImageFunction : public MorphImageFunctionBase<T_in, T_out>
134  {
135  public:
137 
138  typedef Image<T_in> imageInType;
139  typedef typename ImDtTypes<T_in>::lineType lineInType;
140  typedef typename ImDtTypes<T_in>::sliceType sliceInType;
141  typedef typename ImDtTypes<T_in>::volType volInType;
142 
143  typedef Image<T_out> imageOutType;
144  typedef typename ImDtTypes<T_out>::lineType lineOutType;
145  typedef typename ImDtTypes<T_out>::sliceType sliceOutType;
146  typedef typename ImDtTypes<T_out>::volType volOutType;
147 
148 
149  MorphImageFunction(T_in border=ImDtTypes<T_in>::min(), T_out initialValue = ImDtTypes<T_out>::min())
150  : MorphImageFunctionBase<T_in, T_out>(border, initialValue),
151  lineLen(0)
152  {
153  }
154 
155 
156  virtual RES_T initialize(const imageInType &imIn, imageOutType &imOut, const StrElt &se);
157  virtual RES_T finalize(const imageInType &imIn, imageOutType &imOut, const StrElt &se);
158 
159  static bool isInplaceSafe(const StrElt &se);
160 
161  protected:
162  virtual RES_T _exec(const imageInType &imIn, imageOutType &imOut, const StrElt &se);
163  virtual RES_T _exec_single(const imageInType &/*imIn*/, imageOutType &/*imOut*/, const StrElt &/*se*/) { return RES_OK; }
164 
165 
166  lineFunction_T lineFunction;
167 
168  lineInType borderBuf, cpBuf;
169  size_t lineLen;
170 
171  inline void _extract_translated_line(const Image<T_in> *imIn, const int &x, const int &y, const int &z, lineInType outBuf)
172  {
173  if (z<0 || z>=int(imIn->getDepth()) || y<0 || y>=int(imIn->getHeight()))
174  copyLine<T_in>(borderBuf, lineLen, outBuf);
175  // memcpy(outBuf, borderBuf, lineLen*sizeof(T));
176  else
177  shiftLine<T_in>(imIn->getSlices()[z][y], x, lineLen, outBuf, this->borderValue);
178  }
179 
180  inline void _exec_line(const lineInType inBuf, const Image<T_in> *imIn, const int &x, const int &y, const int &z, lineOutType outBuf)
181  {
182  _extract_translated_line(imIn, x, y, z, cpBuf);
183  lineFunction._exec(inBuf, cpBuf, lineLen, outBuf);
184  }
185 
186  inline void _exec_shifted_line(const lineInType inBuf1, const lineInType inBuf2, const int &dx, const int &lineLen, lineOutType outBuf, lineInType tmpBuf)
187  {
188  if (tmpBuf==NULL)
189  tmpBuf = cpBuf;
190  shiftLine<T_in>(inBuf2, dx, lineLen, tmpBuf, this->borderValue);
191  lineFunction._exec(inBuf1, tmpBuf, lineLen, outBuf);
192  }
193 
194  template <class T1, class T2>
195  inline void _exec_shifted_line(const typename ImDtTypes<T1>::lineType inBuf1, const typename ImDtTypes<T1>::lineType inBuf2, const int &dx, const int &lineLen, typename ImDtTypes<T2>::lineType outBuf)
196  {
197  return _exec_shifted_line(inBuf1, inBuf2, dx, lineLen, outBuf, cpBuf);
198  }
199 
200  template <class T1, class T2>
201  inline void _exec_shifted_line(const typename ImDtTypes<T1>::lineType inBuf, const int &dx, const int &lineLen, typename ImDtTypes<T2>::lineType outBuf, typename ImDtTypes<T1>::lineType tmpBuf)
202  {
203  return _exec_shifted_line(inBuf, inBuf, dx, lineLen, outBuf, tmpBuf);
204  }
205 
206  template <class T1, class T2>
207  inline void _exec_shifted_line(const typename ImDtTypes<T1>::lineType inBuf, const int &dx, const int &lineLen, typename ImDtTypes<T2>::lineType outBuf)
208  {
209  return _exec_shifted_line(inBuf, inBuf, dx, lineLen, outBuf, cpBuf);
210  }
211 
212  inline void _exec_shifted_line_2ways(lineInType inBuf1, lineInType inBuf2, const int &dx, const int &lineLen, lineOutType outBuf, lineInType tmpBuf)
213  {
214  if (tmpBuf==NULL)
215  tmpBuf = cpBuf;
216  shiftLine<T_in>(inBuf2, dx, lineLen, tmpBuf, this->borderValue);
217  lineFunction._exec(inBuf1, tmpBuf, lineLen, outBuf);
218  shiftLine<T_in>(inBuf2, -dx, lineLen, tmpBuf, this->borderValue);
219  lineFunction._exec(outBuf, tmpBuf, lineLen, outBuf);
220  }
221  inline void _exec_shifted_line_2ways(const lineInType inBuf, const int &dx, const int &lineLen, lineOutType outBuf, lineInType tmpBuf=NULL)
222  {
223  return _exec_shifted_line_2ways(inBuf, inBuf, dx, lineLen, outBuf, tmpBuf);
224  }
225  };
226 
227  template <class T_in, class lineFunction_T>
228  class MorphImageFunction<T_in, lineFunction_T, T_in, true>
229  : public MorphImageFunction<T_in, lineFunction_T, T_in, false>
230  {
231  public:
233 
234  typedef Image<T_in> imageType;
235  typedef typename ImDtTypes<T_in>::lineType lineType;
236  typedef typename ImDtTypes<T_in>::sliceType sliceType;
237  typedef typename ImDtTypes<T_in>::volType volType;
238 
239  MorphImageFunction(T_in border=ImDtTypes<T_in>::min(), T_in initialValue = ImDtTypes<T_in>::min())
240  : parentClass(border, initialValue),
241  lineFunction(parentClass::lineFunction) // take ref from parent
242  {
243  }
244 
245  lineFunction_T &lineFunction;
246 
247  virtual RES_T _exec(const imageType &imIn, imageType &imOut, const StrElt &se);
248  virtual RES_T _exec_single(const imageType &imIn, imageType &imOut, const StrElt &se);
249  virtual RES_T _exec_single_generic(const imageType &imIn, imageType &imOut, const StrElt &se); // Inplace unsafe !!
250 
251  virtual RES_T _exec_single_hexagonal_SE(const imageType &imIn, imageType &imOut); // Inplace safe
252  virtual RES_T _exec_single_square_SE(const imageType &imIn, imageType &imOut); // Inplace unsafe !!
253  virtual RES_T _exec_single_cube_SE(const imageType &imIn, imageType &imOut); // Inplace unsafe !!
254  virtual RES_T _exec_single_horizontal_2points(const imageType &imIn, int dx, imageType &imOut, bool oddLines=false); // Inplace safe
255  virtual RES_T _exec_single_vertical_2points(const imageType &imIn, int dx, imageType &imOut); // Inplace unsafe !!
256  virtual RES_T _exec_single_horizontal_segment(const imageType &imIn, int xsize, imageType &imOut); // Inplace safe
257  virtual RES_T _exec_single_vertical_segment(const imageType &imIn, imageType &imOut); // Inplace unsafe !!
258  virtual RES_T _exec_single_cross(const imageType &imIn, imageType &imOut); // Inplace unsafe !!
259  virtual RES_T _exec_single_cross_3d(const imageType &imIn, imageType &imOut);
260  virtual RES_T _exec_single_depth_segment(const imageType &imIn, int zsize, imageType &imOut); // Inplace safe
261  virtual RES_T _exec_rhombicuboctahedron(const imageType &imIn, imageType &imOut, unsigned int size); // Inplace unsafe !!
262  };
263 
266 } // namespace smil
267 
268 # endif // _MORPH_IMAGE_OPERATIONS_HPP
Definition: DBaseImageOperations.hpp:42
Definition: DColorConvert.h:38
Definition: DMorphImageOperations.hpp:133
size_t getHeight() const
Get image height.
Definition: DBaseImage.h:91
Base structuring element.
Definition: DStructuringElement.h:51
Base morpho operator class.
Definition: DMorphImageOperations.hpp:54
Definition: DTypes.hpp:78
volType getSlices() const
Get an array containing the start offset of each slice.
Definition: DImage.hpp:118
size_t getDepth() const
Get image depth (Z)
Definition: DBaseImage.h:95