Fawkes API  Fawkes Development Version
segenerator.cpp
1 
2 /***************************************************************************
3  * segenerator.cpp - Class that helps to create some standard structuring
4  * elements
5  *
6  * Created: Wed Jun 07 11:23:03 2006
7  * Copyright 2005-2007 Tim Niemueller [www.niemueller.de]
8  *
9  ****************************************************************************/
10 
11 /* This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version. A runtime exception applies to
15  * this software (see LICENSE.GPL_WRE file mentioned below for details).
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  * GNU Library General Public License for more details.
21  *
22  * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
23  */
24 
25 #include <fvfilters/morphology/segenerator.h>
26 #include <fvutils/color/colorspaces.h>
27 #include <fvutils/draw/drawer.h>
28 #include <fvutils/writers/fvraw.h>
29 #include <fvutils/writers/png.h>
30 #include <utils/math/angle.h>
31 
32 #include <cstdlib>
33 #include <cstring>
34 
35 namespace firevision {
36 
37 /** @class SEGenerator <fvfilters/morphology/segenerator.h>
38  * Basic generators for structuring elements for morphological filters.
39  * @author Tim Niemueller
40  */
41 
42 /** Generate linear structuring element.
43  * @param width width of structuring element
44  * @param height height of structuring element
45  * @param proposed_center_x contains the proposed x coordinate of the anchor
46  * upon return
47  * @param proposed_center_y contains the proposed y coordinate of the anchor
48  * upon return
49  * @param slope_angle_rad the slope of the line in radians
50  * @return buffer with linear structuring element. The buffer has been allocated
51  * using malloc(). Use free() to free the memory after you are done with it.
52  */
53 unsigned char *
54 SEGenerator::linear(unsigned int width,
55  unsigned int height,
56  unsigned int *proposed_center_x,
57  unsigned int *proposed_center_y,
58  float slope_angle_rad)
59 {
60  // we always start at (0,0) and then calculate the corrensponding
61  // y of the linear functional
62  // l: x -> mx + b, where b is 0.
63  // by tan(slope_angle_rad) = y / x
64  // => y = x * tan(slope_angle_rad) with x = width
65 
66  if (height == 0)
67  return NULL;
68  if (width == 0)
69  return NULL;
70 
71  unsigned char *tmp =
72  (unsigned char *)malloc(colorspace_buffer_size(YUV422_PLANAR, width, height));
73  memset(tmp, 0, colorspace_buffer_size(YUV422_PLANAR, width, height));
74  Drawer *d = new Drawer();
75  d->set_buffer(tmp, width, height);
76  d->set_color(1, 0, 0);
77 
78  float a = fawkes::normalize_mirror_rad(slope_angle_rad);
79 
80  if ((a == M_PI / 2) || (a == -M_PI / 2)) {
81  // It's just a vertical line
82  // std::cout << "Drawing line from (0,0) -> (0," << height - 1 << ")" << std::endl;
83  d->draw_line(0, 0, 0, height - 1);
84  } else {
85  // sectors 3 and 4 can be converted to sector 2 and 1 lines
86  if (a > M_PI / 2)
87  a -= M_PI;
88  if (a < -M_PI / 2)
89  a += M_PI;
90 
91  int y = (int)roundf(((float)width - 1.f) * tan(a));
92 
93  if (y < 0) {
94  // std::cout << "Drawing line from (0,0) -> (" << width - 1 << "," << -y << ")" << std::endl;
95  d->draw_line(0, 0, width - 1, -y);
96  } else {
97  // std::cout << "Drawing line from (0," << y << ") -> (" << width - 1 << ",0)" << std::endl;
98  d->draw_line(0, y, width - 1, 0);
99  }
100  }
101 
102  delete d;
103 
104  unsigned char *se = (unsigned char *)malloc((size_t)width * (size_t)height);
105  memcpy(se, tmp, (size_t)width * (size_t)height);
106 
107  PNGWriter *png = new PNGWriter();
108  png->set_dimensions(width, height);
109  png->set_buffer(YUV422_PLANAR, tmp);
110  png->set_filename("se_test.png");
111  png->write();
112  delete png;
113 
114  FvRawWriter *fvraw = new FvRawWriter("se_test.raw", width, height, YUV422_PLANAR, tmp);
115  fvraw->write();
116  delete fvraw;
117 
118  free(tmp);
119 
120  if ((proposed_center_x != NULL) && (proposed_center_y != NULL)) {
121  unsigned int min_x = width;
122  unsigned int max_x = 0;
123  unsigned int min_y = height;
124  unsigned int max_y = 0;
125  for (unsigned int h = 0; h < height; ++h) {
126  for (unsigned int w = 0; w < width; ++w) {
127  if (se[h * width + w] != 0) {
128  if (w < min_x)
129  min_x = w;
130  if (w > max_x)
131  max_x = w;
132  if (h < min_y)
133  min_y = h;
134  if (h > max_y)
135  max_y = h;
136  }
137  }
138  }
139 
140  *proposed_center_x = min_x + (max_x - min_x) / 2;
141  *proposed_center_y = min_y + (max_y - min_y) / 2;
142  }
143 
144  return se;
145 }
146 
147 /** Generate square structuring element.
148  * @param width width of structuring element
149  * @param height height of structuring element
150  * @return buffer with square structuring element. The buffer has been allocated
151  * using malloc(). Use free() to free the memory after you are done with it.
152  */
153 unsigned char *
154 SEGenerator::square(unsigned int width, unsigned int height)
155 {
156  unsigned char *se = (unsigned char *)malloc((size_t)width * (size_t)height);
157  memset(se, 1, (size_t)width * (size_t)height);
158  return se;
159 }
160 
161 /** Draw structuring element.
162  * This draws the structuring element to an image buffer.
163  * @param yuv422planar_buffer image buffer
164  * @param mask structuring element
165  * @param width width of structuring element
166  * @param height height of structuring element
167  */
168 void
169 SEGenerator::drawSE(unsigned char *yuv422planar_buffer,
170  unsigned char *mask,
171  unsigned int width,
172  unsigned int height)
173 {
174  memset(yuv422planar_buffer, 128, colorspace_buffer_size(YUV422_PLANAR, width, height));
175  for (unsigned int h = 0; h < height; ++h) {
176  for (unsigned int w = 0; w < width; ++w) {
177  if (mask[h * width + w] != 0) {
178  yuv422planar_buffer[h * width + w] = 255;
179  }
180  }
181  }
182 }
183 
184 /** Draw structuring element.
185  * This draws the structuring element to a b/w image buffer.
186  * @param yuv422planar_buffer image buffer
187  * @param mask structuring element
188  * @param width width of structuring element
189  * @param height height of structuring element
190  */
191 void
192 SEGenerator::drawSEbw(unsigned char *yuv422planar_buffer,
193  unsigned char *mask,
194  unsigned int width,
195  unsigned int height)
196 {
197  memset(yuv422planar_buffer, 128, colorspace_buffer_size(YUV422_PLANAR, width, height));
198  memset(yuv422planar_buffer, 255, (size_t)width * (size_t)height);
199  for (unsigned int h = 0; h < height; ++h) {
200  for (unsigned int w = 0; w < width; ++w) {
201  if (mask[h * width + w] != 0) {
202  yuv422planar_buffer[h * width + w] = 0;
203  }
204  }
205  }
206 }
207 
208 } // end namespace firevision
firevision::Drawer::set_color
void set_color(unsigned char y, unsigned char u, unsigned char v)
Set drawing color.
Definition: drawer.cpp:77
firevision::SEGenerator::linear
static unsigned char * linear(unsigned int width, unsigned int height, unsigned int *proposed_center_x, unsigned int *proposed_center_y, float slope_angle_rad)
Generate linear structuring element.
Definition: segenerator.cpp:61
firevision::SEGenerator::drawSEbw
static void drawSEbw(unsigned char *yuv422planar_buffer, unsigned char *mask, unsigned int width, unsigned int height)
Draw structuring element.
Definition: segenerator.cpp:199
firevision::Drawer::draw_line
void draw_line(unsigned int x_start, unsigned int y_start, unsigned int x_end, unsigned int y_end)
Draw line.
Definition: drawer.cpp:369
firevision::SEGenerator::drawSE
static void drawSE(unsigned char *yuv422planar_buffer, unsigned char *mask, unsigned int width, unsigned int height)
Draw structuring element.
Definition: segenerator.cpp:176
fawkes::normalize_mirror_rad
float normalize_mirror_rad(float angle_rad)
Normalize angle in radian between -PI (inclusive) and PI (exclusive).
Definition: angle.h:78
firevision::Drawer
Definition: drawer.h:37
firevision::SEGenerator::square
static unsigned char * square(unsigned int width, unsigned int height)
Generate square structuring element.
Definition: segenerator.cpp:161
firevision::Drawer::set_buffer
void set_buffer(unsigned char *buffer, unsigned int width, unsigned int height)
Set the buffer to draw to.
Definition: drawer.cpp:64