Fawkes API  Fawkes Development Version
geodesic_erosion.cpp
1 
2 /***************************************************************************
3  * geodesic_erosion.cpp - implementation of morphological geodesic erosion
4  *
5  * Created: Sat Jun 10 16:21:30 2006
6  * Copyright 2005-2007 Tim Niemueller [www.niemueller.de]
7  *
8  ****************************************************************************/
9 
10 /* This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version. A runtime exception applies to
14  * this software (see LICENSE.GPL_WRE file mentioned below for details).
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU Library General Public License for more details.
20  *
21  * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
22  */
23 
24 #include <core/exception.h>
25 #include <fvfilters/max.h>
26 #include <fvfilters/morphology/erosion.h>
27 #include <fvfilters/morphology/geodesic_erosion.h>
28 #include <fvfilters/morphology/segenerator.h>
29 #include <fvutils/color/colorspaces.h>
30 #include <fvutils/statistical/imagediff.h>
31 
32 #include <cstdlib>
33 #include <cstring>
34 
35 namespace firevision {
36 
37 /** Marker */
38 const unsigned int FilterGeodesicErosion::MARKER = 0;
39 /** Mask */
40 const unsigned int FilterGeodesicErosion::MASK = 1;
41 
42 #define ERROR(m) \
43  { \
44  fawkes::Exception e("FilterGeodesicErosion failed"); \
45  e.append("Function: %s", __FUNCTION__); \
46  e.append("Message: %s", m); \
47  throw e; \
48  }
49 
50 /** @class FilterGeodesicErosion <fvfilters/morphology/geodesic_erosion.h>
51  * Morphological geodesic erosion.
52  * @author Tim Niemueller
53  */
54 
55 /** Constructor.
56  * @param se_size Structuring element size.
57  */
59 : MorphologicalFilter("Morphological Geodesic Erosion")
60 {
61  this->se_size = (se_size > 0) ? se_size : 1;
62  iterations = 0;
63 
64  erode = new FilterErosion();
65  max = new FilterMax();
66  diff = new ImageDiff();
67 
68  isotropic_se = SEGenerator::square(this->se_size, this->se_size);
69 
70  erode->set_structuring_element(isotropic_se, se_size, se_size, se_size / 2, se_size / 2);
71 }
72 
73 /** Destructor. */
75 {
76  delete erode;
77  delete max;
78  delete diff;
79  free(isotropic_se);
80 }
81 
82 void
84 {
85  if (dst == NULL)
86  ERROR("dst == NULL");
87  if (src[MASK] == NULL)
88  ERROR("src[MASK] == NULL");
89  if (src[MARKER] == NULL)
90  ERROR("src[MARKER] == NULL");
91  if (*(src_roi[MASK]) != *(src_roi[MARKER]))
92  ERROR("marker and mask ROI differ");
93 
94  unsigned char *tmp =
95  (unsigned char *)malloc(colorspace_buffer_size(YUV422_PLANAR,
96  src_roi[MARKER]->image_width,
97  src_roi[MARKER]->image_height));
98  memcpy(tmp,
99  src[MARKER],
100  colorspace_buffer_size(YUV422_PLANAR,
101  src_roi[MARKER]->image_width,
102  src_roi[MARKER]->image_height));
103 
104  diff->setBufferA(tmp, src_roi[MARKER]->image_width, src_roi[MARKER]->image_height);
106 
107  erode->set_src_buffer(tmp, src_roi[MARKER]);
108 
109  max->set_src_buffer(src[MASK], src_roi[MASK], 0);
110  max->set_src_buffer(tmp, src_roi[MARKER], 1);
111  max->set_dst_buffer(tmp, src_roi[MARKER]);
112 
113  iterations = 0;
114  do {
115  memcpy(dst,
116  tmp,
117  colorspace_buffer_size(YUV422_PLANAR, dst_roi->image_width, dst_roi->image_height));
118  erode->apply();
119  max->apply();
120  } while (diff->different() && (++iterations < 255));
121 
122  // std::cout << i << " iterations done for geodesic erosion" << std::endl;
123 
124  free(tmp);
125 }
126 
127 /** Get the number of iterations.
128  * @return the number of iterations that were necessary to get a stable result in the
129  * last call to apply().
130  */
131 unsigned int
133 {
134  return iterations;
135 }
136 
137 } // end namespace firevision
Morphological erosion.
Definition: erosion.h:31
virtual void apply()
Apply the filter.
Definition: erosion.cpp:51
FilterGeodesicErosion(unsigned int se_size=3)
Constructor.
virtual unsigned int num_iterations()
Get the number of iterations.
virtual void apply()
Apply the filter.
static const unsigned int MARKER
Marker.
virtual ~FilterGeodesicErosion()
Destructor.
static const unsigned int MASK
Mask.
Maximum filter.
Definition: max.h:32
virtual void apply()
Apply the filter.
Definition: max.cpp:45
ROI ** src_roi
Source ROIs, dynamically allocated by Filter ctor.
Definition: filter.h:66
virtual void set_dst_buffer(unsigned char *buf, ROI *roi)
Set the destination buffer.
Definition: filter.cpp:123
unsigned char ** src
Source buffers, dynamically allocated by Filter ctor.
Definition: filter.h:61
unsigned char * dst
Destination buffer.
Definition: filter.h:63
ROI * dst_roi
Destination ROI.
Definition: filter.h:68
virtual void set_src_buffer(unsigned char *buf, ROI *roi, orientation_t ori=ORI_HORIZONTAL, unsigned int buffer_num=0)
Set source buffer with orientation.
Definition: filter.cpp:89
Image difference checker.
Definition: imagediff.h:33
void setBufferA(unsigned char *yuv422planar_buffer, unsigned int width, unsigned int height)
Set first buffer.
Definition: imagediff.cpp:64
void setBufferB(unsigned char *yuv422planar_buffer, unsigned int width, unsigned int height)
Set second buffer.
Definition: imagediff.cpp:77
bool different()
Check if images are different.
Definition: imagediff.cpp:92
Morphological filter interface.
virtual void set_structuring_element(unsigned char *se, unsigned int se_width, unsigned int se_height, unsigned int se_anchor_x, unsigned int se_anchor_y)
Set the structuring element for successive filter runs.
unsigned int image_width
width of image that contains this ROI
Definition: roi.h:121
unsigned int image_height
height of image that contains this ROI
Definition: roi.h:123
static unsigned char * square(unsigned int width, unsigned int height)
Generate square structuring element.