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 #ifndef APPNEURO_TEST_INTCHANNEL_C_DEFINED
00039 #define APPNEURO_TEST_INTCHANNEL_C_DEFINED
00040
00041 #include "Channels/BlueYellowChannel.H"
00042 #include "Channels/ChannelOpts.H"
00043 #include "Channels/ColorChannel.H"
00044 #include "Channels/DirectionChannel.H"
00045 #include "Channels/FlickerChannel.H"
00046 #include "Channels/GaborChannel.H"
00047 #include "Channels/IntegerInput.H"
00048 #include "Channels/IntegerMathEngine.H"
00049 #include "Channels/IntegerOrientationChannel.H"
00050 #include "Channels/IntegerSimpleChannel.H"
00051 #include "Channels/IntensityChannel.H"
00052 #include "Channels/MotionChannel.H"
00053 #include "Channels/OrientationChannel.H"
00054 #include "Channels/RedGreenChannel.H"
00055 #include "Channels/SingleChannel.H"
00056 #include "Component/ModelManager.H"
00057 #include "Component/ModelOptionDef.H"
00058 #include "Image/ColorOps.H"
00059 #include "Image/Image.H"
00060 #include "Image/ImageSet.H"
00061 #include "Image/IntegerMathOps.H"
00062 #include "Image/MathOps.H"
00063 #include "Image/Pixels.H"
00064 #include "Image/PyrBuilder.H"
00065 #include "Image/PyramidCache.H"
00066 #include "Image/PyramidOps.H"
00067 #include "Image/ShapeOps.H"
00068 #include "Media/FrameSeries.H"
00069 #include "Neuro/NeuroOpts.H"
00070 #include "Channels/RawVisualCortex.H"
00071 #include "Channels/IntegerRawVisualCortex.H"
00072 #include "Raster/GenericFrame.H"
00073 #include "Raster/Raster.H"
00074 #include "Transport/FrameInfo.H"
00075 #include "Util/Pause.H"
00076 #include "Util/csignals.H"
00077 #include "rutz/time.h"
00078
00079 #include <map>
00080
00081 static const ModelOptionDef OPT_ALIASsaveall =
00082 { MODOPT_ALIAS, "ALIASsaveall", &MOC_DISPLAY, OPTEXP_SAVE,
00083 "Default save option for test-intChannel",
00084 "saveall", '\0', "",
00085 "--save-channel-outputs --save-vcx-output" };
00086
00087 namespace
00088 {
00089 struct ChannelCorrcoefData
00090 {
00091 ChannelCorrcoefData() : sum(0.0), n(0) {}
00092
00093 void add(double d) { sum += d; ++n; }
00094
00095 double sum;
00096 int n;
00097 };
00098
00099 std::map<IntegerChannel*, ChannelCorrcoefData> ccdata;
00100
00101 void compareChannels(int c,
00102 IntegerChannel& ic,
00103 ChannelBase& fc)
00104 {
00105 IntegerComplexChannel* icc =
00106 dynamic_cast<IntegerComplexChannel*>(&ic);
00107
00108 if (icc != 0)
00109 {
00110 ComplexChannel* fcc =
00111 dynamic_cast<ComplexChannel*>(&fc);
00112
00113 ASSERT(icc->numChans() == fcc->numChans());
00114
00115 for (uint i = 0; i < icc->numChans(); ++i)
00116 compareChannels(c, *(icc->subChan(i)), *(fcc->subChan(i)));
00117 }
00118
00119 float fmi, fma; getMinMax(fc.getOutput(), fmi, fma);
00120 int imi, ima; getMinMax(ic.getOutputInt(), imi, ima);
00121
00122 const double cc = corrcoef(fc.getOutput(),
00123 Image<float>(ic.getOutputInt()));
00124 LINFO("%06d corrcoef(%-20s,%-20s) = %.4f, "
00125 "frange = %.2e .. %.2e, irange = %.2e .. %.2e, imax/fmax = %.2e",
00126 c, fc.tagName().c_str(), ic.tagName().c_str(), cc,
00127 fmi, fma, float(imi), float(ima), float(ima) / fma);
00128
00129 ccdata[&ic].add(cc);
00130 }
00131 }
00132
00133
00134 int submain(int argc, const char** argv)
00135 {
00136 volatile int signum = 0;
00137 catchsignals(&signum);
00138
00139 IntgTrigTable<256, 8> trig;
00140
00141 ModelManager manager("test-intChannel");
00142
00143 OModelParam<IntegerDecodeType> decodeType
00144 (&OPT_IntInputDecode, &manager);
00145
00146
00147 nub::ref<InputFrameSeries> ifs(new InputFrameSeries(manager));
00148 manager.addSubComponent(ifs);
00149
00150 nub::ref<OutputFrameSeries> ofs(new OutputFrameSeries(manager));
00151 manager.addSubComponent(ofs);
00152
00153 nub::ref<RawVisualCortex> fvc(new RawVisualCortex(manager));
00154 manager.addSubComponent(fvc);
00155
00156 nub::ref<IntegerMathEngine> ieng(new IntegerMathEngine(manager));
00157 manager.addSubComponent(ieng);
00158
00159 nub::ref<IntegerRawVisualCortex> ivc(new IntegerRawVisualCortex(manager, ieng));
00160 manager.addSubComponent(ivc);
00161
00162 REQUEST_OPTIONALIAS_CHANNEL(manager);
00163 manager.requestOptionAlias(&OPT_ALIASsaveall);
00164
00165 manager.setOptionValString(&OPT_MaxNormType, "Maxnorm");
00166 manager.setOptionValString(&OPT_DirectionChannelLowThresh, "0");
00167 manager.setOptionValString(&OPT_IntChannelScaleBits, "16");
00168 manager.setOptionValString(&OPT_IntMathLowPass5, "lp5optim");
00169 manager.setOptionValString(&OPT_IntMathLowPass9, "lp9optim");
00170
00171
00172 if (manager.parseCommandLine(argc, argv, "?prof-only?", 0, 1) == false)
00173 return(1);
00174
00175 const bool profOnly =
00176 manager.numExtraArgs() > 0 ? manager.getExtraArgAs<bool>(0) : false;
00177
00178 manager.start();
00179
00180 LINFO("using %u bits for integer arithmetic", ieng->getNbits());
00181
00182 LINFO("using '%s' decoding algorithm",
00183 convertToString(decodeType.getVal()).c_str());
00184
00185 int c = 0;
00186
00187 PauseWaiter p;
00188
00189 SimTime t;
00190
00191 rutz::time iruser, irsys, fruser, frsys;
00192
00193 PyramidCache<int> cache;
00194
00195 while (true)
00196 {
00197 if (signum != 0)
00198 {
00199 LINFO("quitting because %s was caught", signame(signum));
00200 break;
00201 }
00202
00203 t += SimTime::HERTZ(30);
00204
00205 if (p.checkPause())
00206 continue;
00207
00208 const FrameState is = ifs->updateNext();
00209 if (is == FRAME_COMPLETE)
00210 break;
00211
00212 GenericFrame input = ifs->readFrame();
00213 if (!input.initialized())
00214 break;
00215
00216 const FrameState os = ofs->updateNext();
00217
00218 rutz::time u1 = rutz::time::user_rusage();
00219 rutz::time s1 = rutz::time::sys_rusage();
00220
00221 const Image<PixRGB<byte> > rgb = input.asRgb();
00222
00223 InputFrame finput = InputFrame::fromRgb(&rgb, t);
00224
00225 fvc->input(finput);
00226
00227 (void) fvc->getOutput();
00228
00229 rutz::time u2 = rutz::time::user_rusage();
00230 rutz::time s2 = rutz::time::sys_rusage();
00231
00232 const IntegerInput ii =
00233 IntegerInput::decode(input, decodeType.getVal(),
00234 ieng->getNbits());
00235
00236 ivc->inputInt(ii, t, &cache);
00237
00238 (void) ivc->getOutputInt();
00239
00240 rutz::time u3 = rutz::time::user_rusage();
00241 rutz::time s3 = rutz::time::sys_rusage();
00242
00243 fruser += (u2 - u1);
00244 frsys += (s2 - s1);
00245 iruser += (u3 - u2);
00246 irsys += (s3 - s2);
00247
00248 if (!profOnly)
00249 {
00250 Image<float> frg, fby;
00251 const float lumthresh = 25.5f;
00252 getRGBY(finput.colorFloat(), frg, fby, lumthresh);
00253
00254 ofs->writeFrame(input, "input",
00255 FrameInfo("copy of input frame", SRC_POS));
00256
00257 ofs->writeFloat(finput.grayFloat(), FLOAT_NORM_0_255, "fBW",
00258 FrameInfo("floating-point luminance", SRC_POS));
00259
00260 ofs->writeFloat(frg, FLOAT_NORM_0_255, "fRG",
00261 FrameInfo("floating-point Red-Green", SRC_POS));
00262
00263 ofs->writeFloat(fby, FLOAT_NORM_0_255, "fBY",
00264 FrameInfo("floating-point Blue-Yellow", SRC_POS));
00265
00266 ofs->writeFloat(ii.grayInt(), FLOAT_NORM_0_255, "iBW",
00267 FrameInfo("fixed-point luminance", SRC_POS));
00268
00269 ofs->writeFloat(ii.rgInt(), FLOAT_NORM_0_255, "iRG",
00270 FrameInfo("fixed-point Red-Green", SRC_POS));
00271
00272 ofs->writeFloat(ii.byInt(), FLOAT_NORM_0_255, "iBY",
00273 FrameInfo("fixed-point Blue-Yellow", SRC_POS));
00274
00275 fvc->saveResults(ofs);
00276 ivc->saveResults(ofs);
00277
00278 {
00279 const double cc = corrcoef(finput.grayFloat(), Image<float>(ii.grayInt()));
00280 LINFO("%06d corrcoef(fbw,ibw) = %.4f", c, cc);
00281 }
00282
00283 {
00284 const double cc = corrcoef(frg, Image<float>(ii.rgInt()));
00285 LINFO("%06d corrcoef(frg,irg) = %.4f", c, cc);
00286 }
00287
00288 {
00289 const double cc = corrcoef(fby, Image<float>(ii.byInt()));
00290 LINFO("%06d corrcoef(fby,iby) = %.4f", c, cc);
00291 }
00292
00293 if (fvc->hasSubChan("orientation")
00294 && ivc->hasSubChan("int-orientation"))
00295 {
00296 const ImageSet<float> fpyr =
00297 dyn_cast<OrientationChannel>(fvc->subChan("orientation"))->gabor(2).pyramid(0);
00298 const ImageSet<int> ipyr =
00299 dyn_cast<IntegerOrientationChannel>(ivc->subChan("int-orientation"))->gabor(2).intgPyramid();
00300
00301 for (uint i = 0; i < fpyr.size(); ++i)
00302 if (fpyr[i].initialized())
00303 ofs->writeFloat(fpyr[i], FLOAT_NORM_0_255,
00304 sformat("fpyr[%u]", i),
00305 FrameInfo(sformat("floating-point pyramid "
00306 "level %u of %u", i,
00307 fpyr.size()), SRC_POS));
00308
00309 for (uint i = 0; i < ipyr.size(); ++i)
00310 if (ipyr[i].initialized())
00311 ofs->writeFloat(Image<float>(ipyr[i]), FLOAT_NORM_0_255,
00312 sformat("ipyr[%u]", i),
00313 FrameInfo(sformat("integer pyramid "
00314 "level %u of %u", i,
00315 fpyr.size()), SRC_POS));
00316
00317 for (uint i = 0; i < fpyr.size(); ++i)
00318 if (fpyr[i].initialized())
00319 {
00320 const double cc = corrcoef(fpyr[i], Image<float>(ipyr[i]));
00321 LINFO("%06d pyr[%u] corrcoef = %.4f", c, i, cc);
00322 }
00323 }
00324
00325 compareChannels(c, *ivc, *fvc);
00326 }
00327
00328 if (os == FRAME_FINAL)
00329 break;
00330
00331 LDEBUG("frame %d", c);
00332 ++c;
00333
00334 if (ifs->shouldWait() || ofs->shouldWait())
00335 Raster::waitForKey();
00336 }
00337
00338 manager.stop();
00339
00340 for (std::map<IntegerChannel*, ChannelCorrcoefData>::const_iterator
00341 itr = ccdata.begin(), stop = ccdata.end();
00342 itr != stop; ++itr)
00343 {
00344 LINFO("AVG corrcoef(%-20s) = %.4f",
00345 (*itr).first->tagName().c_str(),
00346 (*itr).second.sum / (*itr).second.n);
00347 }
00348
00349 LINFO("floating-point code: %.3es user + %.3es sys (%.3fms per frame)",
00350 fruser.sec(), frsys.sec(),
00351 c <= 0 ? 0.0 : (fruser.msec() + frsys.msec()) / c);
00352 LINFO("integer code: %.3es user + %.3es sys (%.3fms per frame)",
00353 iruser.sec(), irsys.sec(),
00354 c <= 0 ? 0.0 : (iruser.msec() + irsys.msec()) / c);
00355
00356 if (iruser.sec() + irsys.sec() > 0.0)
00357 LINFO("floating-point/integer runtime ratio: %.2f",
00358 (fruser.sec() + frsys.sec()) / (iruser.sec() + irsys.sec()));
00359
00360 return 0;
00361 }
00362
00363 int main(const int argc, const char **argv)
00364 {
00365 try
00366 {
00367 return submain(argc, argv);
00368 }
00369 catch (...)
00370 {
00371 REPORT_CURRENT_EXCEPTION;
00372 }
00373
00374 return 1;
00375 }
00376
00377
00378
00379
00380
00381
00382
00383
00384 #endif // APPNEURO_TEST_INTCHANNEL_C_DEFINED