00001 /*!@file AppMedia/app-autoCam.C */ 00002 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: Lior Elazary 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/AppMedia/app-autoCam.C $ 00035 // $Id: app-autoCam.C 10794 2009-02-08 06:21:09Z itti $ 00036 // 00037 00038 #include "Component/ModelManager.H" 00039 #include "Devices/FrameGrabberConfigurator.H" 00040 #include "Media/FrameSeries.H" 00041 #include "Transport/FrameInfo.H" 00042 #include "Raster/GenericFrame.H" 00043 #include "Image/Image.H" 00044 #include "Image/Pixels.H" 00045 #include "Image/PixelsTypes.H" 00046 #include "Image/DrawOps.H" 00047 #include "Image/ShapeOps.H" 00048 #include "Image/ColorOps.H" 00049 #include "Raster/Raster.H" 00050 #include "Transport/FrameIstream.H" 00051 #include "Neuro/EnvVisualCortex.H" 00052 #include "Util/Timer.H" 00053 #include "Util/Types.H" 00054 #include "Util/log.H" 00055 00056 #include <cstdio> 00057 #include <cstdlib> 00058 #include <cstring> 00059 00060 #define NAVG 20 00061 00062 void findMinMax(const std::vector<int> &vec, double &min, double &max) 00063 { 00064 max = vec[0]; 00065 min = max; 00066 for (uint n = 1 ; n < vec.size() ; n++) 00067 { 00068 if (vec[n] > max) max = vec[n]; 00069 if (vec[n] < min) min = vec[n]; 00070 } 00071 } 00072 00073 std::vector<int> getHistogram(const Image<byte> &lum) 00074 { 00075 std::vector<int> hist(256,0); 00076 for(int i=0; i<lum.getSize(); i++) 00077 hist[lum[i]]++; 00078 00079 return hist; 00080 } 00081 00082 Image<PixRGB<byte> > showHist(const std::vector<int> &hist) 00083 { 00084 int w = 256, h = 256; 00085 if (hist.size() > (uint)w) w = hist.size(); 00086 00087 if (hist.size() == 0) return Image<PixRGB<byte> >(); 00088 00089 int dw = w / hist.size(); 00090 Image<byte> res(w, h, ZEROS); 00091 00092 // draw lines for 10% marks: 00093 for (int j = 0; j < 10; j++) 00094 drawLine(res, Point2D<int>(0, int(j * 0.1F * h)), 00095 Point2D<int>(w-1, int(j * 0.1F * h)), byte(64)); 00096 drawLine(res, Point2D<int>(0, h-1), Point2D<int>(w-1, h-1), byte(64)); 00097 00098 double minii, maxii; 00099 findMinMax(hist, minii, maxii); 00100 00101 // uniform histogram 00102 if (maxii == minii) minii = maxii - 1.0F; 00103 00104 double range = maxii - minii; 00105 00106 for (uint i = 0; i < hist.size(); i++) 00107 { 00108 int t = abs(h - int((hist[i] - minii) / range * double(h))); 00109 00110 // if we have at least 1 pixel worth to draw 00111 if (t < h-1) 00112 { 00113 for (int j = 0; j < dw; j++) 00114 drawLine(res, 00115 Point2D<int>(dw * i + j, t), 00116 Point2D<int>(dw * i + j, h - 1), 00117 byte(255)); 00118 //drawRect(res, Rectangle::tlbrI(t,dw*i,h-1,dw*i+dw-1), byte(255)); 00119 } 00120 } 00121 return res; 00122 } 00123 00124 double getMSV(const std::vector<int>& hist) 00125 { 00126 00127 double topSum=0, sum=0; 00128 00129 double h[4]; 00130 for(int i=0; i<4; i++) 00131 h[i] = 0; 00132 00133 for(uint i=0; i<hist.size(); i++) 00134 h[i/(256/4)] += hist[i]; 00135 00136 for(int i=0; i<4; i++) 00137 { 00138 topSum += (i+1)*h[i]; 00139 sum += h[i]; 00140 } 00141 00142 return topSum/sum; 00143 } 00144 00145 int contrastCtrl(double cVal, double dVal) 00146 { 00147 double k=0; 00148 return (int)((dVal-cVal)*k); 00149 } 00150 00151 int brightCtrl(double cVal, double dVal) 00152 { 00153 double k=100; 00154 return (int)((dVal-cVal)*k); 00155 } 00156 00157 /*! This simple executable tests video frame grabbing through the 00158 video4linux driver (see V4Lgrabber.H) or the IEEE1394 (firewire) 00159 grabber (see IEEE1394grabber.H). Selection of the grabber type is 00160 made via the --fg-type=XX command-line option. */ 00161 int main(const int argc, const char **argv) 00162 { 00163 // instantiate a model manager: 00164 ModelManager manager("Frame Grabber Tester"); 00165 00166 nub::ref<EnvVisualCortex> evc(new EnvVisualCortex(manager)); 00167 manager.addSubComponent(evc); 00168 00169 // Instantiate our various ModelComponents: 00170 nub::soft_ref<FrameGrabberConfigurator> 00171 gbc(new FrameGrabberConfigurator(manager)); 00172 manager.addSubComponent(gbc); 00173 00174 nub::ref<OutputFrameSeries> ofs(new OutputFrameSeries(manager)); 00175 manager.addSubComponent(ofs); 00176 00177 00178 // Parse command-line: 00179 if (manager.parseCommandLine(argc, argv, "", 0, 0) == false) return(1); 00180 00181 // do post-command-line configs: 00182 nub::soft_ref<FrameIstream> gb = gbc->getFrameGrabber(); 00183 if (gb.isInvalid()) 00184 LFATAL("You need to select a frame grabber type via the " 00185 "--fg-type=XX command-line option for this program " 00186 "to be useful"); 00187 00188 // let's get all our ModelComponent instances started: 00189 manager.start(); 00190 00191 // get ready for main loop: 00192 Timer tim; uint64 t[NAVG]; int frame = 0; 00193 00194 // get the frame grabber to start streaming: 00195 gb->startStream(); 00196 00197 00198 int count = 0; 00199 char* buf = new char[9999]; 00200 00201 int cont = 20000; 00202 int bright = 20000; 00203 while(1) { 00204 count++; 00205 tim.reset(); 00206 00207 Image< PixRGB<byte> > ima = gb->readRGB(); 00208 sprintf(buf, "frame%d.png", count); 00209 00210 uint64 t0 = tim.get(); // to measure display time 00211 ofs->writeRGB(ima, "image", FrameInfo("image", SRC_POS)); 00212 t[frame % NAVG] = tim.get(); 00213 t0 = t[frame % NAVG] - t0; 00214 if (t0 > 20000ULL) LINFO("Display took %lluus", t0); 00215 00216 //evc->input(ima); 00217 //Image<byte> smap = evc->getVCXmap(); 00218 00219 Image<byte> smap = luminance(ima); 00220 00221 std::vector<int> hist = getHistogram(smap); 00222 Image<PixRGB<byte> > histImg = showHist(hist); 00223 ofs->writeRGB(histImg, "hist", FrameInfo("hist", SRC_POS)); 00224 ofs->writeRGB(rescale(smap, ima.getDims()), "smap", FrameInfo("smap", SRC_POS)); 00225 00226 double histVal = getMSV(hist); 00227 00228 cont += contrastCtrl(histVal, 2.5); 00229 bright += brightCtrl(histVal, 2.5); 00230 00231 LINFO("MSV %f cont %i bright %i", histVal, cont, bright); 00232 00233 gb->setModelParamVal("FrameGrabberBrightness", bright, MC_RECURSE); 00234 //gb->setModelParamVal("FrameGrabberContrast", cont, MC_RECURSE); 00235 00236 // compute and show framerate over the last NAVG frames: 00237 if (frame % NAVG == 0 && frame > 0) 00238 { 00239 uint64 avg = 0ULL; for (int i = 0; i < NAVG; i ++) avg += t[i]; 00240 float avg2 = 1000.0F / float(avg) * float(NAVG); 00241 printf("Framerate: %.1f fps\n", avg2); 00242 } 00243 frame ++; 00244 } 00245 00246 // stop all our ModelComponents 00247 manager.stop(); 00248 00249 // all done! 00250 return 0; 00251 } 00252 00253 // ###################################################################### 00254 /* So things look consistent in everyone's emacs... */ 00255 /* Local Variables: */ 00256 /* indent-tabs-mode: nil */ 00257 /* End: */