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 
26 #include <fvfilters/morphology/geodesic_erosion.h>
27 #include <fvfilters/morphology/segenerator.h>
28 #include <fvfilters/morphology/erosion.h>
29 #include <fvfilters/max.h>
30 
31 #include <fvutils/color/colorspaces.h>
32 #include <fvutils/statistical/imagediff.h>
33 
34 #include <cstdlib>
35 #include <cstring>
36 
37 namespace firevision {
38 #if 0 /* just to make Emacs auto-indent happy */
39 }
40 #endif
41 
42 /** Marker */
43 const unsigned int FilterGeodesicErosion::MARKER = 0;
44 /** Mask */
45 const unsigned int FilterGeodesicErosion::MASK = 1;
46 
47 #define ERROR(m) { \
48  fawkes::Exception e("FilterGeodesicErosion failed"); \
49  e.append("Function: %s", __FUNCTION__); \
50  e.append("Message: %s", m); \
51  throw e; \
52  }
53 
54 /** @class FilterGeodesicErosion <fvfilters/morphology/geodesic_erosion.h>
55  * Morphological geodesic erosion.
56  * @author Tim Niemueller
57  */
58 
59 /** Constructor.
60  * @param se_size Structuring element size.
61  */
63  : MorphologicalFilter("Morphological Geodesic Erosion")
64 {
65  this->se_size = (se_size > 0) ? se_size : 1;
66  iterations = 0;
67 
68  erode = new FilterErosion();
69  max = new FilterMax();
70  diff = new ImageDiff();
71 
72  isotropic_se = SEGenerator::square(this->se_size, this->se_size);
73 
74  erode->set_structuring_element( isotropic_se, se_size, se_size, se_size / 2, se_size / 2 );
75 }
76 
77 
78 /** Destructor. */
80 {
81  delete erode;
82  delete max;
83  delete diff;
84  free( isotropic_se );
85 }
86 
87 
88 void
90 {
91  if ( dst == NULL ) ERROR("dst == NULL");
92  if ( src[MASK] == NULL ) ERROR("src[MASK] == NULL");
93  if ( src[MARKER] == NULL ) ERROR("src[MARKER] == NULL");
94  if ( *(src_roi[MASK]) != *(src_roi[MARKER]) ) ERROR("marker and mask ROI differ");
95 
96  unsigned char *tmp = (unsigned char *)malloc(colorspace_buffer_size(YUV422_PLANAR, src_roi[MARKER]->image_width, src_roi[MARKER]->image_height) );
97  memcpy( tmp, src[MARKER], colorspace_buffer_size(YUV422_PLANAR, src_roi[MARKER]->image_width, src_roi[MARKER]->image_height) );
98 
99  diff->setBufferA( tmp, src_roi[MARKER]->image_width, src_roi[MARKER]->image_height );
101 
102  erode->set_src_buffer( tmp, src_roi[MARKER] );
103 
104  max->set_src_buffer( src[MASK], src_roi[MASK], 0 );
105  max->set_src_buffer( tmp, src_roi[MARKER], 1 );
106  max->set_dst_buffer( tmp, src_roi[MARKER] );
107 
108 
109  iterations = 0;
110  do {
111  memcpy(dst, tmp, colorspace_buffer_size(YUV422_PLANAR, dst_roi->image_width, dst_roi->image_height) );
112  erode->apply();
113  max->apply();
114  } while (diff->different() && ( ++iterations < 255) );
115 
116  // std::cout << i << " iterations done for geodesic erosion" << std::endl;
117 
118 
119  free( tmp );
120 
121 }
122 
123 
124 /** Get the number of iterations.
125  * @return the number of iterations that were necessary to get a stable result in the
126  * last call to apply().
127  */
128 unsigned int
130 {
131  return iterations;
132 }
133 
134 } // end namespace firevision
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.
virtual unsigned int num_iterations()
Get the number of iterations.
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:93
void setBufferA(unsigned char *yuv422planar_buffer, unsigned int width, unsigned int height)
Set first buffer.
Definition: imagediff.cpp:70
virtual void apply()
Apply the filter.
Definition: erosion.cpp:60
bool different()
Check if images are different.
Definition: imagediff.cpp:102
virtual void apply()
Apply the filter.
virtual void apply()
Apply the filter.
Definition: max.cpp:49
unsigned int image_width
width of image that contains this ROI
Definition: roi.h:125
Image difference checker.
Definition: imagediff.h:35
static unsigned char * square(unsigned int width, unsigned int height)
Generate square structuring element.
Morphological filter interface.
unsigned char ** src
Source buffers, dynamically allocated by Filter ctor.
Definition: filter.h:65
unsigned int image_height
height of image that contains this ROI
Definition: roi.h:127
static const unsigned int MARKER
Marker.
ROI ** src_roi
Source ROIs, dynamically allocated by Filter ctor.
Definition: filter.h:70
Morphological erosion.
Definition: erosion.h:33
FilterGeodesicErosion(unsigned int se_size=3)
Constructor.
virtual ~FilterGeodesicErosion()
Destructor.
void setBufferB(unsigned char *yuv422planar_buffer, unsigned int width, unsigned int height)
Set second buffer.
Definition: imagediff.cpp:85
static const unsigned int MASK
Mask.
unsigned char * dst
Destination buffer.
Definition: filter.h:67
ROI * dst_roi
Destination ROI.
Definition: filter.h:72
Maximum filter.
Definition: max.h:34
virtual void set_dst_buffer(unsigned char *buf, ROI *roi)
Set the destination buffer.
Definition: filter.cpp:134