Fawkes API Fawkes Development Version
shrinker.cpp
1
2/***************************************************************************
3 * shrinker.cpp - Implementation of Shrinker
4 *
5 * Generated: Wed Aug 31 2005 21:52:28
6 * Copyright 2005 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 <fvclassifiers/shrinker.h>
25#include <fvutils/base/roi.h>
26#include <fvutils/color/colorspaces.h>
27
28#include <cstddef>
29
30namespace firevision {
31
32/** @class Shrinker <fvclassifiers/shrinker.h>
33 * Shrinker class to shrink ROIs.
34 * This shrinker shrinks a given ROI. This is done to cope with several
35 * special problems that arise in different setups. For example if playing
36 * downstairs in the lobby without a carpet we always have a problem with
37 * reflections on the floor.
38 *
39 * This shrinker works like this:
40 * - if ROI is vertically rectangular, we cut off the bottom part
41 * because it is likely to contain reflection
42 * - if ball is not close (roi->width <= 100), we tighten the ROI, such that
43 * it only contains the ball. This helps against reflection.
44 * (If ball is close, this does not work, because it takes away too many edge pixels.)
45 */
46
47/** Constructor. */
49{
50 src = NULL;
51}
52
53/** Destructor. */
55{
56}
57
58/** Set the filtered buffer.
59 * The buffer is assumed to being YUV422_PLANAR mode and the desired filter
60 * combination has been run.
61 * @param yuv422planar_buffer YUV422 planar buffer
62 */
63void
64Shrinker::setFilteredBuffer(unsigned char *yuv422planar_buffer)
65{
66 src = yuv422planar_buffer;
67}
68
69/** Shrink!
70 * Do the actual shrinking. See above for used method.
71 * @param roi ROI to srhink
72 */
73void
75{
76 unsigned int x;
77 unsigned int y;
78
79 /* if ROI is vertically rectangular, we cut off the bottom part
80 because it is likely to contain reflection */
81 if (roi->height > roi->width) {
82 roi->height = roi->width;
83 }
84
85 if (roi->width <= 100) {
86 /* Ball is not close. Tighten ROI, such that it only contains the ball.
87 This helps against reflection.
88 (If ball is close, this does not work, because it takes away too many edge pixels.) */
89
90 unsigned char * bufferTmp = roi->get_roi_buffer_start(src);
91 unsigned char * line_startTmp = bufferTmp;
92 fawkes::upoint_t leftmostPixel = {roi->width, 0};
93 fawkes::upoint_t topmostPixel = {0, roi->height};
94
95 // find leftmost hint-pixel
96 bool pixelFound = false;
97 for (x = 0; !pixelFound && (x < roi->width / 2); ++x) {
98 for (y = 0; y < roi->height / 2; ++y) {
99 if (*bufferTmp > 230) { // if pixel is white or almost white = edge
100 leftmostPixel.x = x;
101 leftmostPixel.y = y;
102 pixelFound = true;
103 }
104 ++bufferTmp;
105 } // inner for
106 line_startTmp += roi->line_step;
107 bufferTmp = line_startTmp;
108 } // outer for
109
110 bufferTmp = roi->get_roi_buffer_start(src);
111 line_startTmp = bufferTmp;
112
113 // find topmost hint-pixel
114 pixelFound = false;
115 for (y = 0; !pixelFound && (y < roi->height / 2); ++y) {
116 for (x = 0; x < roi->width; ++x) {
117 if (*bufferTmp > 230) {
118 topmostPixel.x = x;
119 topmostPixel.y = y;
120 pixelFound = true;
121 }
122 ++bufferTmp;
123 } // inner for
124 /*
125 if (pixelFound) {
126 // try to improve x-coordinate (too small)
127 unsigned int x2 = topmostPixel.x;
128 for (unsigned int a = topmostPixel.x + 1; a < roi->width; ++a) {
129 if (TEST_IF_IS_A_PIXEL(*bufferTmp)) {
130 x2 = a;
131 }
132 ++bufferTmp;
133 }
134 topmostPixel.x = (topmostPixel.x + x2) / 2;
135 }
136 */
137 line_startTmp += roi->line_step;
138 bufferTmp = line_startTmp;
139 } // outer for
140
141 bufferTmp = roi->get_roi_buffer_start(src);
142 line_startTmp = bufferTmp;
143
144 // tighten ROI if it makes sense
145 if ((leftmostPixel.x >= topmostPixel.x) || (topmostPixel.y >= leftmostPixel.y)
146 || (2 * (topmostPixel.x - leftmostPixel.x) >= roi->width)
147 || (2 * (leftmostPixel.y - topmostPixel.y) >= roi->height)) {
148 // bad pixels found
149 } else {
150 // tighten ROI
151 // roi->start.x += leftmostPixel.x;
152 // roi->start.y += topmostPixel.y;
153 // roi->height -= topmostPixel.y;
154 //roi->width = 2 * (topmostPixel.x - leftmostPixel.x);
155 roi->height = 2 * (leftmostPixel.y - topmostPixel.y);
156 /*
157 if ( roi->width < roi->height ) {
158 // further shrinking
159 roi->height = roi->width;
160 }
161 */
162 //cout << "Shrinker: Shrank region!" << endl;
163 }
164 } // else do nothing
165}
166
167} // end namespace firevision
Region of interest.
Definition: roi.h:55
unsigned int height
ROI height.
Definition: roi.h:119
unsigned char * get_roi_buffer_start(unsigned char *buffer) const
Get ROI buffer start.
Definition: roi.cpp:526
unsigned int line_step
line step
Definition: roi.h:125
unsigned int width
ROI width.
Definition: roi.h:117
virtual void shrink(ROI *roi)
Shrink! Do the actual shrinking.
Definition: shrinker.cpp:74
virtual void setFilteredBuffer(unsigned char *yuv422planar_buffer)
Set the filtered buffer.
Definition: shrinker.cpp:64
virtual ~Shrinker()
Destructor.
Definition: shrinker.cpp:54
unsigned char * src
Source image buffer.
Definition: shrinker.h:42
Shrinker()
Constructor.
Definition: shrinker.cpp:48
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