00001 /*!@file Image/OmniOps.C Operations for omnidirectional correction 00002 */ 00003 00004 // //////////////////////////////////////////////////////////////////// // 00005 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the // 00006 // University of Southern California (USC) and the iLab at USC. // 00007 // See http://iLab.usc.edu for information about this project. // 00008 // //////////////////////////////////////////////////////////////////// // 00009 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00010 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00011 // in Visual Environments, and Applications'' by Christof Koch and // 00012 // Laurent Itti, California Institute of Technology, 2001 (patent // 00013 // pending; application number 09/912,225 filed July 23, 2001; see // 00014 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00015 // //////////////////////////////////////////////////////////////////// // 00016 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00017 // // 00018 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00019 // redistribute it and/or modify it under the terms of the GNU General // 00020 // Public License as published by the Free Software Foundation; either // 00021 // version 2 of the License, or (at your option) any later version. // 00022 // // 00023 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00024 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00025 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00026 // PURPOSE. See the GNU General Public License for more details. // 00027 // // 00028 // You should have received a copy of the GNU General Public License // 00029 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00030 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00031 // Boston, MA 02111-1307 USA. // 00032 // //////////////////////////////////////////////////////////////////// // 00033 // 00034 // Primary maintainer for this file: Rob Peters <rjpeters@klab.caltech.edu> 00035 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Image/OmniOps.C $ 00036 // $Id: OmniOps.C 9412 2008-03-10 23:10:15Z farhan $ 00037 // 00038 00039 #ifndef IMAGE_OMNI_C_DEFINED 00040 #define IMAGE_OMNI_C_DEFINED 00041 00042 #include "Image/OmniOps.H" 00043 00044 #include "Image/Image.H" 00045 #include "Image/Pixels.H" 00046 00047 #include <cmath> 00048 #include <iostream> 00049 00050 // ###################################################################### 00051 template <class T> 00052 void lowPassPixel(Image<T>& src, 00053 const int x, const int y, const int radius) 00054 { 00055 int startX = x - radius, endX = x + radius; 00056 int startY = y - radius, endY = y + radius; 00057 T sum = T(); int n = 0; 00058 if (startX < 0) startX = 0; 00059 if (endX > src.getWidth() - 1) endX = src.getWidth() - 1; 00060 if (startY < 0) startY = 0; 00061 if (endY > src.getHeight() - 1) endY = src.getHeight() - 1; 00062 for (int xx = startX; xx < endX ; xx++) 00063 for(int yy = startY; yy < endY; yy++) 00064 { sum += src.getVal(xx, yy); n ++; } 00065 sum /= n; 00066 src.setVal(x, y, sum); 00067 } 00068 00069 // ###################################################################### 00070 template <class T> 00071 Image<PixRGB<T> > omniCorrectGen(const Image<PixRGB<T> >& src, 00072 const int Rx, const int Ry, 00073 const int Xc, const int Yc, 00074 const int RA) 00075 { 00076 Point2D<int> oldPoint, point; 00077 float newX = 0.0F, newY = 0.0F, absX, absY; 00078 bool negX, negY, noPix, stop; 00079 00080 PixRGB<T> value; 00081 // result has same size as input: 00082 Image<PixRGB<T> > result(src.getDims(), NO_INIT); 00083 00084 Dims dims = src.getDims(); 00085 00086 for (int x = 0; x < dims.w(); x++) 00087 { 00088 std::cout << "."; 00089 for(int y = 0; y < dims.h(); y++) 00090 { 00091 noPix = false; stop = false; oldPoint.i = x; oldPoint.j = y; 00092 // Fix circular boundary: 00093 absX = fabs(Rx - x); //find distance from center in X 00094 absY = fabs(Ry - y); //find distance from center in Y 00095 if (x < Xc) negX = true; else negX = false; 00096 if (y < Yc) negY = true; else negY = false; 00097 // find ratio factor for x: 00098 if ((absY <= Ry) && (absY != 0)) 00099 newX = sqrt(1.0 - pow((absY / (Ry + RA)), 2.0)); 00100 else 00101 noPix = true; 00102 //find ratio factor for y: 00103 if((absX <= Rx) && (!noPix) && (absX != 0)) 00104 newY = sqrt(1.0 - pow((absX / (Rx + RA)), 2)); 00105 else 00106 noPix = true; 00107 00108 if(noPix) 00109 { 00110 value = src.getVal(oldPoint); 00111 result.setVal(oldPoint, value); 00112 } 00113 else 00114 { 00115 if ((x != 0) && (newX != 0)) 00116 newX = absX / newX; // finish X pixel 00117 else 00118 { 00119 value = src.getVal(oldPoint); 00120 result.setVal(oldPoint,value); 00121 stop = true; 00122 } 00123 if ((y != 0) && (newY != 0)) 00124 newY = absY / newY; // finish Y pixel 00125 else 00126 { 00127 value = src.getVal(oldPoint); 00128 result.setVal(oldPoint,value); 00129 stop = true; 00130 } 00131 if (stop == false) 00132 { 00133 if (negX) newX = Xc - newX; else newX = Xc + newX; 00134 if (negY) newY = Yc - newY; else newY = Yc + newY; 00135 point.i = (int)newX; point.j = (int)newY; 00136 value = src.getVal(oldPoint); // get value of old pixel 00137 00138 // assure circular bound: 00139 if (point.i < dims.w() && point.j < dims.h()) 00140 { 00141 // translate value to new pixel coordinate 00142 if (point.i >= 0 && point.j >= 0) 00143 result.setVal(point, value); 00144 } 00145 } 00146 } 00147 } 00148 } 00149 00150 return result; 00151 } 00152 00153 // ###################################################################### 00154 template <class T> 00155 Image<PixRGB<T> > omniCorrectSp(const Image<PixRGB<T> >& src, 00156 const float r, 00157 const float hh, const float kk, 00158 const int /*Rx*/, const int /*Ry*/, 00159 const int Xc, const int Yc) 00160 { 00161 // bool noPix = false; // FIXME noPix is unused...? 00162 00163 // result has same size as input image: 00164 Image<PixRGB<T> > result(src.getDims(), NO_INIT); 00165 00166 for(int x = 0; x < src.getWidth(); ++x) 00167 for(int y = 0; y < src.getHeight(); ++y) 00168 { 00169 // FIXME the absX/absY variables are unused...? 00170 // int absX = abs(Rx - x); // find distance from center in X 00171 // int absY = abs(Ry - y); // find distance from center in Y 00172 bool negX = (x < Xc); 00173 bool negY = (y < Yc); 00174 00175 // FIXME things may be bungled here because the 'hh' parameter used to 00176 // be called 'h', which conflicted with the data member 'h' 00177 int newX = int(-(sqrt(-pow((x - kk), 2.0) + pow(r, 2.0)) - hh)); 00178 int newY = int(-(sqrt(-pow((y - kk), 2.0) + pow(r, 2.0)) - hh)); 00179 00180 if (negX) newX = -newX; 00181 if (negY) newY = -newY; 00182 00183 PixRGB<T> value = src.getVal(x, y); // get value of old pixel 00184 result.setVal(newX, newY, value); // translate to new pixel coordinate 00185 } 00186 00187 return result; 00188 } 00189 00190 // ###################################################################### 00191 template <class T> 00192 Image<PixRGB<T> > omniDenebulize(const Image< PixRGB<T> >& src, 00193 const int radius) 00194 { 00195 Image<PixRGB<T> > result = src; 00196 00197 for (int x = 0; x < src.getWidth(); ++x) 00198 for (int y = 0; y < src.getHeight(); ++y) 00199 { 00200 PixRGB<T> pix = src.getVal(x,y); 00201 if((pix.red() < T(1)) && // FIXME why 1 here but 0 in the monochrome 00202 // version?? 00203 (pix.green() < T(1)) && 00204 (pix.blue() < T(1))) 00205 lowPassPixel(result, x, y, radius); 00206 } 00207 00208 return result; 00209 } 00210 00211 // ###################################################################### 00212 template <class T> 00213 Image<T> omniDenebulize(const Image<T>& src, const int radius) 00214 { 00215 Image<T> result = src; 00216 00217 for (int x = 0; x < src.getWidth(); ++x) 00218 for (int y = 0; y < src.getHeight(); ++y) 00219 if (src.getVal(x, y) == T(0)) 00220 lowPassPixel(result, x, y, radius); 00221 00222 return result; 00223 } 00224 00225 // Include the explicit instantiations 00226 #include "inst/Image/OmniOps.I" 00227 00228 // ###################################################################### 00229 /* So things look consistent in everyone's emacs... */ 00230 /* Local Variables: */ 00231 /* indent-tabs-mode: nil */ 00232 /* End: */ 00233 00234 #endif // !IMAGE_OMNI_C_DEFINED