histogram_block.cpp

00001
00002 /***************************************************************************
00003  *  histogram_block.cpp - Histogram block
00004  *
00005  *  Created: Sat Mar 29 21:01:35 2008
00006  *  Copyright  2008  Daniel Beck
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 <fvutils/statistical/histogram_block.h>
00025 #include <core/exceptions/software.h>
00026 #include <cstring>
00027
00028 using namespace fawkes;
00029 
00030 /** @class HistogramBlock fvutils/statistical/histogram_block.h
00031  * This class defines a file block for histograms. Additionally, the very basic routines
00032  * to acccess and manipulate data in the histograms are provided.
00033  * @author Daniel Beck
00034  */
00035
00036 
00037 /** Constructor.
00038  * @param type the type of the histogram block
00039  * @param object_type the object type this histogram is meant for (e.g, ball)
00040  * @param width the width of the histogram
00041  * @param height the height of the histogram
00042  * @param depth the depth of the histogram
00043  */
00044 HistogramBlock::HistogramBlock(histogram_block_type_t type, hint_t object_type,
00045                                uint16_t width, uint16_t height, uint16_t depth)
00046   : FireVisionDataFileBlock(type, width * height * depth * sizeof(uint32_t),
00047                             sizeof(histogram_block_header_t))
00048 {
00049   _block_header = (histogram_block_header_t*) _spec_header;
00050   _block_header->width = width;
00051   _block_header->height = height;
00052   _block_header->depth = depth;
00053   _block_header->object_type = object_type;
00054
00055   _histogram_data = (uint32_t*) _data;
00056 }
00057 
00058 /** Copy constructor.
00059  * @param block another block
00060  */
00061 HistogramBlock::HistogramBlock(FireVisionDataFileBlock* block)
00062   : FireVisionDataFileBlock(block)
00063 {
00064   _block_header = (histogram_block_header_t*) _spec_header;
00065   _histogram_data = (uint32_t*) _data;
00066 }
00067 
00068 /** Destructor. */
00069 HistogramBlock::~HistogramBlock()
00070 {
00071 }
00072 
00073 /** Returns the the width of the histogram.
00074  * @return the width of the histogram
00075  */
00076 uint16_t
00077 HistogramBlock::width() const
00078 {
00079   return _block_header->width;
00080 }
00081 
00082 /** Returns the the height of the histogram.
00083  * @return the height of the histogram
00084  */
00085 uint16_t
00086 HistogramBlock::height() const
00087 {
00088   return _block_header->height;
00089 }
00090 
00091 /** Returns the the depth of the histogram.
00092  * @return the depth of the histogram
00093  */
00094 uint16_t
00095 HistogramBlock::depth() const
00096 {
00097   return _block_header->depth;
00098 }
00099 
00100 /** Returns the type of the object the histogram is associated with.
00101  * @return the object type of the histogram
00102  */
00103 hint_t
00104 HistogramBlock::object_type() const
00105 {
00106   return (hint_t) _block_header->object_type;
00107 }
00108 
00109 /** Set the type of the object the histogram is associated with.
00110  * @param object_type the new type of the object
00111  */
00112 void
00113 HistogramBlock::set_object_type(hint_t object_type)
00114 {
00115   _block_header->object_type = object_type;
00116 }
00117 
00118 /** Directly set the histogram data.
00119  * Note: You are reponsible that the data has the right size and format!
00120  * @param data pointer to the histogram data
00121  */
00122 void
00123 HistogramBlock::set_data(uint32_t* data)
00124 {
00125   memcpy(_data, data, _data_size);
00126 }
00127 
00128 /** Store a value in a certain cell of a 2-dimensional histogram.
00129  * @param x the x-coordinate
00130  * @param y the y-coordinate
00131  * @param val the new value
00132  */
00133 void
00134 HistogramBlock::set_value(uint16_t x, uint16_t y, uint32_t val)
00135 {
00136   if (_block_header->depth != 0)
00137     { throw Exception("Trying to acces a 3-dim histogram with a 2-dim access method"); }
00138
00139   if (x >= _block_header->width)
00140     {
00141       throw OutOfBoundsException("Given x value is too large (set_value, 2)",
00142                                  float(x), 0.0f, float(_block_header->width));
00143     }
00144
00145   if (y >= _block_header->height)
00146     {
00147       throw OutOfBoundsException("Given y value is too large (set_value, 2)",
00148                                  float(y), 0.0f, float(_block_header->height));
00149     }
00150
00151   _histogram_data[y * _block_header->width + x] = val;
00152 }
00153 
00154 /** Store a value in a certain cell of a 3-dimensional histogram.
00155  * @param x the x-coordinate
00156  * @param y the y-coordinate
00157  * @param z the z-coordinate
00158  * @param val the new value
00159  */
00160 void
00161 HistogramBlock::set_value(uint16_t x, uint16_t y, uint16_t z, uint32_t val)
00162 {
00163   if ( x >= _block_header->width)
00164     {
00165       throw OutOfBoundsException("Given x value is too large (set_value, 3)",
00166                                  float(x), 0.0f, float(_block_header->width));
00167     }
00168
00169   if ( y >= _block_header->height)
00170     {
00171       throw OutOfBoundsException("Given y value is too large (set_value, 3)",
00172                                  float(y), 0.0f, float(_block_header->height));
00173     }
00174
00175   if ( z >= _block_header->depth)
00176     {
00177       throw OutOfBoundsException("Given z value is too large (set_value, 3)",
00178                                  float(z), 0.0f, float(_block_header->depth));
00179     }
00180
00181   _histogram_data[z * _block_header->width * _block_header->height + y * _block_header->width + x] = val;
00182 }
00183 
00184 /** Obtain a certain value from a 2-dimensional histogram.
00185  * @param x the x-coordinate
00186  * @param y the y-coordinate
00187  * @return the histogram value
00188  */
00189 uint32_t
00190 HistogramBlock::get_value(uint16_t x, uint16_t y)
00191 {
00192   if (_block_header->depth != 0)
00193     { throw Exception("Trying to acces a 3-dim histogram with a 2-dim access method"); }
00194
00195   if ( x >= _block_header->width)
00196     {
00197       throw OutOfBoundsException("Given x value is too large (get_value, 2)",
00198                                  float(x), 0.0f, float(_block_header->width));
00199     }
00200
00201   if ( y >= _block_header->height)
00202     {
00203       throw OutOfBoundsException("Given y value is too large (get_value, 2)",
00204                                  float(y), 0.0f, float(_block_header->height));
00205     }
00206
00207   return _histogram_data[y * _block_header->width + x];
00208 }
00209 
00210 /** Obtain a certain value from a 3-dimensional histogram.
00211  * @param x the x-coordinate
00212  * @param y the y-coordinate
00213  * @param z the z-coordinate
00214  * @return the histogram value
00215  */
00216 uint32_t
00217 HistogramBlock::get_value(uint16_t x, uint16_t y, uint16_t z)
00218 {
00219   if ( x >= _block_header->width)
00220     {
00221       throw OutOfBoundsException("Given x value is too large (get_value, 3)",
00222                                  float(x), 0.0f, _block_header->width - 1);
00223     }
00224
00225   if ( y >= _block_header->height)
00226     {
00227       throw OutOfBoundsException("Given y value is too large (get_value, 3)",
00228                                  float(y), 0.0f, _block_header->height - 1);
00229     }
00230
00231   if ( z >= _block_header->depth)
00232     {
00233       throw OutOfBoundsException("Given z value is too large (get_value, 3)",
00234                                  float(z), 0.0f, _block_header->depth - 1);
00235     }
00236
00237   return _histogram_data[z * _block_header->width * _block_header->height + y * _block_header->width + x];
00238 }
00239 
00240 /** Reset the histogram. */
00241 void
00242 HistogramBlock::reset()
00243 {
00244   memset(_histogram_data, 0, _data_size);
00245 }