qualifiers.cpp

00001 /***************************************************************************
00002  *  qualifiers.cpp - Pixel qualifier
00003  *
00004  *  Created: Mon, 09. Jun 2008 22:54
00005  *  Copyright  2008  Christof Rath <c.rath@student.tugraz.at>
00006  *
00007  ****************************************************************************/
00008
00009 /*  This program is free software; you can redistribute it and/or modify
00010  *  it under the terms of the GNU General Public License as published by
00011  *  the Free Software Foundation; either version 2 of the License, or
00012  *  (at your option) any later version.
00013  *
00014  *  This program is distributed in the hope that it will be useful,
00015  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  *  GNU Library General Public License for more details.
00018  *
00019  *  Read the full text in the LICENSE.GPL file in the doc directory.
00020  */
00021
00022 #include "qualifiers.h"
00023 #include <core/exceptions/software.h>
00024 #include <fvutils/color/yuv.h>
00025
00026 #include <cstdlib>
00027
00028 using fawkes::point_t;
00029 
00030 /** @class Qualifier qualifiers.h <apps/nao_loc/qualifiers.h>
00031  * Abstract Qualifier for a single pixel
00032  *
00033  * @author Christof Rath
00034  */
00035 
00036 /** Default constructor
00037  */
00038 Qualifier::Qualifier()
00039 {
00040   buffer_     = 0;
00041   width_      = 0;
00042   height_     = 0;
00043   size_       = 0;
00044   colorspace_ = CS_UNKNOWN;
00045 }
00046 
00047 /** Constructor.
00048  * @param buffer containing the image
00049  * @param width of the image
00050  * @param height of the image
00051  * @param colorspace the colorspace in action
00052  */
00053 Qualifier::Qualifier(unsigned char* buffer, unsigned int width,
00054                      unsigned int height, colorspace_t colorspace)
00055 {
00056   if (!buffer)
00057     throw fawkes::NullPointerException("Qualifier: the buffer may not be null!");
00058   if (!width || !height)
00059     throw fawkes::IllegalArgumentException("Qualifier: width and height may not be 0!");
00060
00061   set_buffer(buffer, width, height);
00062   colorspace_ = colorspace;
00063 }
00064
00065 
00066 /** Destructor.
00067  */
00068 Qualifier::~Qualifier()
00069 {
00070 }
00071 
00072 /** buffer getter
00073  */
00074 unsigned char*
00075 Qualifier::get_buffer()
00076 {
00077   return buffer_;
00078 }
00079 
00080 /** buffer setter
00081  * @param buffer containing the image
00082  * @param width of the image (if 0 the param will be ignored)
00083  * @param height of the image (if 0 the param will be ignored)
00084  */
00085 void
00086 Qualifier::set_buffer(unsigned char* buffer, unsigned int width,
00087                       unsigned int height)
00088 {
00089   buffer_ = buffer;
00090
00091   if (width)
00092     width_  = width;
00093
00094   if (height)
00095     height_ = height;
00096
00097   if (width || height)
00098     size_ = width_ * height_;
00099 }
00100
00101
00102
00103 
00104 /** colorspace getter
00105  */
00106 colorspace_t
00107 Qualifier::get_colorspace()
00108 {
00109   return colorspace_;
00110 }
00111
00112 
00113 /** colorspace setter
00114  * @param colorspace the colorspace in action
00115  */
00116 void
00117 Qualifier::set_colorspace(colorspace_t colorspace)
00118 {
00119   colorspace_ = colorspace;
00120 }
00121
00122
00123
00124
00125
00126 
00127 /** @class LumaQualifier qualifiers.h <apps/nao_loc/qualifiers.h>
00128  * LumaQualifier for a single pixel.
00129  * Uses the value of the Y-channel
00130  *
00131  * @author Christof Rath
00132  */
00133
00134 
00135 /** Constructor.
00136  * @param buffer containing the image
00137  * @param width of the image
00138  * @param height of the image
00139  * @param colorspace the colorspace in action
00140  */
00141 LumaQualifier::LumaQualifier(unsigned char* buffer, unsigned int width,
00142                              unsigned int height, colorspace_t colorspace)
00143  :Qualifier(buffer, width, height, colorspace)
00144 {
00145 }
00146
00147 
00148 /** Getter.
00149  * @param pixel the pixel of interest
00150  * @return a corresponding int value
00151  */
00152 int
00153 LumaQualifier::get(point_t pixel)
00154 {
00155   if (pixel.x >= width_)
00156     throw fawkes::OutOfBoundsException("LumaQualifier: requested Pixel is out of bounds!", pixel.x, 0, width_);
00157   if (pixel.y >= height_)
00158     throw fawkes::OutOfBoundsException("LumaQualifier: requested Pixel is out of bounds!", pixel.y, 0, height_);
00159
00160   return buffer_[pixel.y * width_ + pixel.x];
00161 }
00162
00163
00164
00165
00166
00167 
00168 /** @class SkyblueQualifier qualifiers.h <apps/nao_loc/qualifiers.h>
00169  * SkyblueQualifier for a single pixel.
00170  * Uses the value of the U/V-channels
00171  *
00172  * @author Christof Rath
00173  */
00174 
00175 /** Constructor.
00176  * @param buffer containing the image
00177  * @param width of the image
00178  * @param height of the image
00179  * @param colorspace the colorspace in action
00180  */
00181 SkyblueQualifier::SkyblueQualifier(unsigned char* buffer, unsigned int width,
00182                                    unsigned int height, colorspace_t colorspace)
00183  :Qualifier(buffer, width, height, colorspace)
00184 {
00185 }
00186
00187 
00188 /** Getter.
00189  * @param pixel the pixel of interest
00190  * @return a corresponding int value
00191  */
00192 int
00193 SkyblueQualifier::get(point_t pixel)
00194 {
00195   if (pixel.x >= width_)
00196     throw fawkes::OutOfBoundsException("SkyblueQualifier: requested Pixel is out of bounds!", pixel.x, 0, width_);
00197   if (pixel.y >= height_)
00198     throw fawkes::OutOfBoundsException("SkyblueQualifier: requested Pixel is out of bounds!", pixel.y, 0, height_);
00199
00200   unsigned int u_addr = size_ + (pixel.y * width_ + pixel.x) / 2;
00201   unsigned char u = buffer_[u_addr];
00202   unsigned char v = 255 - buffer_[u_addr + size_ / 2];
00203
00204   if ((u < threshold_) || (v < threshold_))
00205     return 0;
00206
00207   return u + v;
00208 }
00209
00210
00211
00212
00213
00214 
00215 /** @class YellowQualifier qualifiers.h <apps/nao_loc/qualifiers.h>
00216  * YellowQualifier for a single pixel.
00217  * Uses the value of the U/V-channels
00218  *
00219  * @author Christof Rath
00220  */
00221 
00222 /** Constructor.
00223  * @param buffer containing the image
00224  * @param width of the image
00225  * @param height of the image
00226  * @param colorspace the colorspace in action
00227  */
00228 YellowQualifier::YellowQualifier(unsigned char* buffer, unsigned int width,
00229                                  unsigned int height, colorspace_t colorspace)
00230  :Qualifier(buffer, width, height, colorspace)
00231 {
00232 }
00233
00234 
00235 /** Getter.
00236  * @param pixel the pixel of interest
00237  * @return a corresponding int value
00238  */
00239 int
00240 YellowQualifier::get(point_t pixel)
00241 {
00242   if (pixel.x >= width_)
00243     throw fawkes::OutOfBoundsException("YellowQualifier: requested Pixel is out of bounds!", pixel.x, 0, width_);
00244   if (pixel.y >= height_)
00245     throw fawkes::OutOfBoundsException("YellowQualifier: requested Pixel is out of bounds!", pixel.y, 0, height_);
00246
00247   unsigned int y_addr = (pixel.y * width_ + pixel.x);
00248   unsigned int u_addr = size_ + y_addr / 2;
00249   unsigned char y = buffer_[y_addr];
00250   unsigned int u = (255 - buffer_[u_addr]) * y;
00251   unsigned int v = (255 - abs(127 - buffer_[u_addr + size_ / 2]) * 2) * y;
00252
00253   if ((u <= threshold_) || (v <= threshold_))
00254     return 0;
00255
00256   return (u + v);
00257 }