test-parseScanpath.C

Go to the documentation of this file.
00001 /*!@file AppPsycho/test-parseScanpath.C Parses the eye scanpath and recognizes
00002   each fixation */
00003 
00004 // ////////////////////////////////////////////////////////////////////
00005 // // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C)
00006 // 2000-2002 // by the University of Southern California (USC)
00007 // and the iLab at USC.  // See http://iLab.usc.edu for
00008 // information about this project.  //
00009 // ////////////////////////////////////////////////////////////////////
00010 // // Major portions of the iLab Neuromorphic Vision Toolkit
00011 // are protected // under the U.S. patent ``Computation of
00012 // Intrinsic Perceptual Saliency // in Visual Environments,
00013 // and Applications'' by Christof Koch and // Laurent Itti,
00014 // California Institute of Technology, 2001 (patent //
00015 // pending; application number 09/912,225 filed July 23, 2001;
00016 // see // http://pair.uspto.gov/cgi-bin/final/home.pl for
00017 // current status).  //
00018 // ////////////////////////////////////////////////////////////////////
00019 // // This file is part of the iLab Neuromorphic Vision C++
00020 // Toolkit.  // // The iLab Neuromorphic Vision C++ Toolkit is
00021 // free software; you can // redistribute it and/or modify it
00022 // under the terms of the GNU General // Public License as
00023 // published by the Free Software Foundation; either //
00024 // version 2 of the License, or (at your option) any later
00025 // version.  // // The iLab Neuromorphic Vision C++ Toolkit is
00026 // distributed in the hope // that it will be useful, but
00027 // WITHOUT ANY WARRANTY; without even the // implied warranty
00028 // of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE.
00029 // See the GNU General Public License for more details.  // //
00030 // You should have received a copy of the GNU General Public
00031 // License // along with the iLab Neuromorphic Vision C++
00032 // Toolkit; if not, write // to the Free Software Foundation,
00033 // Inc., 59 Temple Place, Suite 330, // Boston, MA 02111-1307
00034 // USA.  //
00035 // ////////////////////////////////////////////////////////////////////
00036 // //
00037 //
00038 // Primary maintainer for this file: Vidhya Navalpakkam <navalpak@usc.edu>
00039 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/AppPsycho/test-parseScanpath.C $
00040 // $Id: test-parseScanpath.C 9412 2008-03-10 23:10:15Z farhan $
00041 //
00042 
00043 #include "Image/Image.H"
00044 #include "Image/DrawOps.H"
00045 #include "Component/ModelManager.H"
00046 #include "Image/Pixels.H"
00047 #include "Image/Point2D.H"
00048 #include "Raster/Raster.H"
00049 #include "Util/log.H"
00050 
00051 #include <cstdlib>
00052 #include <ctime>
00053 #include <fstream>
00054 #include <string>
00055 #include <unistd.h>
00056 #include <vector>
00057 
00058 int main(const int argc, const char **argv)
00059 {
00060   MYLOGVERB = LOG_INFO;  // suppress debug messages
00061 
00062   // Instantiate a ModelManager:
00063   ModelManager manager("parse scanpath");
00064 
00065   // Parse command-line:
00066   if (manager.parseCommandLine(argc, argv,
00067                                "<input.ppm> <rows> <columns> <coordsFile>"
00068                                " <fixnsFile> <reco> <traj.ppm>"
00069                                " <saccadeEndPoints>"
00070                                " <target> <less> <same> <more>"
00071                                " <'d' for draw / 'r' for recognize /"
00072                                " 'g' for generate stimuli>",
00073                                1, -1) == false)
00074     return(1);
00075 
00076   // let's get all our ModelComponent instances started:
00077   manager.start();
00078 
00079   // ------------------ READ INPUT --------------------------
00080   // get the arguments
00081   int rows = manager.getExtraArgAs<int>(1);
00082   int cols = manager.getExtraArgAs<int>(2);
00083   const char* coords = manager.getExtraArg (3).c_str();
00084   const char* fixns = manager.getExtraArg (4).c_str();
00085   const char* reco = manager.getExtraArg (5).c_str();
00086   const char* output = manager.getExtraArg (6).c_str();
00087   const char* saccTargets = manager.getExtraArg (7).c_str();
00088   const char* targetName = manager.getExtraArg (8).c_str();
00089   const char* lessName = manager.getExtraArg (9).c_str();
00090   const char* sameName = manager.getExtraArg (10).c_str();
00091   const char* moreName = manager.getExtraArg (11).c_str();
00092   const char* option = manager.getExtraArg (12).c_str();
00093 
00094   // ------------------ INITIALIZE PARAMS -------------------------
00095   if (option[0] == 'd')
00096     {
00097       Image<PixRGB< byte> > traj =
00098         Raster::ReadRGB(manager.getExtraArg (0));
00099       // draw the scanpath
00100       LINFO (" image grid: %d x %d", cols, rows);
00101       int w = traj.getWidth();
00102       int h = traj.getHeight();
00103       // box size in the grid
00104       int bw = w / cols;
00105       int bh = h / rows;
00106       // draw the grid
00107           // draw the horizontal lines
00108       for (int i = 1; i < rows; i++)
00109         {
00110           Point2D<int> start (0, i * bh), end (w, i * bh);
00111           drawLine (traj, start, end, PixRGB<byte>(128, 128, 128), 1);
00112         }
00113       // draw the vertical lines
00114       for (int i = 1; i < cols; i++)
00115         {
00116           Point2D<int> start (i * bw, 0), end (i * bw, h);
00117           drawLine (traj, start, end, PixRGB<byte>(128, 128, 128), 1);
00118         }
00119 
00120       // draw the scanpath
00121       std::ifstream fil (coords);
00122       if (fil == 0) LFATAL ("Couldn't open the coords file: %s", coords);
00123       // read all the coords
00124       std::string line;
00125       std::vector< std::string > xy;
00126       while (getline (fil, line))
00127         {
00128           int x_idx = line.find (" ");
00129           std::string x = line.substr (0, x_idx);
00130           line = line.substr (x_idx + 1);
00131           int y_idx = line.find (" ");
00132           std::string y = line.substr (0,  y_idx - 1);
00133           xy.push_back (x);
00134           xy.push_back (y);
00135         }
00136 
00137       // set some loop params
00138       Point2D<int> prev_fixn (-1, -1);
00139       for (uint i = 0; i < xy.size(); i = i + 2)
00140         {
00141           Point2D<int> fixn (atoi (xy[i].c_str()), atoi (xy[i+1].c_str()));
00142           drawCircle(traj, fixn, 2, PixRGB<byte>(255, 0, 0) , 2);
00143           if (i != 0)
00144             drawLine(traj, prev_fixn, fixn, PixRGB<byte>(255, 255, 0), 1);
00145           prev_fixn = fixn;
00146         }
00147 
00148       // draw fixations
00149       std::ifstream fix (fixns);
00150       if (fix == 0) LFATAL ("Couldn't open the fixations file: %s", fixns);
00151       xy.clear();
00152       while (getline (fix, line))
00153         {
00154           int x_idx = line.find (" ");
00155           std::string x = line.substr (0, x_idx);
00156           line = line.substr (x_idx + 1);
00157           int y_idx = line.find (" ");
00158           std::string y = line.substr (0,  y_idx - 1);
00159           xy.push_back (x);
00160           xy.push_back (y);
00161         }
00162       // draw saccade targets
00163       std::ifstream sac (saccTargets);
00164       if (sac == 0) LFATAL ("Couldn't open the saccade targets file: %s",
00165                             saccTargets);
00166       xy.clear();
00167       while (getline (sac, line))
00168         {
00169           int x_idx = line.find (" ");
00170           std::string x = line.substr (0, x_idx);
00171           line = line.substr (x_idx + 1);
00172           int y_idx = line.find (" ");
00173           std::string y = line.substr (0,  y_idx - 1);
00174           xy.push_back (x);
00175           xy.push_back (y);
00176         }
00177       for (uint i = 0; i < xy.size(); i = i + 2)
00178         {
00179           Point2D<int> sacEndPt (atoi (xy[i].c_str()), atoi (xy[i+1].c_str()));
00180           drawCircle(traj, sacEndPt, 2, PixRGB<byte>(0, 255, 0) , 4);
00181         }
00182       Raster::WriteRGB (traj, output, RASFMT_PNM);
00183     }
00184   //***************** GENERATE STIMULI AND DRAW SCANPATHS *******************
00185   if (option[0] == 'g')
00186     {
00187       Image<PixRGB< byte> > traj =
00188         Raster::ReadRGB(manager.getExtraArg (0));
00189       // draw the scanpath
00190       LINFO (" image grid: %d x %d", cols, rows);
00191       int w = traj.getWidth();
00192       int h = traj.getHeight();
00193       // box size in the grid
00194       int bw = w / cols;
00195       int bh = h / rows;
00196       // draw the grid
00197           // draw the horizontal lines
00198       for (int i = 1; i < rows; i++)
00199         {
00200           Point2D<int> start (0, i * bh), end (w, i * bh);
00201           drawLine (traj, start, end, PixRGB<byte>(128, 128, 128), 1);
00202         }
00203       // draw the vertical lines
00204       for (int i = 1; i < cols; i++)
00205         {
00206           Point2D<int> start (i * bw, 0), end (i * bw, h);
00207           drawLine (traj, start, end, PixRGB<byte>(128, 128, 128), 1);
00208         }
00209       // mark each cell in the grid with less/mid/high
00210       std::ifstream rec (reco);
00211       if (rec == 0) LFATAL  ("Couldn't open the reco file: %s", reco);
00212       std::string line;
00213       while (getline (rec, line))
00214         {
00215           char msg[2];
00216           int idx = line.find_last_of (" ");
00217           std::string itemName = line.substr (idx + 1);
00218           line = line.substr (0, idx);
00219           idx = line.find_last_of (" ");
00220           int y = atoi (line.substr (idx + 1).c_str());
00221           line = line.substr (0, idx);
00222           idx = line.find_last_of (" ");
00223           int x = atoi (line.substr (idx + 1).c_str());
00224           if (itemName.find(targetName,0) != std::string::npos)
00225             sprintf (msg, "T");
00226           if (itemName.find(lessName,0) != std::string::npos)
00227             sprintf (msg, "L");
00228           if (itemName.find(sameName,0) != std::string::npos)
00229             sprintf (msg, "M");
00230           if (itemName.find(moreName,0) != std::string::npos)
00231             sprintf (msg, "H");
00232           writeText (traj, Point2D<int>(x,y), msg,PixRGB<byte>(255),PixRGB<byte>(0));
00233         }
00234       // draw the scanpath
00235       std::ifstream fil (coords);
00236       if (fil == 0) LFATAL ("Couldn't open the coords file: %s", coords);
00237       // read all the coords
00238       std::vector< std::string > xy;
00239       while (getline (fil, line))
00240         {
00241           int x_idx = line.find (" ");
00242           std::string x = line.substr (0, x_idx);
00243           line = line.substr (x_idx + 1);
00244           int y_idx = line.find (" ");
00245           std::string y = line.substr (0,  y_idx - 1);
00246           xy.push_back (x);
00247           xy.push_back (y);
00248         }
00249 
00250       // set some loop params
00251       Point2D<int> prev_fixn (-1, -1);
00252       for (uint i = 0; i < xy.size(); i = i + 2)
00253         {
00254           Point2D<int> fixn (atoi (xy[i].c_str()), atoi (xy[i+1].c_str()));
00255           drawCircle(traj, fixn, 2, PixRGB<byte>(255, 0, 0) , 2);
00256           if (i != 0)
00257             drawLine(traj, prev_fixn, fixn, PixRGB<byte>(255, 255, 0), 1);
00258           prev_fixn = fixn;
00259         }
00260 
00261       // draw fixations
00262       std::ifstream fix (fixns);
00263       if (fix == 0) LFATAL ("Couldn't open the fixations file: %s", fixns);
00264       xy.clear();
00265       while (getline (fix, line))
00266         {
00267           int x_idx = line.find (" ");
00268           std::string x = line.substr (0, x_idx);
00269           line = line.substr (x_idx + 1);
00270           int y_idx = line.find (" ");
00271           std::string y = line.substr (0,  y_idx - 1);
00272           xy.push_back (x);
00273           xy.push_back (y);
00274         }
00275       /*
00276       for (uint i = 0; i < xy.size(); i = i + 2)
00277         {
00278           Point2D<int> fixn (atoi (xy[i].c_str()), atoi (xy[i+1].c_str()));
00279           drawCircle(traj, fixn, 2, PixRGB<byte>(0, 0, 255) , 4);
00280         }
00281       */
00282       // draw saccade targets
00283       std::ifstream sac (saccTargets);
00284       if (sac == 0) LFATAL ("Couldn't open the saccade targets file: %s",
00285                             saccTargets);
00286       xy.clear();
00287       while (getline (sac, line))
00288         {
00289           int x_idx = line.find (" ");
00290           std::string x = line.substr (0, x_idx);
00291           line = line.substr (x_idx + 1);
00292           int y_idx = line.find (" ");
00293           std::string y = line.substr (0,  y_idx - 1);
00294           xy.push_back (x);
00295           xy.push_back (y);
00296         }
00297       for (uint i = 0; i < xy.size(); i = i + 2)
00298         {
00299           Point2D<int> sacEndPt (atoi (xy[i].c_str()), atoi (xy[i+1].c_str()));
00300           drawCircle(traj, sacEndPt, 2, PixRGB<byte>(0, 255, 0) , 4);
00301         }
00302       Raster::WriteRGB (traj, output, RASFMT_PNM);
00303     }
00304 
00305   //***************** RECOGNIZE SACCADIC ENDPOINTS *********************
00306   else if (option[0] == 'r')
00307     {
00308       // recognize the fixations
00309       std::ifstream rec (reco);
00310       if (rec == 0) LFATAL  ("Couldn't open the reco file: %s", reco);
00311       /* 6 distractors: s2, s3, m2, m3, n2, n3
00312          4 item sper distractor
00313          x, y per item
00314       */
00315       int d[3][8][2], t[2];
00316       t[0] = 0; t[1] = 0; // avoid compiler warning
00317       //initialize the distances
00318       for (int i = 0; i < 3; i++)
00319         for (int j = 0; j < 8; j++){
00320           d[i][j][0] = 1024;d[i][j][1]=1024;
00321         }
00322       std::string line;
00323       int num[3];
00324       for (int i = 0; i < 3; i ++)
00325         num[i] = 0; // initialize
00326 
00327        while (getline (rec, line))
00328         {
00329           int idx = line.find_last_of (" ");
00330           std::string itemName = line.substr (idx + 1);
00331           line = line.substr (0, idx);
00332           idx = line.find_last_of (" ");
00333           int y = atoi (line.substr (idx + 1).c_str());
00334           line = line.substr (0, idx);
00335           idx = line.find_last_of (" ");
00336           int x = atoi (line.substr (idx + 1).c_str());
00337           //LINFO ("item %s at (%d, %d)", itemName.c_str(), x, y);
00338           if (itemName.find(targetName,0) != std::string::npos)
00339             {
00340               t[0] = x;
00341               t[1] = y;
00342             }
00343           if (itemName.find(lessName,0) != std::string::npos)
00344             {
00345               d[0][num[0]][0] = x;
00346               d[0][num[0]][1] = y;
00347               num[0] += 1;
00348             }
00349           if (itemName.find(sameName,0) != std::string::npos)
00350             {
00351               d[1][num[1]][0] = x;
00352               d[1][num[1]][1] = y;
00353               num[1] += 1;
00354             }
00355           if (itemName.find(moreName,0) != std::string::npos)
00356             {
00357               d[2][num[2]][0] = x;
00358               d[2][num[2]][1] = y;
00359               num[2] += 1;
00360             }
00361         }
00362        int score[4], count[4]; float nearest[4];
00363        // 3 types of dtarctors, 1 target
00364        for (int i = 0; i < 4; i ++){
00365          score[i] = 0; count[i] = 0; nearest[i] = 1024.0f;
00366        }
00367        std::ifstream sac (saccTargets);
00368        if (sac == 0) LFATAL ("Couldn't open the saccade targets file: %s",
00369                              saccTargets);
00370        // read all the saccade targets
00371        int numFix = 1;
00372        // distance to the nearest category
00373        float minD = 1024.0f;
00374 
00375        while (getline (sac, line))
00376          {
00377            // recognize the current fixn
00378            // score: 1 for the nearest item, 0 for others
00379            int idx = line.find_last_of (" ");
00380            int y = atoi (line.substr (idx + 1).c_str());
00381            int x = atoi (line.substr (0, idx).c_str());
00382            // find distance btw fixn and distractors
00383            for (int i = 0; i < 3; i ++)
00384              for (int j = 0; j < 8; j ++)
00385                {
00386                  float dist = sqrt ((d[i][j][0] - x)*(d[i][j][0] - x) +
00387                                     (d[i][j][1] - y)*(d[i][j][1] - y));
00388                  if (dist < nearest[i])
00389                    nearest[i] = dist;
00390                }
00391           // distance btw target and fixn
00392           nearest[3] = sqrt ((t[0] - x)*(t[0] - x) + (t[1] - y)*(t[1] - y));
00393 
00394           // find the nearest category
00395           for (int i = 0; i < 4; i ++)
00396             if (nearest[i] < minD)
00397               minD = nearest[i];
00398 
00399           // check if there are multiple nearest items
00400           for (int i = 0; i < 4; i ++){
00401             if (nearest[i] == minD) count[i] ++;
00402             // assign the fixation to the nearest category
00403             score[i] += count[i];
00404           }
00405           // display the results of the current fixn.
00406           //LINFO ("fix%d: %f %f %f %f", numFix, nearest[0],
00407           //     nearest[1], nearest[2],nearest[3]);
00408           LINFO ("fix%d: %d %d %d %d", numFix, count[0],
00409                  count[1], count[2], count[3]);
00410 
00411           numFix ++;
00412           // reset count values
00413           for (int i  = 0; i < 4; i ++){
00414             count[i] = 0; nearest[i] = 1024.0f;
00415           }
00416           // reset distance to the nearest category
00417           minD = 1024.0f;
00418          }
00419        // display cumulative results
00420        LINFO ("total: %d %d %d %d", score[0], score[1],
00421               score[2], score[3]);
00422 
00423     }
00424   manager.stop();
00425   manager.saveConfig();
00426 
00427 }
00428 
00429 // ######################################################################
00430 /* So things look consistent in everyone's emacs... */
00431 /* Local Variables: */
00432 /* indent-tabs-mode: nil */
00433 /* End: */
Generated on Sun May 8 08:40:11 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3