00001 /*!@file AppPsycho/searcharray2.C create a randomized search array from image patches */ 00002 00003 // //////////////////////////////////////////////////////////////////// // 00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2002 // 00005 // by the 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: Laurent Itti <itti@usc.edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/AppPsycho/searcharray2.C $ 00035 // $Id: searcharray2.C 7157 2006-09-15 07:55:58Z itti $ 00036 // 00037 00038 #include "Util/Assert.H" 00039 #include "Image/Image.H" 00040 #include "Image/Pixels.H" 00041 #include "Raster/Raster.H" 00042 #include "Util/log.H" 00043 00044 #include <cstdlib> 00045 #include <ctime> 00046 #include <iostream> 00047 #include <unistd.h> 00048 00049 //! Spacing between elements as a factor of their size: 00050 // Added lines for t2i and t2j, indices for second target 00051 #define FACTOR 1.5 00052 00053 void image_patch(const Image< PixRGB<byte> >& patch, const int ti, 00054 const int tj, Image< PixRGB<byte> >& image, 00055 const double alpha, Image<byte>& targets, bool do_target); 00056 00057 00058 /*! This program generates a randomized search array (and associated 00059 target mask) from two image patches (for target and distractors). */ 00060 00061 int main(const int argc, const char **argv) 00062 { 00063 if (argc != 10) 00064 { 00065 std::cerr<<"USAGE: searcharray <patch1.ppm> <patch2.ppm> <patch3.ppm> <patch4.ppm> <patch5.ppm> "; 00066 std::cerr<<"<w> <alpha> <noise> <result>"<<std::endl; 00067 exit(1); 00068 } 00069 int w = atoi(argv[3]); float alpha = atof(argv[4]); 00070 float noise = atof(argv[5]); 00071 initRandomNumbers(); 00072 00073 // read in the patches: 00074 Image<PixRGB<byte> > patch1 = Raster::ReadRGB(argv[1]); 00075 Image<PixRGB<byte> > patch2 = Raster::ReadRGB(argv[2]); 00076 Image<PixRGB<byte> > patch3 = Raster::ReadRGB(argv[7]); 00077 Image<PixRGB<byte> > patch4 = Raster::ReadRGB(argv[8]); 00078 Image<PixRGB<byte> > patch5 = Raster::ReadRGB(argv[9]); 00079 00080 int pw = patch1.getWidth(), ph = patch1.getHeight(); 00081 00082 ASSERT(pw == patch2.getWidth() && ph == patch2.getHeight()); 00083 ASSERT(pw == patch3.getWidth() && ph == patch3.getHeight()); //all targets equal size 00084 ASSERT(pw == patch4.getWidth() && ph == patch4.getHeight()); 00085 ASSERT(pw == patch5.getWidth() && ph == patch5.getHeight()); 00086 00087 // initialize results: 00088 Image<PixRGB<byte> > image(w, w, ZEROS); 00089 Image<byte> targets(w, w, ZEROS); 00090 00091 int ti = 1 + int(randomDouble() * floor(w / (FACTOR * pw) * 0.999 - 2.0)); 00092 int tj = 1 + int(randomDouble() * floor(w / (FACTOR * ph) * 0.999 - 2.0)); 00093 LINFO("-- FIRST TARGET AT (%d, %d)", ti, tj); 00094 00095 // Create second target: 00096 00097 int t2i = 1 + int(randomDouble() * floor(w / (FACTOR * pw) * 0.999 - 2.0)); 00098 int t2j = 1 + int(randomDouble() * floor(w / (FACTOR * ph) * 0.999 - 2.0)); 00099 LINFO("-- SECOND TARGET AT (%d, %d)", t2i, t2j); 00100 00101 for (int j = 0; j < int(w / (FACTOR * ph)); j++) 00102 for (int i = 0; i < int(w / (FACTOR * pw)); i++) 00103 if (i == ti && j == tj) 00104 image_patch(patch2, ti, tj, image, alpha, targets, 1); 00105 else if (i == t2i && j ==t2j) 00106 image_patch(patch3, t2i, t2j, image, alpha, targets, 1); 00107 else if (randomUpToNotIncluding(3) == 0) 00108 image_patch(patch1, i, j, image, alpha, targets, 0); 00109 else if (randomUpToNotIncluding(3) == 1) 00110 image_patch(patch4, i, j, image, alpha, targets, 0); 00111 else 00112 image_patch(patch5, i, j, image, alpha, targets, 0); 00113 00114 /* add noise */ 00115 Image< PixRGB<byte> >::iterator iptr = image.beginw(), stop = image.endw(); 00116 while(iptr != stop) 00117 { 00118 if (randomDouble() <= noise) 00119 { 00120 if (randomDouble() >= 0.5) iptr->setRed(255); else iptr->setRed(0); 00121 if (randomDouble() >= 0.5) iptr->setGreen(255); else iptr->setGreen(0); 00122 if (randomDouble() >= 0.5) iptr->setBlue(255); else iptr->setBlue(0); 00123 } 00124 iptr ++; 00125 } 00126 00127 Raster::WriteRGB(image, argv[6], RASFMT_PNM); 00128 Raster::WriteGray(targets, argv[6], RASFMT_PNM); 00129 00130 return 0; 00131 } 00132 00133 // ###################################################################### 00134 void image_patch(const Image< PixRGB<byte> >& patch, const int ti, 00135 const int tj, Image< PixRGB<byte> >& image, 00136 const double alpha, Image<byte>& targets, bool do_target) 00137 { 00138 int pw = patch.getWidth(), ph = patch.getHeight(); 00139 int w = image.getWidth(); 00140 00141 int jitx = int(randomDouble() * (FACTOR - 1.0) * pw); 00142 int jity = int(randomDouble() * (FACTOR - 1.0) * ph); 00143 00144 float jita = float(alpha * 3.14159 / 180.0 * (randomDouble() - 0.5) * 2.0); 00145 int offset = int(w - floor(w / (pw * FACTOR)) * (pw * FACTOR)) / 2; 00146 00147 PixRGB<byte> zero(0, 0, 0); 00148 int px = 0, py = 0; 00149 00150 for (double y = int(tj * ph * FACTOR); y < int(tj * ph * FACTOR + ph); y ++) 00151 { 00152 for (double x = int(ti * pw * FACTOR); x < int(ti * pw * FACTOR + pw); x ++) 00153 { 00154 int x2 = int(x + jitx + offset); 00155 int y2 = int(y + jity + offset); 00156 00157 /* Shifting back and forth the center of rotation.*/ 00158 double px2 = px - pw / 2.0F; 00159 double py2 = py - ph / 2.0F; 00160 00161 float px3 = float(cos(jita) * px2 + sin(jita) * py2 + pw / 2.0F); 00162 float py3 = float(-sin(jita) * px2 + cos(jita) * py2 + pw / 2.0F); 00163 00164 if (px3 < 0 || px3 >= pw || py3 < 0 || py3 >= ph ) 00165 image.setVal(x2, y2, zero); 00166 else 00167 { 00168 image.setVal(x2, y2, patch.getValInterp(px3, py3)); 00169 if (do_target) 00170 { 00171 if (patch.getVal(int(px3), int(py3)) == zero) 00172 targets.setVal(x2, y2, 0); 00173 else 00174 targets.setVal(x2, y2, 255); 00175 } 00176 } 00177 px ++; 00178 } 00179 py ++; 00180 px = 0; 00181 } 00182 } 00183 00184 // ###################################################################### 00185 /* So things look consistent in everyone's emacs... */ 00186 /* Local Variables: */ 00187 /* indent-tabs-mode: nil */ 00188 /* End: */