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 
27 #include <utils/math/angle.h>
28 
29 #include <fvutils/draw/drawer.h>
30 #include <fvutils/color/colorspaces.h>
31 #include <fvutils/writers/png.h>
32 #include <fvutils/writers/fvraw.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 /** @class SEGenerator <fvfilters/morphology/segenerator.h>
43  * Basic generators for structuring elements for morphological filters.
44  * @author Tim Niemueller
45  */
46 
47 
48 /** Generate linear structuring element.
49  * @param width width of structuring element
50  * @param height height of structuring element
51  * @param proposed_center_x contains the proposed x coordinate of the anchor
52  * upon return
53  * @param proposed_center_y contains the proposed y coordinate of the anchor
54  * upon return
55  * @param slope_angle_rad the slope of the line in radians
56  * @return buffer with linear structuring element. The buffer has been allocated
57  * using malloc(). Use free() to free the memory after you are done with it.
58  */
59 unsigned char *
60 SEGenerator::linear(unsigned int width, unsigned int height,
61  unsigned int *proposed_center_x, unsigned int *proposed_center_y,
62  float slope_angle_rad)
63 {
64 
65  // we always start at (0,0) and then calculate the corrensponding
66  // y of the linear functional
67  // l: x -> mx + b, where b is 0.
68  // by tan(slope_angle_rad) = y / x
69  // => y = x * tan(slope_angle_rad) with x = width
70 
71  if ( height == 0 ) return NULL;
72  if ( width == 0) return NULL;
73 
74 
75  unsigned char *tmp = (unsigned char *)malloc(colorspace_buffer_size(YUV422_PLANAR, width, height));
76  memset(tmp, 0, colorspace_buffer_size(YUV422_PLANAR, width, height));
77  Drawer *d = new Drawer();
78  d->set_buffer(tmp, width, height);
79  d->set_color(1, 0, 0);
80 
81  float a = fawkes::normalize_mirror_rad( slope_angle_rad );
82 
83  if ( (a == M_PI/2) || (a == -M_PI/2) ) {
84  // It's just a vertical line
85  // std::cout << "Drawing line from (0,0) -> (0," << height - 1 << ")" << std::endl;
86  d->draw_line(0, 0, 0, height - 1);
87  } else {
88 
89  // sectors 3 and 4 can be converted to sector 2 and 1 lines
90  if ( a > M_PI / 2) a -= M_PI;
91  if ( a < - M_PI / 2) a += M_PI;
92 
93  int y = (int)roundf(((float)width - 1.f) * tan( a ));
94 
95  if ( y < 0) {
96  // std::cout << "Drawing line from (0,0) -> (" << width - 1 << "," << -y << ")" << std::endl;
97  d->draw_line( 0, 0, width - 1, -y );
98  } else {
99  // std::cout << "Drawing line from (0," << y << ") -> (" << width - 1 << ",0)" << std::endl;
100  d->draw_line( 0, y, width - 1, 0 );
101  }
102  }
103 
104  delete d;
105 
106  unsigned char *se = (unsigned char *)malloc(width * height);
107  memcpy(se, tmp, width * height);
108 
109  PNGWriter *png = new PNGWriter();
110  png->set_dimensions( width, height );
111  png->set_buffer(YUV422_PLANAR, tmp);
112  png->set_filename("se_test.png");
113  png->write();
114  delete png;
115 
116  FvRawWriter *fvraw = new FvRawWriter("se_test.raw", width, height, YUV422_PLANAR, tmp);
117  fvraw->write();
118  delete fvraw;
119 
120  free( tmp );
121 
122  if ( (proposed_center_x != NULL) && (proposed_center_y != NULL) ) {
123  unsigned int min_x = width;
124  unsigned int max_x = 0;
125  unsigned int min_y = height;
126  unsigned int max_y = 0;
127  for (unsigned int h = 0; h < height; ++h) {
128  for (unsigned int w = 0; w < width; ++w) {
129  if ( se[ h * width + w ] != 0 ) {
130  if ( w < min_x ) min_x = w;
131  if ( w > max_x ) max_x = w;
132  if ( h < min_y ) min_y = h;
133  if ( h > max_y ) max_y = h;
134  }
135  }
136  }
137 
138  *proposed_center_x = min_x + (max_x - min_x) / 2;
139  *proposed_center_y = min_y + (max_y - min_y) / 2;
140  }
141 
142  return se;
143 }
144 
145 
146 /** Generate square structuring element.
147  * @param width width of structuring element
148  * @param height height of structuring element
149  * @return buffer with square structuring element. The buffer has been allocated
150  * using malloc(). Use free() to free the memory after you are done with it.
151  */
152 unsigned char *
153 SEGenerator::square(unsigned int width, unsigned int height)
154 {
155  unsigned char *se = (unsigned char *)malloc(width * height);
156  memset(se, 1, width * height);
157  return se;
158 }
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, unsigned char *mask, unsigned int width, unsigned int height)
170 {
171  memset(yuv422planar_buffer, 128, colorspace_buffer_size(YUV422_PLANAR, width, height) );
172  for (unsigned int h = 0; h < height; ++h) {
173  for (unsigned int w = 0; w < width; ++w) {
174  if ( mask[ h * width + w ] != 0 ) {
175  yuv422planar_buffer[ h * width + w ] = 255;
176  }
177  }
178  }
179 }
180 
181 
182 /** Draw structuring element.
183  * This draws the structuring element to a b/w image buffer.
184  * @param yuv422planar_buffer image buffer
185  * @param mask structuring element
186  * @param width width of structuring element
187  * @param height height of structuring element
188  */
189 void
190 SEGenerator::drawSEbw(unsigned char *yuv422planar_buffer, unsigned char *mask, unsigned int width, unsigned int height)
191 {
192  memset(yuv422planar_buffer, 128, colorspace_buffer_size(YUV422_PLANAR, width, height) );
193  memset(yuv422planar_buffer, 255, width * height );
194  for (unsigned int h = 0; h < height; ++h) {
195  for (unsigned int w = 0; w < width; ++w) {
196  if ( mask[ h * width + w ] != 0 ) {
197  yuv422planar_buffer[ h * width + w ] = 0;
198  }
199  }
200  }
201 }
202 
203 } // end namespace firevision
static void drawSE(unsigned char *yuv422planar_buffer, unsigned char *mask, unsigned int width, unsigned int height)
Draw structuring element.
PNG file writer.
Definition: png.h:34
Draw to an image.
Definition: drawer.h:34
virtual void write()
Write to file.
Definition: png.cpp:81
void draw_line(unsigned int x_start, unsigned int y_start, unsigned int x_end, unsigned int y_end)
Draw line.
Definition: drawer.cpp:381
static void drawSEbw(unsigned char *yuv422planar_buffer, unsigned char *mask, unsigned int width, unsigned int height)
Draw structuring element.
static unsigned char * square(unsigned int width, unsigned int height)
Generate square structuring element.
float normalize_mirror_rad(float angle_rad)
Normalize angle in radian between -PI (inclusive) and PI (exclusive).
Definition: angle.h:75
FvRaw Writer implementation.
Definition: fvraw.h:34
void set_buffer(unsigned char *buffer, unsigned int width, unsigned int height)
Set the buffer to draw to.
Definition: drawer.cpp:62
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:60
virtual void write()
Write to file.
Definition: fvraw.cpp:128
virtual void set_filename(const char *filename)
Set filename.
Definition: writer.cpp:106
virtual void set_buffer(colorspace_t cspace, unsigned char *buffer)
Set image buffer.
Definition: png.cpp:70
virtual void set_dimensions(unsigned int width, unsigned int height)
Set dimensions of image in pixels.
Definition: writer.cpp:132
void set_color(unsigned char y, unsigned char u, unsigned char v)
Set drawing color.
Definition: drawer.cpp:77