00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "Component/ModelManager.H"
00039 #include "Image/Image.H"
00040 #include "Image/DrawOps.H"
00041 #include "Image/SimpleFont.H"
00042 #include "Psycho/PsychoOpts.H"
00043 #include "Component/EventLog.H"
00044 #include "Component/ComponentOpts.H"
00045 #include "Util/Types.H"
00046 #include "Util/StringConversions.H"
00047 #include "Util/StringUtil.H"
00048 #include "Media/FrameSeries.H"
00049 #include "Transport/FrameInfo.H"
00050
00051 #include <fstream>
00052
00053 #define HDEG 54.9
00054
00055 typedef struct trial
00056 {
00057 std::string itsClip;
00058 std::string itsQuestion;
00059 std::vector<std::string> itsChoices;
00060 Image<PixRGB<byte> > itsQimage;
00061 Image<PixRGB<byte> > itsSimage;
00062 Image<PixRGB<byte> > itsAimage;
00063 int itsFamily;
00064 uint itsIAnswer;
00065 } SearchTrial;
00066
00067
00068 int submain(const int argc, char** argv)
00069 {
00070
00071
00072
00073
00074
00075 MYLOGVERB = LOG_INFO;
00076
00077
00078 ModelManager manager("Text Search Array");
00079
00080
00081 nub::soft_ref<OutputFrameSeries> ofs(new OutputFrameSeries(manager));
00082 manager.addSubComponent(ofs);
00083
00084
00085 if (manager.parseCommandLine(argc, argv,
00086 "<textfile> visual-angle-of-single-character grid-rows grid-columns <index> <xml-output>",
00087 6,6)==false)
00088 return(1);
00089
00090
00091 manager.start();
00092
00093
00094
00095
00096
00097
00098
00099 std::ifstream *itsFile;
00100 itsFile = new std::ifstream(manager.getExtraArg(0).c_str());
00101
00102
00103 if (itsFile->is_open() == false)
00104 LFATAL("Cannot open '%s' for reading",manager.getExtraArg(0).c_str());
00105
00106
00107 std::string line;
00108 std::string clipstem = "";
00109 std::vector<SearchTrial> expt(100);
00110 uint num_trials = 0, num_stems = 0;
00111 std::vector<uint> curr_stem_index;
00112
00113
00114 while (!itsFile->eof())
00115 {
00116 getline(*itsFile, line, '\n');
00117
00118
00119 if (line[0] == '>')
00120 {
00121 line.erase(0,1);
00122 expt[num_trials].itsClip = line;
00123
00124
00125 if(line.compare(0,line.size()-5,clipstem) != 0)
00126 {
00127 num_stems++;
00128 clipstem = line.substr(0,line.size()-5);
00129 curr_stem_index.push_back(num_trials);
00130 }
00131 expt[num_trials].itsFamily = num_stems;
00132 num_trials++;
00133 }
00134 else if (line[0] == '#')
00135 {
00136 line.erase(0,1);
00137 expt[num_trials-1].itsQuestion = line;
00138 }
00139 else if (line[0] == '!')
00140 {
00141 if(line[1] == '$')
00142 {
00143 line.erase(0,1);
00144 expt[num_trials-1].itsIAnswer = 0;
00145 }
00146 line.erase(0,1);
00147 expt[num_trials-1].itsChoices.push_back(line);
00148 }
00149 else if (line[0] == '$')
00150 {
00151 line.erase(0,1);
00152 expt[num_trials-1].itsIAnswer = expt[num_trials-1].itsChoices.size();
00153 expt[num_trials-1].itsChoices.push_back(line);
00154 }
00155 else if (line[0] == '&')
00156 {
00157
00158 }
00159 else
00160 {
00161 expt[num_trials-1].itsChoices.push_back(line);
00162 }
00163 }
00164 itsFile->close();
00165
00166
00167 int w = 1920;
00168 int h = 1080;
00169
00170 double fontsize = fromStr<double>(manager.getExtraArg(1));
00171 uint fontwidth = uint(fontsize * w / HDEG);
00172 SimpleFont fnt = SimpleFont::fixedMaxWidth(fontwidth);
00173
00174
00175 const uint gridrows = fromStr<uint>(manager.getExtraArg(2));
00176 const uint gridcols = fromStr<uint>(manager.getExtraArg(3));
00177 const uint gridslots = gridrows*gridcols;
00178 std::vector<int> x_coords(gridslots);
00179 std::vector<int> y_coords(gridslots);
00180 for (uint i = 0; i < gridrows; i++)
00181 {
00182 for(uint j = 0; j < gridcols; j++)
00183 {
00184 x_coords[gridcols*i+j] = (int( double(w*(j+1)) / (gridcols+1)));
00185 y_coords[gridcols*i+j] = (int( double(h*(i+1)) / (gridrows+1)));
00186 }
00187 }
00188
00189 Point2D<int> tanchor;
00190
00191 for (uint i = 0; i < num_trials; i++)
00192 {
00193 int space = 0;
00194 int hanchor = int(h/2) - int(fnt.h()/2);
00195 expt[i].itsQimage.resize(w,h);
00196 PixRGB<byte> gr(128,128,128);
00197 expt[i].itsQimage.clear(gr);
00198
00199 space = int( double(w - fnt.w() * expt[i].itsQuestion.size()) / 2.0 );
00200 tanchor = Point2D<int>(space, hanchor);
00201
00202 writeText(expt[i].itsQimage,tanchor,expt[i].itsQuestion.c_str(),
00203 PixRGB<byte>(0,0,0),
00204 gr,
00205 fnt);
00206
00207 expt[i].itsSimage.resize(w,h);
00208 expt[i].itsSimage.clear(gr);
00209 expt[i].itsAimage.resize(w,h);
00210 expt[i].itsAimage.clear(gr);
00211
00212 for (uint j = 0; j < expt[i].itsChoices.size(); j++)
00213 {
00214
00215 if(j >= gridslots)
00216 {
00217 LDEBUG("Trial %d, clip %s: Too many answer choices for the grid", i, expt[i].itsClip.c_str());
00218 break;
00219 }
00220 space = x_coords[j] - int( double(fnt.w() * expt[i].itsChoices[j].length()) / 2.0);
00221 hanchor = y_coords[j] - int(fnt.h()/2);
00222 tanchor = Point2D<int>(space, hanchor);
00223
00224 Point2D<int> center(x_coords[j],y_coords[j]);
00225
00226
00227 writeText(expt[i].itsSimage,tanchor,expt[i].itsChoices[j].c_str(),
00228 PixRGB<byte>(0,0,0),
00229 gr,
00230 fnt);
00231
00232
00233 if(j == expt[i].itsIAnswer)
00234 {
00235 PixRGB<byte> fill(64,192,64);
00236 const Dims rectsize(w/(gridcols+1),h/(gridrows+1));
00237 Point2D<int> rSize(w/(gridcols+1),h/(gridrows+1));
00238 Point2D<int> corner = center-rSize/2;
00239 const Rectangle correctRect(corner,rectsize);
00240
00241
00242 drawFilledRect(expt[i].itsAimage,correctRect,fill);
00243
00244 writeText(expt[i].itsAimage,tanchor,expt[i].itsChoices[j].c_str(),
00245 PixRGB<byte>(0,0,0),
00246 fill, fnt);
00247
00248 }
00249 else
00250 writeText(expt[i].itsAimage,tanchor,expt[i].itsChoices[j].c_str(),
00251 PixRGB<byte>(0,0,0),
00252 gr, fnt);
00253
00254
00255 }
00256
00257
00258 }
00259
00260 const uint questionNum = fromStr<uint>(manager.getExtraArg(4));
00261
00262
00263 if (ofs->becameVoid())
00264 {
00265 LINFO("quitting because output stream was closed or became void");
00266 return 0;
00267 }
00268
00269
00270
00271 ofs->updateNext();
00272
00273
00274 ofs->writeRGB(expt[questionNum].itsQimage, "output",
00275 FrameInfo("Text embedded image",SRC_POS));
00276
00277
00278 ofs->updateNext();
00279 ofs->writeRGB(expt[questionNum].itsSimage, "output",
00280 FrameInfo("Searchtext embedded image", SRC_POS));
00281
00282
00283 ofs->updateNext();
00284 ofs->writeRGB(expt[questionNum].itsAimage, "output",
00285 FrameInfo("Search embedded image with answer", SRC_POS));
00286
00287
00288 manager.stop();
00289
00290
00291 return 0;
00292 }
00293
00294 extern "C" int main(const int argc, char** argv)
00295 {
00296
00297
00298
00299
00300 try
00301 {
00302 return submain(argc, argv);
00303 }
00304 catch (...)
00305 {
00306 REPORT_CURRENT_EXCEPTION;
00307 }
00308
00309 return 1;
00310 }
00311
00312
00313
00314
00315
00316