00001 /*!@file AppPsycho/searcharray.C create a randomized search array from two image patches */ 00002 00003 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/AppPsycho/searcharray.C $ 00004 // $Id: searcharray.C 7157 2006-09-15 07:55:58Z itti $ 00005 00006 #include "Util/Assert.H" 00007 #include "Image/Image.H" 00008 #include "Image/Pixels.H" 00009 #include "Raster/Raster.H" 00010 #include "Util/log.H" 00011 00012 #include <cstdlib> 00013 #include <ctime> 00014 #include <iostream> 00015 #include <unistd.h> 00016 00017 //! Spacing between elements as a factor of their size: 00018 #define FACTOR 1.2 00019 00020 void image_patch(const Image< PixRGB<byte> >& patch, const int ti, 00021 const int tj, Image< PixRGB<byte> >& image, 00022 const double alpha, Image<byte>& targets, bool do_target); 00023 00024 00025 /*! This program generates a randomized search array (and associated 00026 target mask) from two image patches (for target and distractors). */ 00027 00028 int main(const int argc, const char **argv) 00029 { 00030 if (argc != 7) 00031 { 00032 std::cerr<<"USAGE: searcharray <patch1.ppm> <patch2.ppm> <w> <alpha> "; 00033 std::cerr<<"<noise> <result>"<<std::endl; 00034 exit(1); 00035 } 00036 int w = atoi(argv[3]); float alpha = atof(argv[4]); 00037 float noise = atof(argv[5]); 00038 initRandomNumbers(); 00039 00040 // read in the patches: 00041 Image<PixRGB<byte> > patch1 = Raster::ReadRGB(argv[1]); 00042 Image<PixRGB<byte> > patch2 = Raster::ReadRGB(argv[2]); 00043 00044 int pw = patch1.getWidth(), ph = patch1.getHeight(); 00045 ASSERT(pw == patch2.getWidth() && ph == patch2.getHeight()); 00046 00047 // initialize results: 00048 Image<PixRGB<byte> > image(w, w, ZEROS); 00049 Image<byte> targets(w, w, ZEROS); 00050 00051 int ti = 1 + int(randomDouble() * floor(w / (FACTOR * pw) * 0.999 - 2.0)); 00052 int tj = 1 + int(randomDouble() * floor(w / (FACTOR * ph) * 0.999 - 2.0)); 00053 LINFO("-- TARGET AT (%d, %d)", ti, tj); 00054 00055 for (int j = 0; j < int(w / (FACTOR * ph)); j++) 00056 for (int i = 0; i < int(w / (FACTOR * pw)); i++) 00057 if (i == ti && j == tj) 00058 image_patch(patch2, ti, tj, image, alpha, targets, 1); 00059 else 00060 image_patch(patch1, i, j, image, alpha, targets, 0); 00061 00062 /* add noise */ 00063 Image< PixRGB<byte> >::iterator iptr = image.beginw(), stop = image.endw(); 00064 while(iptr != stop) 00065 { 00066 if (randomDouble() <= noise) 00067 { 00068 if (randomDouble() >= 0.5) iptr->setRed(255); else iptr->setRed(0); 00069 if (randomDouble() >= 0.5) iptr->setGreen(255); else iptr->setGreen(0); 00070 if (randomDouble() >= 0.5) iptr->setBlue(255); else iptr->setBlue(0); 00071 } 00072 iptr ++; 00073 } 00074 00075 Raster::WriteRGB(image, argv[6], RASFMT_PNM); 00076 Raster::WriteGray(targets, argv[6], RASFMT_PNM); 00077 00078 return 0; 00079 } 00080 00081 // ###################################################################### 00082 void image_patch(const Image< PixRGB<byte> >& patch, const int ti, 00083 const int tj, Image< PixRGB<byte> >& image, 00084 const double alpha, Image<byte>& targets, bool do_target) 00085 { 00086 int pw = patch.getWidth(), ph = patch.getHeight(); 00087 int w = image.getWidth(); 00088 00089 int jitx = int(randomDouble() * (FACTOR - 1.0) * pw); 00090 int jity = int(randomDouble() * (FACTOR - 1.0) * ph); 00091 00092 float jita = float(alpha * 3.14159 / 180.0 * (randomDouble() - 0.5) * 2.0); 00093 int offset = int(w - floor(w / (pw * FACTOR)) * (pw * FACTOR)) / 2; 00094 00095 PixRGB<byte> zero(0, 0, 0); 00096 int px = 0, py = 0; 00097 00098 for (double y = int(tj * ph * FACTOR); y < int(tj * ph * FACTOR + ph); y ++) 00099 { 00100 for (double x = int(ti * pw * FACTOR); x < int(ti * pw * FACTOR + pw); x ++) 00101 { 00102 int x2 = int(x + jitx + offset); 00103 int y2 = int(y + jity + offset); 00104 00105 /* Shifting back and forth the center of rotation.*/ 00106 double px2 = px - pw / 2.0F; 00107 double py2 = py - ph / 2.0F; 00108 00109 float px3 = float(cos(jita) * px2 + sin(jita) * py2 + pw / 2.0F); 00110 float py3 = float(-sin(jita) * px2 + cos(jita) * py2 + pw / 2.0F); 00111 00112 if (px3 < 0 || px3 >= pw || py3 < 0 || py3 >= ph ) 00113 image.setVal(x2, y2, zero); 00114 else 00115 { 00116 image.setVal(x2, y2, patch.getValInterp(px3, py3)); 00117 if (do_target) 00118 { 00119 if (patch.getVal(int(px3), int(py3)) == zero) 00120 targets.setVal(x2, y2, 0); 00121 else 00122 targets.setVal(x2, y2, 255); 00123 } 00124 } 00125 px ++; 00126 } 00127 py ++; 00128 px = 0; 00129 } 00130 } 00131 00132 // ###################################################################### 00133 /* So things look consistent in everyone's emacs... */ 00134 /* Local Variables: */ 00135 /* indent-tabs-mode: nil */ 00136 /* End: */