Fawkes API Fawkes Development Version
|
00001 00002 /*************************************************************************** 00003 * shrinker.cpp - Implementation of Shrinker 00004 * 00005 * Generated: Wed Aug 31 2005 21:52:28 00006 * Copyright 2005 Tim Niemueller [www.niemueller.de] 00007 * 00008 ****************************************************************************/ 00009 00010 /* This program is free software; you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation; either version 2 of the License, or 00013 * (at your option) any later version. A runtime exception applies to 00014 * this software (see LICENSE.GPL_WRE file mentioned below for details). 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU Library General Public License for more details. 00020 * 00021 * Read the full text in the LICENSE.GPL_WRE file in the doc directory. 00022 */ 00023 00024 #include <classifiers/shrinker.h> 00025 #include <fvutils/color/colorspaces.h> 00026 #include <fvutils/base/roi.h> 00027 00028 #include <cstddef> 00029 00030 namespace firevision { 00031 #if 0 /* just to make Emacs auto-indent happy */ 00032 } 00033 #endif 00034 00035 /** @class Shrinker <classifiers/shrinker.h> 00036 * Shrinker class to shrink ROIs. 00037 * This shrinker shrinks a given ROI. This is done to cope with several 00038 * special problems that arise in different setups. For example if playing 00039 * downstairs in the lobby without a carpet we always have a problem with 00040 * reflections on the floor. 00041 * 00042 * This shrinker works like this: 00043 * - if ROI is vertically rectangular, we cut off the bottom part 00044 * because it is likely to contain reflection 00045 * - if ball is not close (roi->width <= 100), we tighten the ROI, such that 00046 * it only contains the ball. This helps against reflection. 00047 * (If ball is close, this does not work, because it takes away too many edge pixels.) 00048 */ 00049 00050 /** Constructor. */ 00051 Shrinker::Shrinker() 00052 { 00053 src = NULL; 00054 } 00055 00056 00057 /** Destructor. */ 00058 Shrinker::~Shrinker() 00059 { 00060 } 00061 00062 00063 /** Set the filtered buffer. 00064 * The buffer is assumed to being YUV422_PLANAR mode and the desired filter 00065 * combination has been run. 00066 * @param yuv422planar_buffer YUV422 planar buffer 00067 */ 00068 void 00069 Shrinker::setFilteredBuffer(unsigned char *yuv422planar_buffer) { 00070 src = yuv422planar_buffer; 00071 } 00072 00073 00074 /** Shrink! 00075 * Do the actual shrinking. See above for used method. 00076 * @param roi ROI to srhink 00077 */ 00078 void 00079 Shrinker::shrink( ROI *roi ) 00080 { 00081 00082 unsigned int x; 00083 unsigned int y; 00084 00085 /* if ROI is vertically rectangular, we cut off the bottom part 00086 because it is likely to contain reflection */ 00087 if (roi->height > roi->width) { 00088 roi->height = roi->width; 00089 } 00090 00091 if ( roi->width <= 100 ) { 00092 /* Ball is not close. Tighten ROI, such that it only contains the ball. 00093 This helps against reflection. 00094 (If ball is close, this does not work, because it takes away too many edge pixels.) */ 00095 00096 unsigned char *bufferTmp = roi->get_roi_buffer_start( src ); 00097 unsigned char *line_startTmp = bufferTmp; 00098 fawkes::point_t leftmostPixel = {roi->width, 0}; 00099 fawkes::point_t topmostPixel = {0, roi->height}; 00100 00101 // find leftmost hint-pixel 00102 bool pixelFound = false; 00103 for (x = 0; !pixelFound && (x < roi->width / 2); ++x) { 00104 for (y = 0; y < roi->height/2; ++y) { 00105 if (*bufferTmp > 230) { // if pixel is white or almost white = edge 00106 leftmostPixel.x = x; 00107 leftmostPixel.y = y; 00108 pixelFound = true; 00109 } 00110 ++bufferTmp; 00111 } // inner for 00112 line_startTmp += roi->line_step; 00113 bufferTmp = line_startTmp; 00114 } // outer for 00115 00116 bufferTmp = roi->get_roi_buffer_start( src ); 00117 line_startTmp = bufferTmp; 00118 00119 // find topmost hint-pixel 00120 pixelFound = false; 00121 for (y = 0; !pixelFound && (y < roi->height/2); ++y) { 00122 for (x = 0; x < roi->width; ++x) { 00123 if (*bufferTmp > 230) { 00124 topmostPixel.x = x; 00125 topmostPixel.y = y; 00126 pixelFound = true; 00127 } 00128 ++bufferTmp; 00129 } // inner for 00130 /* 00131 if (pixelFound) { 00132 // try to improve x-coordinate (too small) 00133 unsigned int x2 = topmostPixel.x; 00134 for (unsigned int a = topmostPixel.x + 1; a < roi->width; ++a) { 00135 if (TEST_IF_IS_A_PIXEL(*bufferTmp)) { 00136 x2 = a; 00137 } 00138 ++bufferTmp; 00139 } 00140 topmostPixel.x = (topmostPixel.x + x2) / 2; 00141 } 00142 */ 00143 line_startTmp += roi->line_step; 00144 bufferTmp = line_startTmp; 00145 } // outer for 00146 00147 bufferTmp = roi->get_roi_buffer_start( src ); 00148 line_startTmp = bufferTmp; 00149 00150 // tighten ROI if it makes sense 00151 if ( (leftmostPixel.x >= topmostPixel.x) || 00152 (topmostPixel.y >= leftmostPixel.y) || 00153 (2 * (topmostPixel.x - leftmostPixel.x) >= roi->width) || 00154 (2 * (leftmostPixel.y - topmostPixel.y) >= roi->height) ) { 00155 // bad pixels found 00156 } else { 00157 // tighten ROI 00158 // roi->start.x += leftmostPixel.x; 00159 // roi->start.y += topmostPixel.y; 00160 // roi->height -= topmostPixel.y; 00161 //roi->width = 2 * (topmostPixel.x - leftmostPixel.x); 00162 roi->height = 2 * (leftmostPixel.y - topmostPixel.y); 00163 /* 00164 if ( roi->width < roi->height ) { 00165 // further shrinking 00166 roi->height = roi->width; 00167 } 00168 */ 00169 //cout << "Shrinker: Shrank region!" << endl; 00170 } 00171 } // else do nothing 00172 00173 } 00174 00175 } // end namespace firevision