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 CornersFeatures_C_DEFINED
00039 #define CornersFeatures_C_DEFINED
00040
00041 #include "plugins/SceneUnderstanding/CornersFeatures.H"
00042
00043 #include "Image/DrawOps.H"
00044 #include "Image/MathOps.H"
00045
00046 #include "Image/Kernels.H"
00047 #include "Image/FilterOps.H"
00048 #include "Image/Transforms.H"
00049 #include "Image/fancynorm.H"
00050 #include "Image/Convolutions.H"
00051 #include "Image/MatrixOps.H"
00052 #include "Simulation/SimEventQueue.H"
00053 #include "GUI/DebugWin.H"
00054 #include <math.h>
00055 #include <fcntl.h>
00056 #include <limits>
00057 #include <string>
00058
00059 const ModelOptionCateg MOC_CornersFeatures = {
00060 MOC_SORTPRI_3, "CornersFeatures-Related Options" };
00061
00062
00063 const ModelOptionDef OPT_CornersFeaturesShowDebug =
00064 { MODOPT_ARG(bool), "CornersFeaturesShowDebug", &MOC_CornersFeatures, OPTEXP_CORE,
00065 "Show debug img",
00066 "corners-debug", '\0', "<true|false>", "false" };
00067
00068
00069
00070 SIMMODULEINSTFUNC(CornersFeatures);
00071
00072
00073 CornersFeatures::CornersFeatures(OptionManager& mgr, const std::string& descrName,
00074 const std::string& tagName) :
00075 SimModule(mgr, descrName, tagName),
00076 SIMCALLBACK_INIT(SimEventV2Output),
00077 SIMCALLBACK_INIT(SimEventSaveOutput),
00078 SIMCALLBACK_INIT(SimEventUserInput),
00079 itsShowDebug(&OPT_CornersFeaturesShowDebug, this),
00080 itsPatchSize(20,20)
00081 {
00082
00083 initRandomNumbers();
00084
00085 itsSOFM = new SOFM("Corners", itsPatchSize.sz(), 50,50 );
00086
00087 itsSOFM->ReadNet("SOFM.net");
00088
00089 }
00090
00091
00092
00093 CornersFeatures::~CornersFeatures()
00094 {
00095 }
00096
00097
00098
00099 void CornersFeatures::onSimEventV2Output(SimEventQueue& q,
00100 rutz::shared_ptr<SimEventV2Output>& e)
00101 {
00102 itsLines = e->getLines();
00103
00104 evolve(q);
00105
00106 q.post(rutz::make_shared(new SimEventCornersOutput(this, itsCorners)));
00107 }
00108
00109
00110 void CornersFeatures::onSimEventSaveOutput(SimEventQueue& q, rutz::shared_ptr<SimEventSaveOutput>& e)
00111 {
00112 if (itsShowDebug.getVal())
00113 {
00114
00115
00116 nub::ref<FrameOstream> ofs =
00117 dynamic_cast<const SimModuleSaveInfo&>(e->sinfo()).ofs;
00118 Layout<PixRGB<byte> > disp = getDebugImage(q);
00119 ofs->writeRgbLayout(disp, "CornersFeatures", FrameInfo("CornersFeatures", SRC_POS));
00120 }
00121 }
00122
00123
00124 void CornersFeatures::onSimEventUserInput(SimEventQueue& q, rutz::shared_ptr<SimEventUserInput>& e)
00125 {
00126
00127 LINFO("Got event %s %ix%i key=%i",
00128 e->getWinName(),
00129 e->getMouseClick().i,
00130 e->getMouseClick().j,
00131 e->getKey());
00132
00133 if (e->getMouseClick().isValid())
00134 {
00135 }
00136
00137
00138
00139 }
00140
00141 std::vector<CornersFeatures::CornerState> CornersFeatures::getCorners(std::vector<V2::LineSegment>& lines)
00142 {
00143 std::vector<CornersFeatures::CornerState> corners;
00144 float minDist = 5;
00145 float minDistSq = minDist*minDist;
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155 for(uint i=0; i<lines.size(); i++)
00156 {
00157 V2::LineSegment& ls1 = itsLines[i];
00158
00159
00160
00161
00162 std::vector<float> angles1;
00163 std::vector<float> angles2;
00164 double dx = ls1.p2.i - ls1.p1.i;
00165 double dy = ls1.p2.j - ls1.p1.j;
00166 double ang = atan2(dx, dy) + M_PI/2;
00167 angles1.push_back(ang);
00168 angles2.push_back(ang+M_PI);
00169
00170 for(uint j=i+1; j<lines.size(); j++)
00171 {
00172 if (i == j)
00173 continue;
00174 V2::LineSegment& ls2 = itsLines[j];
00175
00176
00177
00178 if (ls1.p1.distanceToSegment(ls2.p1, ls2.p2) < minDist)
00179 {
00180 double dx1 = ls2.p1.i - ls1.p1.i;
00181 double dy1 = ls2.p1.j - ls1.p1.j;
00182
00183 double dx2 = ls2.p2.i - ls1.p1.i;
00184 double dy2 = ls2.p2.j - ls1.p1.j;
00185
00186
00187 if ( (dx1*dx1 + dy1*dy1) > minDistSq)
00188 angles1.push_back(atan2(dx1, dy1) + M_PI/2);
00189
00190 if ( (dx2*dx2 + dy2*dy2) > minDistSq)
00191 angles1.push_back(atan2(dx2, dy2) + M_PI/2);
00192 }
00193
00194
00195
00196 if (ls1.p2.distanceToSegment(ls2.p1, ls2.p2) < minDist)
00197 {
00198 double dx1 = ls2.p1.i - ls1.p2.i;
00199 double dy1 = ls2.p1.j - ls1.p2.j;
00200
00201 double dx2 = ls2.p2.i - ls1.p2.i;
00202 double dy2 = ls2.p2.j - ls1.p2.j;
00203
00204
00205 if ( (dx1*dx1 + dy1*dy1) > minDistSq)
00206 angles2.push_back(atan2(dx1, dy1) + M_PI/2);
00207
00208 if ( (dx2*dx2 + dy2*dy2) > minDistSq)
00209 angles2.push_back(atan2(dx2, dy2) + M_PI/2);
00210
00211 }
00212 }
00213
00214
00215
00216 CornerState c1;
00217 c1.center = ls1.p1;
00218 c1.angles = angles1;
00219 corners.push_back(c1);
00220
00221 CornerState c2;
00222 c2.center = ls1.p2;
00223 c2.angles = angles2;
00224 corners.push_back(c2);
00225
00226
00227
00228 }
00229
00230
00231 return corners;
00232
00233 }
00234
00235
00236 void CornersFeatures::evolve(SimEventQueue& q)
00237 {
00238
00239
00240
00241
00242 std::vector<CornerState> corners = getCorners(itsLines);
00243
00244 itsCorners = corners;
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358 }
00359
00360
00361 Layout<PixRGB<byte> > CornersFeatures::getDebugImage(SimEventQueue& q)
00362 {
00363 Layout<PixRGB<byte> > outDisp;
00364
00365 Image<PixRGB<byte> > cornersImg(320, 240, ZEROS);
00366 for(uint i=0; i<itsCorners.size(); i++)
00367 {
00368 for(uint ai=0; ai<itsCorners[i].angles.size(); ai++)
00369 {
00370 int x1 = int(cos(itsCorners[i].angles[ai])*30.0/2.0);
00371 int y1 = int(sin(itsCorners[i].angles[ai])*30.0/2.0);
00372 Point2D<float> p1(itsCorners[i].center.i-x1, itsCorners[i].center.j+y1);
00373
00374 drawLine(cornersImg, Point2D<int>(itsCorners[i].center), Point2D<int>(p1), PixRGB<byte>(0,255,0));
00375 }
00376 }
00377
00378 outDisp = cornersImg;
00379
00380 return outDisp;
00381
00382 }
00383
00384
00385
00386
00387
00388
00389
00390 #endif
00391