Fawkes API Fawkes Development Version

shrinker.cpp

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
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends