Fawkes API Fawkes Development Version
roi.cpp
1
2/***************************************************************************
3 * roi.cpp - Implementation for Region Of Interest (ROI) representation
4 *
5 * Generated: Thu Jul 14 12:01:58 2005
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 <fvutils/base/roi.h>
25
26#include <cstdlib>
27
28using namespace fawkes;
29
30namespace firevision {
31
32/** @class ROI <fvutils/base/roi.h>
33 * Region of interest.
34 * The ROI class is central to FireVision. All image processing is concentrated
35 * on the pre-classified interesting parts of the image, denoted by the
36 * regions of interest (ROIs).
37 *
38 * A ROI is a rectangular area of the image. Its start is denoted by the upper
39 * left corner of this rectangle and the size is given by its width and height.
40 *
41 * @author Tim Niemueller
42 */
43
44ROI *ROI::roi_full_image = NULL;
45
46/** Constructor. */
48{
51 color = C_BACKGROUND;
52}
53
54/** Constructor.
55 * @param start_x Upper left corner of ROI X coordinate
56 * @param start_y Upper left corner of ROI y coordinate
57 * @param width Width of extent of ROI
58 * @param height height of extent of ROI
59 * @param image_width width of full image this ROI belongs to
60 * @param image_height height of full image this ROI belongs to
61 */
62ROI::ROI(unsigned int start_x,
63 unsigned int start_y,
64 unsigned int width,
65 unsigned int height,
66 unsigned int image_width,
67 unsigned int image_height)
68{
70 start.x = start_x;
71 start.y = start_y;
72 this->width = width;
73 this->height = height;
74 this->image_width = image_width;
75 this->image_height = image_height;
77 pixel_step = 1;
78 color = C_BACKGROUND;
79}
80
81/** Copy constructor.
82 * @param roi reference to ROI to copy
83 */
84ROI::ROI(const ROI &roi)
85{
86 start = roi.start;
87 width = roi.width;
88 height = roi.height;
91 line_step = roi.line_step;
93 hint = roi.hint;
94 color = roi.color;
96}
97
98/** Copy constructor.
99 * @param roi pointer to ROI to copy
100 */
101ROI::ROI(const ROI *roi)
102{
103 start = roi->start;
104 width = roi->width;
105 height = roi->height;
108 line_step = roi->line_step;
109 pixel_step = roi->pixel_step;
110 hint = roi->hint;
111 color = roi->color;
113}
114
115/** Set upper left corner of ROI.
116 * @param p point
117 */
118void
120{
121 start.x = p.x;
122 start.y = p.y;
123}
124
125/** Set upper left corner.
126 * @param x x coordinate in image
127 * @param y y coordinate in image
128 */
129void
130ROI::set_start(unsigned int x, unsigned int y)
131{
132 start.x = x;
133 start.y = y;
134}
135
136/** Set width of ROI.
137 * @param width new width
138 */
139void
140ROI::set_width(unsigned int width)
141{
142 this->width = width;
143}
144
145/** Get width of ROI.
146 * @return width
147 */
148unsigned int
150{
151 return width;
152}
153
154/** Set height of ROI.
155 * @param height new height
156 */
157void
158ROI::set_height(unsigned int height)
159{
160 this->height = height;
161}
162
163/** Get height of ROI.
164 * @return height
165 */
166unsigned int
168{
169 return height;
170}
171
172/** Set full image width.
173 * Set the width of the image that contains this ROI.
174 * @param image_width full width of image.
175 */
176void
177ROI::set_image_width(unsigned int image_width)
178{
179 this->image_width = image_width;
180}
181
182/** Get full image width.
183 * Get the width of the image that contains this ROI.
184 * @return full width of image.
185 */
186unsigned int
188{
189 return image_width;
190}
191
192/** Set full image height
193 * Set the height of the image that contains this ROI.
194 * @param image_height full height of image.
195 */
196void
197ROI::set_image_height(unsigned int image_height)
198{
199 this->image_height = image_height;
200}
201
202/** Get full image height.
203 * Get the height of the image that contains this ROI.
204 * @return full height of image.
205 */
206unsigned int
208{
209 return image_height;
210}
211
212/** Set linestep.
213 * The linestep is the offset in bytes from the beginning of one line
214 * in the buffer to the beginning of the next line.
215 * @param step new line step
216 */
217void
218ROI::set_line_step(unsigned int step)
219{
220 line_step = step;
221}
222
223/** Get linestep.
224 * @return line step
225 * @see setLineStep()
226 */
227unsigned int
229{
230 return line_step;
231}
232
233/** Set pixel step.
234 * The pixel step is the offset in bytes to get from one pixel to the next
235 * in the buffer.
236 * @param step new pixel step.
237 */
238void
239ROI::set_pixel_step(unsigned int step)
240{
241 pixel_step = step;
242}
243
244/** Get pixel step.
245 * @return pixel step.
246 * @see setPixelStep()
247 */
248unsigned int
250{
251 return pixel_step;
252}
253
254/** Get hint.
255 * The hint gives an intuition what is in the ROI. In most cases this will
256 * depend on the color that the classifier used.
257 * @return hint
258 */
259unsigned int
261{
262 return hint;
263}
264
265/** Set hint.
266 * @param hint new hint
267 * @see getHint()
268 */
269void
270ROI::set_hint(unsigned int hint)
271{
272 this->hint = hint;
273}
274
275/** Check if this ROI contains the given coordinates.
276 * @param x x coordinate in image
277 * @param y y coordinate in image
278 * @return true if this ROI contains the given point, false otherwise
279 */
280bool
281ROI::contains(unsigned int x, unsigned int y)
282{
283 if ((x >= start.x) && (x < start.x + width) && (y >= start.y) && (y < start.y + height)) {
284 num_hint_points += 1;
285 return true;
286 } else {
287 return false;
288 }
289}
290
291/** Intersect this ROI with another.
292 * @param roi The other roi
293 * @return A new ROI that covers the intersection of this and the other ROI.
294 * If there's no intersection, width = height = 0.
295 */
296ROI
297ROI::intersect(ROI const &roi) const
298{
299 ROI rv;
300 if (start.x + width <= roi.start.x || roi.start.x + roi.width <= start.x
301 || start.y + height <= roi.start.y || roi.start.y + roi.height <= start.y) {
302 return rv;
303
304 } else {
305 rv = new ROI(this);
306 rv.start.x = start.x <= roi.start.x ? roi.start.x : start.x;
307 rv.start.y = start.y <= roi.start.y ? roi.start.y : start.y;
308 if (start.x + width < roi.start.x + roi.width) {
309 rv.width = start.x + width - rv.start.x;
310 } else {
311 rv.width = roi.start.x + roi.width - rv.start.x;
312 }
313 if (start.y + height < roi.start.y + roi.height) {
314 rv.height = start.y + height - rv.start.y;
315 } else {
316 rv.height = roi.start.y + roi.height - rv.start.y;
317 }
318 }
319 return rv;
320}
321
322/** Check if this ROI neighbours a pixel.
323 * This checks if the given pixel is close to this ROI considered with
324 * the given margin.
325 * @param x x coordinate in image
326 * @param y y coordinate in image
327 * @param margin margin
328 * @return true if this ROI is a neigbour of the given pixel, false otherwise
329 */
330bool
331ROI::neighbours(unsigned int x, unsigned int y, unsigned int margin) const
332{
333 return ((static_cast<int>(x) >= static_cast<int>(start.x) - static_cast<int>(margin))
334 && (x <= start.x + width + margin)
335 && (static_cast<int>(y) >= static_cast<int>(start.y) - static_cast<int>(margin))
336 && (y <= start.y + height + margin));
337}
338
339/** Check if this ROI neighbours another ROI.
340 * This checks if the given ROI is close to this ROI considered with
341 * the given margin.
342 * @param roi ROI
343 * @param margin margin
344 * @return true if this ROI is a neigbour of the given ROI, false otherwise
345 */
346bool
347ROI::neighbours(ROI *roi, unsigned int margin) const
348{
349 //Testing only x -> y test returns always true
350 bool overlapping_x = neighbours(roi->start.x, start.y, margin)
351 || neighbours(roi->start.x + roi->width, start.y, margin)
352 || roi->neighbours(start.x, roi->start.y, margin)
353 || roi->neighbours(start.x + width, roi->start.y, margin);
354
355 //Testing only y -> x test returns always true
356 bool overlapping_y = roi->neighbours(roi->start.x, start.y, margin)
357 || roi->neighbours(roi->start.x, start.y + height, margin)
358 || neighbours(start.x, roi->start.y, margin)
359 || neighbours(start.x, roi->start.y + roi->height, margin);
360
361 return overlapping_x && overlapping_y;
362}
363
364/** Extend ROI to include given pixel.
365 * @param x x coordinate of pixel to include
366 * @param y y coordinate of pixel to include
367 */
368void
369ROI::extend(unsigned int x, unsigned int y)
370{
371 if (x < start.x) {
372 width += start.x - x;
373 start.x = x;
374 }
375 if (y < start.y) {
376 height += start.y - y;
377 start.y = y;
378 }
379 if (x >= start.x + width) {
380 width += (x - (start.x + width) + 1);
381 }
382 if (y >= start.y + height) {
383 height += (y - (start.y + height) + 1);
384 }
385
386 num_hint_points += 1;
387}
388
389/** Grow this ROI by a given margin.
390 * @param margin margin to grow by
391 */
392void
393ROI::grow(unsigned int margin)
394{
395 if (start.x < margin) {
396 start.x = 0;
397 } else {
398 start.x -= margin;
399 }
400
401 if (start.y < margin) {
402 start.y = 0;
403 } else {
404 start.y -= margin;
405 }
406
407 if ((start.x + width + margin) > image_width) {
408 width += (image_width - (start.x + width));
409 } else {
410 width += margin;
411 }
412
413 if ((start.y + height + margin) > image_height) {
414 height += (image_height - (start.y + height));
415 } else {
416 height += margin;
417 }
418}
419
420/** Merge two ROIs.
421 * This ROI will be extended in any direction necessary to fully include the given
422 * ROI.
423 * @param roi ROI to include
424 * @return this instance
425 */
426ROI &
428{
429 if (roi.start.x < start.x) {
430 width += start.x - roi.start.x;
431 start.x = roi.start.x;
432 }
433 if (roi.start.y < start.y) {
434 height += start.y - roi.start.y;
435 start.y = roi.start.y;
436 }
437 if (roi.start.x + roi.width > start.x + width) {
438 width += roi.start.x + roi.width - (start.x + width);
439 }
440 if (roi.start.y + roi.height > start.y + height) {
441 height += roi.start.y + roi.height - (start.y + height);
442 }
443
445
446 return *this;
447}
448
449/** Check if this ROI contains less hint points than the given ROI.
450 * @param roi ROI to compare to.
451 * @return true, if the this ROI is smaller, false otherwise
452 */
453bool
454ROI::operator<(const ROI &roi) const
455{
456 return (color < roi.color) || (num_hint_points < roi.num_hint_points);
457}
458
459/** Check if this ROI contains more hint points than the given ROI.
460 * @param roi ROI to compare to.
461 * @return true, if the this ROI is greater, false otherwise
462 */
463bool
464ROI::operator>(const ROI &roi) const
465{
466 return (color > roi.color) || (num_hint_points > roi.num_hint_points);
467}
468
469/** Check if this ROI marks the same region for the same object
470 * and an image of the same base size and step parameters like the
471 * given ROI.
472 * @param roi ROI to compare to
473 * @return true, if ROIs are similar, false otherwise
474 */
475bool
476ROI::operator==(const ROI &roi) const
477{
478 return (start.x == roi.start.x) && (start.y == roi.start.y) && (width == roi.width)
479 && (height == roi.height) && (image_width == roi.image_width)
480 && (image_height == roi.image_height) && (line_step == roi.line_step)
481 && (pixel_step == roi.pixel_step) && (hint == roi.hint) && (color == roi.color)
483}
484
485/** Check if this ROI does not mark the same region for the same object
486 * and an image of the same base size and step parameters like the
487 * given ROI.
488 * @param roi ROI to compare to
489 * @return true, if ROIs are not similar, false otherwise
490 */
491bool
492ROI::operator!=(const ROI &roi) const
493{
494 return (num_hint_points != roi.num_hint_points);
495}
496
497/** Assign the given ROI data to this ROI.
498 * @param roi ROI to copy
499 * @return this instance
500 */
501ROI &
503{
504 this->start.x = roi.start.x;
505 this->start.y = roi.start.y;
506 this->width = roi.width;
507 this->height = roi.height;
508 this->image_width = roi.image_width;
509 this->image_height = roi.image_height;
510 this->line_step = roi.line_step;
511 this->pixel_step = roi.pixel_step;
512 this->hint = roi.hint;
513 this->color = roi.color;
515
516 return *this;
517}
518
519/** Get ROI buffer start.
520 * This uses the ROI's step and start data to calculate where
521 * the ROI starts in the given buffer.
522 * @param buffer buffer
523 * @return pointer into buffer where the ROI starts
524 */
525unsigned char *
526ROI::get_roi_buffer_start(unsigned char *buffer) const
527{
528 return (buffer + (start.y * line_step) + (start.x * pixel_step));
529}
530
531/** Gives an estimate of the number of points in this ROI that
532 * are classified to the given hint
533 * It is: num_hint_points <= total_num_of_scanline_points
534 * If you call contains and the point is actually included in
535 * this ROI this number is incremented. So you need to make
536 * sure to only call contains() for a point of the given hint
537 * class. This should always be the case anyway.
538 * If you extend the region by one very point the number will
539 * be incremented by one although the region may grow by more
540 * than just one point of the hint class.
541 * If you merge to ROIs by using the += operator this region
542 * adds the number of hint points of the region being merged
543 * to its own number. The region may grow by more than this
544 * number of points though.
545 * @return an estimate of the number of points of the hint class
546 *
547 */
548unsigned int
550{
551 return num_hint_points;
552}
553
554/** Get full image ROI for given size.
555 * Shortcut to get a full size ROI. This ROI is a static member so this
556 * method is not thread-safe or reentrant. It is also only valid until the
557 * next call to full_image() with different parameters. Line step is assumed
558 * to be the image width, the pixel step is assumed to be one. So this is
559 * only useful for b/w or planar images.
560 * @param width image width
561 * @param height image height
562 * @return full image ROI
563 */
564ROI *
565ROI::full_image(unsigned int width, unsigned int height)
566{
567 if (roi_full_image == NULL) {
568 roi_full_image = new ROI();
569 roi_full_image->start.x = 0;
570 roi_full_image->start.y = 0;
571 roi_full_image->pixel_step = 1;
572 }
573 roi_full_image->width = width;
574 roi_full_image->height = height;
575 roi_full_image->image_width = roi_full_image->width;
576 roi_full_image->image_height = roi_full_image->height;
577 roi_full_image->line_step = roi_full_image->width;
578
579 return roi_full_image;
580}
581
582} // end namespace firevision
Region of interest.
Definition: roi.h:55
void set_line_step(unsigned int step)
Set linestep.
Definition: roi.cpp:218
unsigned int height
ROI height.
Definition: roi.h:119
fawkes::upoint_t start
ROI start.
Definition: roi.h:115
unsigned char * get_roi_buffer_start(unsigned char *buffer) const
Get ROI buffer start.
Definition: roi.cpp:526
void set_pixel_step(unsigned int step)
Set pixel step.
Definition: roi.cpp:239
bool operator==(const ROI &roi) const
Check if this ROI marks the same region for the same object and an image of the same base size and st...
Definition: roi.cpp:476
static ROI * full_image(unsigned int width, unsigned int height)
Get full image ROI for given size.
Definition: roi.cpp:565
bool operator<(const ROI &roi) const
Check if this ROI contains less hint points than the given ROI.
Definition: roi.cpp:454
ROI & operator+=(ROI &roi)
Merge two ROIs.
Definition: roi.cpp:427
unsigned int line_step
line step
Definition: roi.h:125
unsigned int get_line_step() const
Get linestep.
Definition: roi.cpp:228
void set_hint(unsigned int)
Set hint.
Definition: roi.cpp:270
unsigned int width
ROI width.
Definition: roi.h:117
void set_start(fawkes::upoint_t p)
Set upper left corner of ROI.
Definition: roi.cpp:119
void set_image_width(unsigned int image_width)
Set full image width.
Definition: roi.cpp:177
unsigned int get_width() const
Get width of ROI.
Definition: roi.cpp:149
void extend(unsigned int x, unsigned int y)
Extend ROI to include given pixel.
Definition: roi.cpp:369
unsigned int hint
ROI hint.
Definition: roi.h:129
unsigned int get_image_height() const
Get full image height.
Definition: roi.cpp:207
unsigned int image_width
width of image that contains this ROI
Definition: roi.h:121
color_t color
ROI primary color.
Definition: roi.h:132
unsigned int get_hint() const
Get hint.
Definition: roi.cpp:260
void set_image_height(unsigned int image_height)
Set full image height Set the height of the image that contains this ROI.
Definition: roi.cpp:197
void set_width(unsigned int width)
Set width of ROI.
Definition: roi.cpp:140
void set_height(unsigned int height)
Set height of ROI.
Definition: roi.cpp:158
unsigned int pixel_step
pixel step
Definition: roi.h:127
void grow(unsigned int margin)
Grow this ROI by a given margin.
Definition: roi.cpp:393
unsigned int get_image_width() const
Get full image width.
Definition: roi.cpp:187
ROI intersect(ROI const &roi) const
Intersect this ROI with another.
Definition: roi.cpp:297
bool neighbours(unsigned int x, unsigned int y, unsigned int margin) const
Check if this ROI neighbours a pixel.
Definition: roi.cpp:331
unsigned int get_height() const
Get height of ROI.
Definition: roi.cpp:167
bool operator>(const ROI &roi) const
Check if this ROI contains more hint points than the given ROI.
Definition: roi.cpp:464
bool operator!=(const ROI &roi) const
Check if this ROI does not mark the same region for the same object and an image of the same base siz...
Definition: roi.cpp:492
unsigned int get_num_hint_points() const
Gives an estimate of the number of points in this ROI that are classified to the given hint It is: nu...
Definition: roi.cpp:549
ROI & operator=(const ROI &roi)
Assign the given ROI data to this ROI.
Definition: roi.cpp:502
unsigned int num_hint_points
Minimum estimate of points in ROI that are attributed to the ROI hint.
Definition: roi.h:135
ROI()
Constructor.
Definition: roi.cpp:47
bool contains(unsigned int x, unsigned int y)
Check if this ROI contains the given coordinates.
Definition: roi.cpp:281
unsigned int get_pixel_step() const
Get pixel step.
Definition: roi.cpp:249
unsigned int image_height
height of image that contains this ROI
Definition: roi.h:123
Fawkes library namespace.
Point with cartesian coordinates as unsigned integers.
Definition: types.h:35
unsigned int x
x coordinate
Definition: types.h:36
unsigned int y
y coordinate
Definition: types.h:37