Fawkes API Fawkes Development Version
|
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