SMIL  0.9.1
DMorphoGraph.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_GRAPH_HPP
31 #define _D_MORPHO_GRAPH_HPP
32 
33 #include "DMorphImageOperations.hpp"
34 #include "Core/include/private/DGraph.hpp"
35 #include "Core/include/private/DTraits.hpp"
36 
37 
38 namespace smil
39 {
46  template <class T1, class T2, class graphT=Graph<T1,T2> >
48 #ifndef SWIG
49  : public MorphImageFunctionBase<T1, T2>
50 #endif // SWIG
51  {
52  public:
54  typedef Image<T1> imageInType;
55  typedef Image<T2> imageOutType;
56 
57  typedef typename graphT::NodeType NodeType;
58  typedef typename graphT::EdgeType EdgeType;
59  typedef typename graphT::EdgeWeightType EdgeWeightType;
60  typedef typename graphT::NodeListType NodeListType;
61  typedef typename graphT::EdgeListType EdgeListType;
62 
64  {
65  internalGraph = NULL;
66  imEdgeValues = NULL;
67  imNodeValues = NULL;
68  }
69 
70  virtual ~mosaicToGraphFunct()
71  {
72  if (internalGraph)
73  delete internalGraph;
74  }
75 
76 
77  RES_T operator()(const Image<T1> &imMosaic, const Image<T2> &imEdgeValues, const Image<T2> &imNodeValues, graphT &graph, const StrElt &se=DEFAULT_SE)
78  {
79  ASSERT_ALLOCATED(&imMosaic, &imEdgeValues, &imNodeValues);
80  ASSERT_SAME_SIZE(&imMosaic, &imEdgeValues, &imNodeValues);
81 
82  this->imEdgeValues = &imEdgeValues;
83  this->imNodeValues = &imNodeValues;
84  this->graph = &graph;
85  return this->_exec(imMosaic, se);
86  }
87  const graphT &operator()(const Image<T1> &imMosaic, const Image<T2> &imEdgeValues, const Image<T2> &imNodeValues, const StrElt &se=DEFAULT_SE)
88  {
89  ASSERT( areAllocated(&imMosaic, &imEdgeValues, &imNodeValues, NULL), "Unallocated input image", *internalGraph );
90  ASSERT( haveSameSize(&imMosaic, &imEdgeValues, &imNodeValues, NULL), "Input images must have the same size", *internalGraph );
91 
92  this->imEdgeValues = &imEdgeValues;
93  this->imNodeValues = &imNodeValues;
94  this->graph = internalGraph;
95  this->_exec(imMosaic, se);
96  return *internalGraph;
97  }
98  RES_T operator()(const Image<T1> &imMosaic, const Image<T2> &imEdgeValues, graphT &graph, const StrElt &se=DEFAULT_SE)
99  {
100  ASSERT_ALLOCATED(&imMosaic, &imEdgeValues);
101  ASSERT_SAME_SIZE(&imMosaic, &imEdgeValues);
102 
103  this->imEdgeValues = &imEdgeValues;
104  this->imNodeValues = NULL;
105  this->graph = &graph;
106  return this->_exec(imMosaic, se);
107  }
108  const graphT &operator()(const Image<T1> &imMosaic, const Image<T2> &imEdgeValues, const StrElt &se=DEFAULT_SE)
109  {
110  ASSERT( areAllocated(&imMosaic, &imEdgeValues, NULL), "Unallocated input image", *internalGraph );
111  ASSERT( haveSameSize(&imMosaic, &imEdgeValues, NULL), "Input images must have the same size", *internalGraph );
112 
113  this->imEdgeValues = &imEdgeValues;
114  this->imNodeValues = NULL;
115  this->graph = internalGraph;
116  this->_exec(imMosaic, se);
117  return *internalGraph;
118  }
119  RES_T operator()(const Image<T1> &imMosaic, graphT &graph, const StrElt &se=DEFAULT_SE)
120  {
121  ASSERT_ALLOCATED(&imMosaic);
122 
123  this->imEdgeValues = NULL;
124  this->imNodeValues = NULL;
125  this->graph = &graph;
126  return this->_exec(imMosaic, se);
127  }
128  const graphT &operator()(const Image<T1> &imMosaic, const StrElt &se=DEFAULT_SE)
129  {
130  ASSERT(areAllocated(&imMosaic, NULL), "Unallocated input image", *internalGraph);
131 
132  this->imEdgeValues = NULL;
133  this->imNodeValues = NULL;
134  this->graph = internalGraph;
135  this->_exec(imMosaic, se);
136  return *internalGraph;
137  }
138 
139 
140 
141  virtual RES_T initialize(const imageInType &imIn, imageOutType &imOut, const StrElt &se)
142  {
143  ASSERT( parentClass::initialize(imIn, imOut, se)==RES_OK );
144 
145  if (graph==NULL)
146  graph = internalGraph = new graphT();
147 
148  graph->clear();
149  edges = &graph->getEdges();
150  nodes = &graph->getNodes();
151 
152  imMosaic = &imIn;
153  if (imEdgeValues)
154  edgeValuePixels = imEdgeValues->getPixels();
155  if (imNodeValues)
156  nodeValuePixels = imNodeValues->getPixels();
157 
158  return RES_OK;
159  }
160 
161  virtual RES_T finalize(const imageInType &imIn, imageOutType &imOut, const StrElt &se)
162  {
163  return parentClass::finalize(imIn, imOut, se);
164  }
165 
166  virtual inline void processPixel(size_t pointOffset, vector<int> &dOffsetList)
167  {
168  T1 curVal = parentClass::pixelsIn[pointOffset];
169  vector<int>::iterator dOffset = dOffsetList.begin();
170 
171  while(dOffset!=dOffsetList.end())
172  {
173  T1 val = parentClass::pixelsIn[pointOffset + *dOffset];
174  if (val!=curVal)
175  {
176  int edgeInd = graph->findEdge(curVal, val);
177 
178  // If the edge already exists, take the min weight value between the existing and the new one (pixelsOut[pointOffset]).
179  if (edgeInd!=-1 && imEdgeValues)
180  {
181  EdgeType &edge = edges->at(edgeInd);
182  edge.weight = min(edge.weight, EdgeWeightType(edgeValuePixels[pointOffset]));
183  }
184  else
185  {
186  if (imNodeValues)
187  {
188  graph->addNode(curVal, nodeValuePixels[pointOffset]);
189  graph->addNode(val, nodeValuePixels[pointOffset + *dOffset]);
190  }
191  if (imEdgeValues)
192  graph->addEdge(curVal, val, edgeValuePixels[pointOffset], false); // false means don't check if the edge exists
193  else
194  graph->addEdge(curVal, val, 0, false);
195  }
196  }
197  dOffset++;
198  }
199  }
200  protected:
201  graphT *internalGraph;
202  typename ImDtTypes<T2>::lineType edgeValuePixels;
203  typename ImDtTypes<T2>::lineType nodeValuePixels;
204 
205  NodeListType *nodes;
206  EdgeListType *edges;
207 
208  public:
209  graphT *graph;
210  const Image<T1> *imMosaic;
211  const Image<T2> *imEdgeValues;
212  const Image<T2> *imNodeValues;
213  };
214 
215  // Generic functions
216  template <class T1, class T2, class GT1, class GT2>
217  RES_T mosaicToGraph(const Image<T1> &imMosaic, const Image<T2> &imEdgeValues, const Image<T2> &imNodeValues, Graph<GT1,GT2> &graph, const StrElt &se=DEFAULT_SE)
218  {
219  typedef Graph<GT1,GT2> graphT;
221 
222  return f(imMosaic, imEdgeValues, imNodeValues, graph, se);
223  }
224  template <class T1, class T2>
225  Graph<T1,T2> mosaicToGraph(const Image<T1> &imMosaic, const Image<T2> &imEdgeValues, const Image<T2> &imNodeValues, const StrElt &se=DEFAULT_SE)
226  {
227  typedef Graph<T1,T2> graphT;
229 
230  return f(imMosaic, imEdgeValues, imNodeValues, se);
231  }
232  template <class T1, class T2, class GT1, class GT2>
233  RES_T mosaicToGraph(const Image<T1> &imMosaic, const Image<T2> &imEdgeValues, Graph<GT1,GT2> &graph, const StrElt &se=DEFAULT_SE)
234  {
235  typedef Graph<GT1,GT2> graphT;
237 
238  return f(imMosaic, imEdgeValues, graph, se);
239  }
240  template <class T1, class T2>
241  Graph<T1,T2> mosaicToGraph(const Image<T1> &imMosaic, const Image<T2> &imEdgeValues, const StrElt &se=DEFAULT_SE)
242  {
243  typedef Graph<T1,T2> graphT;
245 
246  return f(imMosaic, imEdgeValues, se);
247  }
248  template <class T1, class GT1, class GT2>
249  RES_T mosaicToGraph(const Image<T1> &imMosaic, Graph<GT1,GT2> &graph, const StrElt &se=DEFAULT_SE)
250  {
251  typedef Graph<GT1,GT2> graphT;
253 
254  return f(imMosaic, graph, se);
255  }
256  template <class T1>
257  Graph<T1,UINT> mosaicToGraph(const Image<T1> &imMosaic, const StrElt &se=DEFAULT_SE)
258  {
259  typedef Graph<T1,UINT> graphT;
261 
262  return f(imMosaic, se);
263  }
264 
265 
266 
267 
268 
269 
270 #ifndef SWIG
271  template <class T1>
272  ENABLE_IF( !IS_SAME(T1,size_t), RES_T ) // SFINAE Only if T1!=size_t && T2!=size_t
273  mosaicToGraph(const Image<T1> &imMosaic, Graph<> &graph, const StrElt &se=DEFAULT_SE)
274  {
275  return mosaicToGraph<T1, size_t, size_t>(imMosaic, graph, se);
276  }
277  template <class T1, class T2>
278  ENABLE_IF( !IS_SAME(T1,size_t) && !IS_SAME(T2,size_t), RES_T ) // SFINAE Only if T1!=size_t && T2!=size_t
279  mosaicToGraph(const Image<T1> &imMosaic, const Image<T2> &imEdgeValues, Graph<> &graph, const StrElt &se=DEFAULT_SE)
280  {
281  return mosaicToGraph<T1, T2, size_t, size_t>(imMosaic, imEdgeValues, graph, se);
282  }
283  template <class T1, class T2>
284  ENABLE_IF( !IS_SAME(T1,size_t) && !IS_SAME(T2,size_t), RES_T ) // SFINAE Only if T1!=size_t && T2!=size_t
285  mosaicToGraph(const Image<T1> &imMosaic, const Image<T2> &imEdgeValues, const Image<T2> &imNodeValues, Graph<> &graph, const StrElt &se=DEFAULT_SE)
286  {
287  return mosaicToGraph<T1, T2, size_t, size_t>(imMosaic, imEdgeValues, imNodeValues, graph, se);
288  }
289 
290 #ifdef USE_64BIT_IDS
291  template <class T1>
292  ENABLE_IF( !IS_SAME(T1,UINT), RES_T ) // SFINAE Only if T1!=UINT
293  mosaicToGraph(const Image<T1> &imMosaic, Graph<UINT,UINT> &graph, const StrElt &se=DEFAULT_SE)
294  {
295  return mosaicToGraph<T1, UINT,UINT>(imMosaic, graph, se);
296  }
297 #endif // USE_64BIT_IDS
298  template <class T1, class T2>
299  ENABLE_IF( !IS_SAME(T1,UINT), RES_T ) // SFINAE Only if T1!=UINT
300  mosaicToGraph(const Image<T1> &imMosaic, const Image<T2> &imEdgeValues, Graph<UINT,T2> &graph, const StrElt &se=DEFAULT_SE)
301  {
302  return mosaicToGraph<T1, T2, UINT,T2>(imMosaic, imEdgeValues, graph, se);
303  }
304  template <class T1, class T2>
305  ENABLE_IF( !IS_SAME(T1,UINT), RES_T ) // SFINAE Only if T1!=UINT
306  mosaicToGraph(const Image<T1> &imMosaic, const Image<T2> &imEdgeValues, const Image<T2> &imNodeValues, Graph<UINT,T2> &graph, const StrElt &se=DEFAULT_SE)
307  {
308  return mosaicToGraph<T1, T2, UINT,T2>(imMosaic, imEdgeValues, imNodeValues, graph, se);
309  }
310 
311  template <class T1, class T2>
312  ENABLE_IF( !IS_SAME(T2,UINT), RES_T ) // SFINAE Only if T2!=UINT
313  mosaicToGraph(const Image<T1> &imMosaic, const Image<T2> &imEdgeValues, Graph<T1,UINT> &graph, const StrElt &se=DEFAULT_SE)
314  {
315  return mosaicToGraph<T1, T2, T1,UINT>(imMosaic, imEdgeValues, graph, se);
316  }
317  template <class T1, class T2>
318  ENABLE_IF( !IS_SAME(T2,UINT), RES_T ) // SFINAE Only if T2!=UINT
319  mosaicToGraph(const Image<T1> &imMosaic, const Image<T2> &imEdgeValues, const Image<T2> &imNodeValues, Graph<T1,UINT> &graph, const StrElt &se=DEFAULT_SE)
320  {
321  return mosaicToGraph<T1, T2, T1,UINT>(imMosaic, imEdgeValues, imNodeValues, graph, se);
322  }
323 #else // SWIG
324  template <class T1>
325  RES_T mosaicToGraph(const Image<T1> &imMosaic, Graph<T1,T1> &graph, const StrElt &se=DEFAULT_SE);
326  template <class T1, class T2>
327  RES_T mosaicToGraph(const Image<T1> &imMosaic, const Image<T2> &imEdgeValues, Graph<T1,T2> &graph, const StrElt &se=DEFAULT_SE);
328 
329  template <class T1>
330  RES_T mosaicToGraph(const Image<T1> &imMosaic, Graph<> &graph, const StrElt &se=DEFAULT_SE);
331  template <class T1, class T2>
332  RES_T mosaicToGraph(const Image<T1> &imMosaic, const Image<T2> &imEdgeValues, Graph<> &graph, const StrElt &se=DEFAULT_SE);
333  template <class T1, class T2>
334  RES_T mosaicToGraph(const Image<T1> &imMosaic, const Image<T2> &imEdgeValues, const Image<T2> &imNodeValues, Graph<> &graph, const StrElt &se=DEFAULT_SE);
335 
336  template <class T1>
337  RES_T mosaicToGraph(const Image<T1> &imMosaic, Graph<UINT,UINT> &graph, const StrElt &se=DEFAULT_SE);
338  template <class T1, class T2>
339  RES_T mosaicToGraph(const Image<T1> &imMosaic, const Image<T2> &imEdgeValues, Graph<UINT,T2> &graph, const StrElt &se=DEFAULT_SE);
340  template <class T1, class T2>
341  RES_T mosaicToGraph(const Image<T1> &imMosaic, const Image<T2> &imEdgeValues, const Image<T2> &imNodeValues, Graph<UINT,T2> &graph, const StrElt &se=DEFAULT_SE);
342 
343  template <class T1, class T2>
344  RES_T mosaicToGraph(const Image<T1> &imMosaic, const Image<T2> &imEdgeValues, Graph<T1,UINT> &graph, const StrElt &se=DEFAULT_SE);
345  template <class T1, class T2>
346  RES_T mosaicToGraph(const Image<T1> &imMosaic, const Image<T2> &imEdgeValues, const Image<T2> &imNodeValues, Graph<T1,UINT> &graph, const StrElt &se=DEFAULT_SE);
347 #endif // SWIG
348 
349 
350 
351 
352  template <class T, class graphT>
353  RES_T graphToMosaic(const Image<T> &imMosRef, const graphT &graph, Image<T> &imOut)
354  {
355  ASSERT_ALLOCATED(&imOut);
356 
357  typedef typename graphT::NodeType NodeType;
358  map<NodeType,NodeType> nodeMap = graph.labelizeNodes();
359  map<T,T> lut(nodeMap.begin(), nodeMap.end());
360 
361  return applyLookup(imMosRef, lut, imOut);
362  }
363 
364  template <class T>
365  RES_T graphToMosaic(const Image<T> &imMosRef, const Graph<T, T> &graph, Image<T> &imOut)
366  {
367  return graphToMosaic< T, Graph<T,T> >(imMosRef, graph, imOut);
368  }
369 
370 #ifndef SWIG
371  template <class T>
372  ENABLE_IF( !IS_SAME(T,UINT), RES_T ) // SFINAE Only if T!=UINT
373  graphToMosaic(const Image<T> &imMosRef, const Graph<UINT, T> &graph, Image<T> &imOut)
374  {
375  return graphToMosaic< T, Graph<UINT,T> >(imMosRef, graph, imOut);
376  }
377 
378  template <class T>
379  ENABLE_IF( !IS_SAME(T,UINT), RES_T ) // SFINAE Only if T!=UINT
380  graphToMosaic(const Image<T> &imMosRef, const Graph<T, UINT> &graph, Image<T> &imOut)
381  {
382  return graphToMosaic< T, Graph<T,UINT> >(imMosRef, graph, imOut);
383  }
384 
385  template <class T>
386  ENABLE_IF( !IS_SAME(T,size_t), RES_T ) // SFINAE Only if T!=size_t
387  graphToMosaic(const Image<T> &imMosRef, const Graph<> &graph, Image<T> &imOut)
388  {
389  return graphToMosaic< T, Graph<> >(imMosRef, graph, imOut);
390  }
391 #else // SWIG
392  template <class T>
393  RES_T graphToMosaic(const Image<T> &imMosRef, const Graph<UINT, T> &graph, Image<T> &imOut);
394 
395  template <class T>
396  RES_T graphToMosaic(const Image<T> &imMosRef, const Graph<T, UINT> &graph, Image<T> &imOut);
397 
398  template <class T>
399  RES_T graphToMosaic(const Image<T> &imMosRef, const Graph<> &graph, Image<T> &imOut);
400 #endif // SWIG
401 
402 
403  template <class mosImT, class graphT, class imOutT>
404  RES_T drawGraph(const Image<mosImT> &imMosaic, const graphT &graph, Image<imOutT> &imOut, imOutT linesValue=ImDtTypes<imOutT>::max())
405  {
406  ASSERT_ALLOCATED(&imMosaic, &imOut);
407  ASSERT_SAME_SIZE(&imMosaic, &imOut);
408 
409  ImageFreezer freeze(imOut);
410 
411  map<mosImT, vector<double> > barys = measBarycenters(imMosaic);
412 
413  typedef typename graphT::EdgeType EdgeType;
414  typedef const vector< EdgeType > EdgeListType;
415  EdgeListType &edges = graph.getEdges();
416 
417  for(typename EdgeListType::const_iterator it=edges.begin();it!=edges.end();it++)
418  {
419  const EdgeType &edge = *it;
420 
421  if (edge.source==edge.target)
422  continue;
423 
424  vector<double> &p1 = barys[edge.source];
425  vector<double> &p2 = barys[edge.target];
426 
427  if (p1.empty() || p2.empty())
428  continue;
429 
430  ASSERT(drawLine(imOut, int(p1[0]), int(p1[1]), int(p2[0]), int(p2[1]), linesValue)==RES_OK);
431  }
432 
433  return RES_OK;
434  }
435 
436  template <class mosImT, class imOutT>
437  RES_T drawGraph(const Image<mosImT> &imMosaic, const Graph<mosImT,imOutT> &graph, Image<imOutT> &imOut, imOutT linesValue=ImDtTypes<imOutT>::max())
438  {
439  return drawGraph<mosImT, Graph<mosImT,imOutT>, imOutT >(imMosaic, graph, imOut, linesValue);
440  }
441 
442 #ifndef SWIG
443  template <class mosImT, class imOutT>
444  ENABLE_IF( !IS_SAME(mosImT,size_t) && !IS_SAME(imOutT,size_t), RES_T ) // SFINAE Only if mosImT!=size_t && imOutT!=size_t
445  drawGraph(const Image<mosImT> &imMosaic, const Graph<> &graph, Image<imOutT> &imOut, imOutT linesValue=ImDtTypes<imOutT>::max())
446  {
447  return drawGraph<mosImT, Graph<>, imOutT>(imMosaic, graph, imOut, linesValue);
448  }
449 
450  template <class mosImT, class imOutT>
451  ENABLE_IF( !IS_SAME(mosImT,UINT), RES_T ) // SFINAE Only if mosImT!=UINT
452  drawGraph(const Image<mosImT> &imMosaic, const Graph<UINT,imOutT> &graph, Image<imOutT> &imOut, imOutT linesValue=ImDtTypes<imOutT>::max())
453  {
454  return drawGraph<mosImT, Graph<UINT,imOutT>, imOutT >(imMosaic, graph, imOut, linesValue);
455  }
456 
457  template <class mosImT, class imOutT>
458  ENABLE_IF( !IS_SAME(imOutT,UINT), RES_T ) // SFINAE Only if imOutT!=UINT
459  drawGraph(const Image<mosImT> &imMosaic, const Graph<mosImT,UINT> &graph, Image<imOutT> &imOut, imOutT linesValue=ImDtTypes<imOutT>::max())
460  {
461  return drawGraph<mosImT, Graph<mosImT,UINT>, imOutT >(imMosaic, graph, imOut, linesValue);
462  }
463 #else //SWIG
464  template <class mosImT, class imOutT>
465  RES_T drawGraph(const Image<mosImT> &imMosaic, const Graph<> &graph, Image<imOutT> &imOut, imOutT linesValue=ImDtTypes<imOutT>::max());
466 
467  template <class mosImT, class imOutT>
468  RES_T drawGraph(const Image<mosImT> &imMosaic, const Graph<UINT,imOutT> &graph, Image<imOutT> &imOut, imOutT linesValue=ImDtTypes<imOutT>::max());
469 
470  template <class mosImT, class imOutT>
471  RES_T drawGraph(const Image<mosImT> &imMosaic, const Graph<mosImT,UINT> &graph, Image<imOutT> &imOut, imOutT linesValue=ImDtTypes<imOutT>::max());
472 #endif //SWIG
473 
474 
477 } // namespace smil
478 
479 
480 
481 #endif // _D_MORPHO_GRAPH_HPP
482 
RES_T drawLine(Image< T > &im, int x0, int y0, int x1, int y1, T value=ImDtTypes< T >::max())
Draws a line between two points P0(x0,y0) and P1(x1,y1).
Definition: DImageDraw.hpp:61
Definition: DColorConvert.h:38
map< T, Vector_double > measBarycenters(const Image< T > &imLbl, const bool onlyNonZero=true)
Measure barycenter of a labeled image.
Definition: DBlobMeasures.hpp:159
Definition: DBaseImage.h:235
Non-oriented graph.
Definition: DGraph.hpp:144
lineType getPixels() const
Get the pixels as a 1D array.
Definition: DImage.hpp:110
Base structuring element.
Definition: DStructuringElement.h:51
Base morpho operator class.
Definition: DMorphImageOperations.hpp:54
Definition: DTypes.hpp:78
RES_T applyLookup(const Image< T1 > &imIn, const mapT &_map, Image< T2 > &imOut, T2 defaultValue=T2(0))
Apply a lookup map.
Definition: DImageArith.hpp:1092
Definition: DMorphoGraph.hpp:47