line_grid.cpp

00001 
00002 /***************************************************************************
00003  *  line_grid.cpp - Implementation of the line grid scanline model
00004  *
00005  *  Created: Wed Mar 25 17:31:00 2009
00006  *  Copyright  2009 Christof Rath <c.rath@student.tugraz.at>
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 <models/scanlines/line_grid.h>
00025 
00026 #include <fvutils/base/roi.h>
00027 #include <fvutils/draw/drawer.h>
00028 #include <core/exceptions/software.h>
00029 
00030 #include <cstring>
00031 
00032 using fawkes::point_t;
00033 
00034 namespace firevision {
00035 #if 0 /* just to make Emacs auto-indent happy */
00036 }
00037 #endif
00038 
00039 /** @class ScanlineLineGrid <models/scanlines/line_grid.h>
00040  * Grid of scan lines.
00041  * A grid of scan lines (i.e. horizontal and/or vertical lines) instead of only
00042  * points on the grid crossings.
00043  * The behavior of the ScanlineGrid (grid.h) class can be modeled if offset_hor
00044  * is set to the same value as offset_x in the Grid class, offset_ver = 0 and
00045  * gap is set to offset_y - 1. The advantage of doing this is a performance gain
00046  * as the LineGrid is pre-calculated and getting the next point is only an
00047  * iterator increment.
00048  */
00049 
00050 /** Constructor.
00051  * @param width Width of grid (most likely equal to image_width)
00052  * @param height Height of grid (most likely equal to image_height)
00053  * @param offset_hor Offset between horizontal lines (set to 0 to get only vertical lines)
00054  * @param offset_ver Offset between vertical lines (set to 0 to get only horizontal lines)
00055  * @param roi The grid will only be calculated within the roi (if NULL the grid gets
00056  *            calculated over the complete width/height).
00057  *            The provided object will be deleted by ScanlineLineGrid!
00058  * @param gap Gap between two points on the line
00059  */
00060 ScanlineLineGrid::ScanlineLineGrid(unsigned int width, unsigned int height,
00061                            unsigned int offset_hor, unsigned int offset_ver,
00062                            ROI* roi, unsigned int gap)
00063 {
00064   __roi = NULL;
00065   __next_pixel = gap + 1;
00066   set_grid_params(width, height,
00067                 offset_hor, offset_ver, roi);
00068   //reset is done in set_grid_params ()
00069 }
00070 
00071 /** Destructor
00072  */
00073 ScanlineLineGrid::~ScanlineLineGrid()
00074 {
00075   delete __roi;
00076 }
00077 
00078 point_t
00079 ScanlineLineGrid::operator*()
00080 {
00081   return *__cur;
00082 }
00083 
00084 point_t*
00085 ScanlineLineGrid::operator->()
00086 {
00087   return &*__cur;
00088 }
00089 
00090 void
00091 ScanlineLineGrid::calc_coords()
00092 {
00093   __point_list.clear();
00094   bool more_to_come = true;
00095   point_t coord;
00096   unsigned int next_px;
00097 
00098   if (__offset_hor > 0) //horizontal lines
00099   {
00100     more_to_come = true;
00101     next_px = std::min(__next_pixel, __offset_ver ? __offset_ver : __width);
00102     coord.x = __roi->start.x;
00103     coord.y = __roi->start.y + ((__roi->height - 1) % __offset_hor) / 2; //Center the horizontal lines in the image
00104     __point_list.push_back(coord);
00105 
00106     while (more_to_come) {
00107       if (coord.x < (__roi->image_width - next_px))
00108       {
00109         coord.x += next_px;
00110       }
00111       else
00112       {
00113         if (coord.y < (__roi->image_height - __offset_hor))
00114         {
00115           coord.x = __roi->start.x;
00116           coord.y += __offset_hor;
00117         }
00118         else
00119         {
00120           more_to_come = false;
00121         }
00122       }
00123 
00124       if (more_to_come) __point_list.push_back(coord);
00125     }
00126   }
00127 
00128   if (__offset_ver > 0) //vertical lines
00129   {
00130     more_to_come = true;
00131     next_px = std::min(__next_pixel, __offset_hor ? __offset_hor : __height);
00132     coord.x = __roi->start.x + ((__roi->width - 1) % __offset_ver) / 2; //Center the vertical lines in the image
00133     coord.y = __roi->start.y;
00134     __point_list.push_back(coord);
00135 
00136     while (more_to_come) {
00137       if (coord.y < (__roi->image_height - next_px))
00138       {
00139         coord.y += next_px;
00140       }
00141       else
00142       {
00143         if (coord.x < (__roi->image_width - __offset_ver))
00144         {
00145           coord.x += __offset_ver;
00146           coord.y = __roi->start.y;
00147         }
00148         else
00149         {
00150           more_to_come = false;
00151         }
00152       }
00153 
00154       if (more_to_come) __point_list.push_back(coord);
00155     }
00156   }
00157 
00158   reset();
00159 }
00160 
00161 point_t *
00162 ScanlineLineGrid::operator++()
00163 {
00164   if (__cur != __point_list.end()) ++__cur;
00165   return __cur != __point_list.end() ? &*__cur : &__point_list.back();
00166 }
00167 
00168 point_t *
00169 ScanlineLineGrid::operator++(int)
00170 {
00171   if (__cur != __point_list.end()) {
00172     point_t *res = &*__cur++;
00173     return res;
00174   }
00175   else return &__point_list.back();
00176 }
00177 
00178 bool
00179 ScanlineLineGrid::finished()
00180 {
00181   return __cur == __point_list.end();
00182 }
00183 
00184 void
00185 ScanlineLineGrid::reset()
00186 {
00187   __cur = __point_list.begin();
00188 }
00189 
00190 const char *
00191 ScanlineLineGrid::get_name()
00192 {
00193   return "ScanlineModel::LineGrid";
00194 }
00195 
00196 
00197 unsigned int
00198 ScanlineLineGrid::get_margin()
00199 {
00200   return std::max(__offset_ver, __offset_hor);
00201 }
00202 
00203 
00204 void
00205 ScanlineLineGrid::set_robot_pose(float x, float y, float ori)
00206 {
00207   // ignored
00208 }
00209 
00210 
00211 void
00212 ScanlineLineGrid::set_pan_tilt(float pan, float tilt)
00213 {
00214   // ignored
00215 }
00216 
00217 
00218 /** Sets the dimensions of the grid.
00219  * Set width and height of scanline grid. Implicitly resets the grid.
00220  *
00221  * @param width Width of grid (most likely equal to image_width)
00222  * @param height Height of grid (most likely equal to image_height)
00223  * @param roi The grid will only be calculated within the roi (if NULL the grid gets
00224  *            calculated over the complete width/height).
00225  *            The provided object will be deleted by ScanlineLineGrid!
00226  */
00227 void
00228 ScanlineLineGrid::set_dimensions(unsigned int width, unsigned int height, ROI* roi)
00229 {
00230   __width  = width;
00231   __height = height;
00232 
00233   set_roi(roi);
00234 }
00235 
00236 /** Sets the region-of-interest.
00237  * @param roi The grid will only be calculated within the roi (if NULL the grid gets
00238  *            calculated over the complete width/height).
00239  *            The provided object will be deleted by ScanlineLineGrid!
00240  */
00241 void
00242 ScanlineLineGrid::set_roi(ROI* roi)
00243 {
00244   delete __roi;
00245 
00246   if (!roi) __roi = new ROI(0, 0, __width, __height, __width, __height);
00247   else
00248   {
00249     __roi = roi;
00250     //Use roi image width/height as grid boundary
00251     __roi->set_image_width(__roi->start.x + __roi->width);
00252     __roi->set_image_height(__roi->start.y + __roi->height);
00253 
00254     if (__roi->image_width > __width)
00255       throw fawkes::OutOfBoundsException("ScanlineLineGrid: ROI is out of grid bounds!", __roi->image_width, 0, __width);
00256     if (__roi->image_height > __height)
00257       throw fawkes::OutOfBoundsException("ScanlineLineGrid: ROI is out of grid bounds!", __roi->image_height, 0, __height);
00258   }
00259 
00260   calc_coords();
00261 }
00262 
00263 /** Sets offset.
00264  * Set horizontal and vertical offset by which the pointer in the grid is advanced.
00265  * This function implicitly resets the grid.
00266  *
00267  * @param offset_hor Offset between horizontal lines (set to 0 to get only vertical lines)
00268  * @param offset_ver Offset between vertical lines (set to 0 to get only horizontal lines)
00269  */
00270 void
00271 ScanlineLineGrid::set_offset(unsigned int offset_hor, unsigned int offset_ver)
00272 {
00273   __offset_hor = offset_hor;
00274   __offset_ver = offset_ver;
00275 
00276   calc_coords();
00277 }
00278 
00279 
00280 /** Set all grid parameters.
00281  * Set width, height, horizontal and vertical offset by which the pointer in the
00282  * grid is advanced.
00283  * Implicitly resets the grid.
00284  *
00285  * @param width Width of grid (most likely equal to image_width)
00286  * @param height Height of grid (most likely equal to image_height)
00287  * @param offset_hor Offset between horizontal lines (set to 0 to get only vertical lines)
00288  * @param offset_ver Offset between vertical lines (set to 0 to get only horizontal lines)
00289  * @param roi The grid will only be calculated within the roi (if NULL the grid gets
00290  *            calculated over the complete width/height).
00291  *            The provided object will be deleted by ScanlineLineGrid!
00292  */
00293 void
00294 ScanlineLineGrid::set_grid_params(unsigned int width, unsigned int height,
00295                             unsigned int offset_hor, unsigned int offset_ver,
00296                             ROI* roi)
00297 {
00298   __offset_hor = offset_hor;
00299   __offset_ver = offset_ver;
00300 
00301   set_dimensions(width, height, roi);
00302 }
00303 
00304 } // end namespace firevision

Generated on Tue Feb 22 13:31:17 2011 for Fawkes API by  doxygen 1.4.7