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
35namespace 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 */
53unsigned char *
54SEGenerator::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 */
153unsigned char *
154SEGenerator::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 */
168void
169SEGenerator::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 */
191void
192SEGenerator::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
Draw to an image.
Definition: drawer.h:32
void set_color(unsigned char y, unsigned char u, unsigned char v)
Set drawing color.
Definition: drawer.cpp:71
void draw_line(unsigned int x_start, unsigned int y_start, unsigned int x_end, unsigned int y_end)
Draw line.
Definition: drawer.cpp:363
void set_buffer(unsigned char *buffer, unsigned int width, unsigned int height)
Set the buffer to draw to.
Definition: drawer.cpp:58
FvRaw Writer implementation.
Definition: fvraw.h:32
virtual void write()
Write to file.
Definition: fvraw.cpp:118
PNG file writer.
Definition: png.h:32
virtual void set_buffer(colorspace_t cspace, unsigned char *buffer)
Set image buffer.
Definition: png.cpp:65
virtual void write()
Write to file.
Definition: png.cpp:75
static void drawSE(unsigned char *yuv422planar_buffer, unsigned char *mask, unsigned int width, unsigned int height)
Draw structuring element.
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:54
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.
virtual void set_dimensions(unsigned int width, unsigned int height)
Set dimensions of image in pixels.
Definition: writer.cpp:128
virtual void set_filename(const char *filename)
Set filename.
Definition: writer.cpp:102
float normalize_mirror_rad(float angle_rad)
Normalize angle in radian between -PI (inclusive) and PI (exclusive).
Definition: angle.h:72