00001 /*!@file Devices/VectorField.C implementation of vector histogram 00002 field algorithm routines */ 00003 // //////////////////////////////////////////////////////////////////// // 00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the // 00005 // University of Southern California (USC) and the iLab at USC. // 00006 // See http://iLab.usc.edu for information about this project. // 00007 // //////////////////////////////////////////////////////////////////// // 00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00010 // in Visual Environments, and Applications'' by Christof Koch and // 00011 // Laurent Itti, California Institute of Technology, 2001 (patent // 00012 // pending; application number 09/912,225 filed July 23, 2001; see // 00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00014 // //////////////////////////////////////////////////////////////////// // 00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00016 // // 00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00018 // redistribute it and/or modify it under the terms of the GNU General // 00019 // Public License as published by the Free Software Foundation; either // 00020 // version 2 of the License, or (at your option) any later version. // 00021 // // 00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00025 // PURPOSE. See the GNU General Public License for more details. // 00026 // // 00027 // You should have received a copy of the GNU General Public License // 00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00030 // Boston, MA 02111-1307 USA. // 00031 // //////////////////////////////////////////////////////////////////// // 00032 // 00033 // Primary maintainer for this file: farhan baluch fbaluch@usc.edu 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Image/VectorField.C $ 00035 // $Id: VectorField.C 12962 2010-03-06 02:13:53Z irock $ 00036 // 00037 00038 #include "Image/VectorField.H" 00039 #include "Component/OptionManager.H" 00040 #include "Devices/Serial.H" 00041 #include "Image/DrawOps.H" 00042 #include "Image/ShapeOps.H" 00043 #include <iterator> 00044 00045 00046 // ###################################################################### 00047 VectorField::VectorField(OptionManager& mgr, const std::string& descrName, 00048 const std::string& tagName, const int width, 00049 const int height) : 00050 ModelComponent(mgr, descrName, tagName) 00051 { 00052 itsDims = Dims(width,height); 00053 itsField = Image<geom::vec2f> (itsDims,NO_INIT); 00054 itsGoalField = Image<geom::vec2f>(itsDims,NO_INIT); 00055 00056 geom::vec2f tmp; 00057 tmp.set_polar_rad(20.0,geom::deg2rad(90.0)); 00058 itsField.clear(tmp); 00059 00060 LINFO("vector field initialized"); 00061 } 00062 00063 00064 // ###################################################################### 00065 VectorField::~VectorField() 00066 { } 00067 00068 // ###################################################################### 00069 Image<geom::vec2f> VectorField::getField() 00070 { 00071 return itsField; 00072 00073 } 00074 00075 // ###################################################################### 00076 Image<PixRGB<byte> > VectorField::plotField(int spacing) 00077 { 00078 00079 Image<PixRGB<byte> > result(itsDims.w(),itsDims.h(),ZEROS); 00080 00081 Image<geom::vec2f>::iterator itr = itsField.beginw(); 00082 00083 int idx= 0; 00084 00085 while(itr!=itsField.endw()) 00086 { 00087 Point2D<int> startPt, endPt; 00088 startPt.i = idx % (itsDims.w()); 00089 startPt.j = (int)idx/(itsDims.w()); 00090 geom::vec2f tmp = *itr; 00091 00092 if((idx > spacing*itsDims.w()) && (startPt.i % spacing == 0) 00093 && (startPt.j % spacing ==0)) 00094 { 00095 endPt.i = startPt.i + tmp.x(); 00096 endPt.j = startPt.j + tmp.y(); 00097 if(result.coordsOk(startPt) && result.coordsOk(endPt)) 00098 { 00099 drawLine(result, startPt, endPt,PixRGB<byte>(0,255,0),1); 00100 drawDisk(result, startPt, 2, PixRGB<byte>(255,0,0)); 00101 } 00102 } 00103 else 00104 { 00105 // drawPoint(result, idx % itsDims.w(), idx/itsDims.w(), 00106 // PixRGB<byte>(0,255,0) ); 00107 } 00108 itr++; 00109 idx++; 00110 } 00111 00112 // lets also draw the vectors pointing to obstacles detected 00113 for(uint i=0; i<itsSensorData.size();i++) 00114 { 00115 geom::vec2f tmp; 00116 tmp.set_polar_rad(itsSensorData[i].i,geom::deg2rad(itsSensorData[i].j)); 00117 Point2D<int> center(tmp.x()+itsRobotPos.i, itsRobotPos.j - tmp.y()); 00118 drawLine(result,itsRobotPos,center,PixRGB<byte> (0,0,255),1); 00119 } 00120 return result; 00121 } 00122 00123 00124 // ###################################################################### 00125 Image<PixRGB<byte> > VectorField::plotGridField(int spacing) 00126 { 00127 Image<PixRGB<byte> > result(itsDims.w()*spacing,itsDims.h()*spacing,ZEROS); 00128 00129 //first draw grid on this image 00130 drawGrid(result, spacing, spacing, 1, 1, PixRGB<byte>(255,0,0)); 00131 Image<geom::vec2f>::iterator itr = itsField.beginw(); 00132 00133 int idx= 0; 00134 while(itr!=itsField.endw()) 00135 { 00136 Point2D<int> vecImg,startPt, endPt; 00137 vecImg.i = idx % (itsDims.w()); 00138 vecImg.j = (int)idx/(itsDims.w()); 00139 geom::vec2f tmp = *itr; 00140 00141 startPt.i = vecImg.i*spacing + spacing/2; 00142 startPt.j = vecImg.j*spacing + spacing/2; 00143 00144 endPt.i = startPt.i + tmp.x(); 00145 endPt.j = startPt.j + tmp.y(); 00146 00147 if(result.coordsOk(startPt) && result.coordsOk(endPt)) 00148 { 00149 drawLine(result, startPt, endPt,PixRGB<byte>(0,255,0),1); 00150 drawDisk(result, startPt, 2, PixRGB<byte>(255,0,0)); 00151 } 00152 00153 itr++; 00154 idx++; 00155 } 00156 00157 Point2D<int> robotPos; 00158 robotPos.i = itsRobotPos.i*spacing + spacing/2; 00159 robotPos.j = itsRobotPos.j*spacing + spacing/2; 00160 00161 drawCircle(result, robotPos,5,PixRGB<byte>(150,255,0),1); 00162 00163 // lets also draw the vectors pointing to obstacles detected 00164 for(uint i=0; i<itsSensorData.size();i++) 00165 { 00166 geom::vec2f tmp; 00167 tmp.set_polar_rad(itsSensorData[i].i,geom::deg2rad(itsSensorData[i].j)); 00168 Point2D<int> center(tmp.x() + itsRobotPos.i, itsRobotPos.j - tmp.y()); 00169 00170 //center.i = center.i + itsRobotPos.i; 00171 //center.j = itsRobotPos.j - center.j; 00172 00173 center.i = center.i*spacing + spacing/2; 00174 center.j = center.j*spacing + spacing/2; 00175 drawLine(result,robotPos,center,PixRGB<byte> (255,255,255),1); 00176 } 00177 return result; 00178 } 00179 00180 // ###################################################################### 00181 geom::vec2f VectorField::getVectorAt(Point2D<int> location) 00182 { 00183 return itsField.getVal(location.i,location.j); 00184 } 00185 00186 00187 // ###################################################################### 00188 void VectorField::setVectorAt(Point2D<int> location, geom::vec2f val) 00189 { 00190 itsField.setVal(location.i,location.j,val); 00191 } 00192 00193 00194 // ###################################################################### 00195 00196 //!scaleby -- scale vector field by factor 00197 void VectorField::scaleFieldBy(float factor) 00198 { 00199 Image<geom::vec2f>::iterator aptr = itsField.beginw(); 00200 while(aptr != itsField.end()) 00201 { 00202 geom::vec2f tmp = *aptr; 00203 tmp.scale_by(factor); 00204 *aptr++= tmp; 00205 } 00206 } 00207 00208 00209 // ###################################################################### 00210 00211 //!scaleby -- scale vector field by factor 00212 void VectorField::scaleGoalFieldBy(float factor) 00213 { 00214 Image<geom::vec2f>::iterator aptr = itsGoalField.beginw(); 00215 while(aptr != itsGoalField.end()) 00216 { 00217 geom::vec2f tmp = *aptr; 00218 tmp.scale_by(factor); 00219 *aptr++= tmp; 00220 } 00221 } 00222 // ###################################################################### 00223 void VectorField::makeUnitLength() 00224 { 00225 Image<geom::vec2f>::iterator aptr = itsField.beginw(); 00226 00227 while(aptr != itsField.end()) 00228 { 00229 geom::vec2f tmp = *aptr; 00230 *aptr++ = make_unit_length(tmp); 00231 } 00232 00233 } 00234 00235 // ###################################################################### 00236 void VectorField::normalizeTo(float maxFactor) 00237 { 00238 Image<geom::vec2f>::iterator aptr = itsField.beginw(); 00239 00240 while(aptr != itsField.end()) 00241 { 00242 geom::vec2f tmp = *aptr; 00243 *aptr++= tmp/=maxFactor; 00244 } 00245 00246 } 00247 00248 00249 // ###################################################################### 00250 void VectorField::rotateField(float angle) 00251 { 00252 //rotate the image 00253 itsField = rotate(itsField,itsRobotPos.i,itsRobotPos.j,geom::deg2rad(angle)); 00254 //rotate individual vectors 00255 00256 Image<geom::vec2f>::iterator aptrF; 00257 geom::vec2f tmp; 00258 aptrF = itsField.beginw(); 00259 while(aptrF != itsField.end()) 00260 { 00261 tmp = *aptrF; 00262 tmp.rotate_deg(angle); 00263 *aptrF++ = tmp; 00264 } 00265 00266 } 00267 00268 00269 // ###################################################################### 00270 void VectorField::rotateGoalField(float angle) 00271 { 00272 //since we have a general goal direction only no need to rotate 00273 //entire field just individual vectos 00274 00275 //rotate individual vectors 00276 Image<geom::vec2f>::iterator aptrF; 00277 geom::vec2f tmp; 00278 aptrF = itsGoalField.beginw(); 00279 while(aptrF != itsGoalField.end()) 00280 { 00281 tmp = *aptrF; 00282 tmp.rotate_deg(angle); 00283 *aptrF++ = tmp; 00284 } 00285 00286 } 00287 00288 00289 // ###################################################################### 00290 /* So things look consistent in everyone's emacs... */ 00291 /* Local Variables: */ 00292 /* indent-tabs-mode: nil */ 00293 /* End: */