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