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
35namespace firevision {
36
37/** Marker */
38const unsigned int FilterGeodesicErosion::MARKER = 0;
39/** Mask */
40const 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
82void
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 */
131unsigned 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.