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 "SeaBee/SiftRec.H"
00039 #include "Image/ColorOps.H"
00040 #include "Image/DrawOps.H"
00041 #include "Util/sformat.H"
00042
00043 const ModelOptionCateg MOC_SiftRecOps = {
00044 MOC_SORTPRI_3, "SiftRec options" };
00045
00046 const ModelOptionDef OPT_VDBFileName =
00047 { MODOPT_ARG(std::string), "VDBFileName", &MOC_SiftRecOps, OPTEXP_CORE,
00048 "The visual database file name",
00049 "vdb-filename", '\0', "", "objects.vdb" };
00050
00051 const ModelOptionDef OPT_SiftUseColor =
00052 { MODOPT_FLAG, "SiftUseColor", &MOC_SiftRecOps, OPTEXP_CORE,
00053 "Use color in the Sift descriptor",
00054 "use-color", '\0', "", "false" };
00055
00056
00057 SiftRec::SiftRec(OptionManager& mgr,
00058 const std::string& descrName,
00059 const std::string& tagName ) :
00060 ModelComponent(mgr, descrName, tagName),
00061 itsVDBFile(&OPT_VDBFileName, this, ALLOW_ONLINE_CHANGES),
00062 itsUseColor(&OPT_SiftUseColor, this, ALLOW_ONLINE_CHANGES)
00063 {
00064 }
00065
00066 SiftRec::~SiftRec()
00067 {
00068 }
00069
00070
00071 bool SiftRec::initVDB()
00072 {
00073 itsTrainingMode = false;
00074 itsMaxLabelHistory = 1;
00075 itsVDB.loadFrom(itsVDBFile.getVal());
00076
00077 return true;
00078 }
00079
00080 void SiftRec::getObject(const Image<PixRGB<byte> > &img)
00081 {
00082
00083
00084 Image<PixRGB<byte> > inputImg = img;
00085
00086
00087 std::string objectName;
00088 if (objectName == "nomatch")
00089 {
00090 itsRecentLabels.resize(0);
00091 if (itsTrainingMode)
00092 {
00093 LINFO("Enter a lebel for this object:");
00094 std::getline(std::cin, objectName);
00095 if (objectName != "")
00096 {
00097 rutz::shared_ptr<VisualObject>
00098 vo(new VisualObject(objectName.c_str(), "NULL", inputImg,
00099 Point2D<int>(-1,-1),
00100 std::vector<double>(),
00101 std::vector< rutz::shared_ptr<Keypoint> >(),
00102 itsUseColor.getVal()));
00103 itsVDB.addObject(vo);
00104 itsVDB.saveTo(itsVDBFile.getVal());
00105 }
00106 }
00107 } else {
00108 itsRecentLabels.push_back(objectName);
00109 while(itsRecentLabels.size() > itsMaxLabelHistory)
00110 itsRecentLabels.pop_front();
00111
00112 const std::string bestObjName = getBestLabel(1);
00113
00114 if (bestObjName.size() > 0)
00115 {
00116
00117
00118
00119
00120
00121
00122 }
00123 }
00124
00125 }
00126
00127 void SiftRec::trainObject(const Image<PixRGB<byte> > &img, const std::string& objectName)
00128 {
00129 if (objectName != "")
00130 {
00131 rutz::shared_ptr<VisualObject>
00132 vo(new VisualObject(objectName.c_str(), "NULL", img,
00133 Point2D<int>(-1,-1),
00134 std::vector<double>(),
00135 std::vector< rutz::shared_ptr<Keypoint> >(),
00136 itsUseColor.getVal()));
00137 itsVDB.addObject(vo, false);
00138 itsVDB.saveTo(itsVDBFile.getVal());
00139 }
00140 }
00141
00142 std::string SiftRec::getBestLabel(const size_t mincount)
00143 {
00144 if (itsRecentLabels.size() == 0)
00145 return std::string();
00146
00147 std::map<std::string, size_t> counts;
00148
00149 size_t bestcount = 0;
00150 size_t bestpos = 0;
00151
00152 for (size_t i = 0; i < itsRecentLabels.size(); ++i)
00153 {
00154 const size_t c = ++(counts[itsRecentLabels[i]]);
00155
00156 if (c >= bestcount)
00157 {
00158 bestcount = c;
00159 bestpos = i;
00160 }
00161 }
00162
00163 if (bestcount >= mincount)
00164 return itsRecentLabels[bestpos];
00165
00166 return std::string();
00167 }
00168
00169 std::string SiftRec::matchObject(Image<PixRGB<byte> > &ima, float &score, Rectangle& rect)
00170 {
00171
00172 std::vector< rutz::shared_ptr<VisualObjectMatch> > matches;
00173 rutz::shared_ptr<VisualObject>
00174 vo(new VisualObject("PIC", "PIC", ima,
00175 Point2D<int>(-1,-1),
00176 std::vector<double>(),
00177 std::vector< rutz::shared_ptr<Keypoint> >(),
00178 itsUseColor.getVal()));
00179
00180 const uint nmatches = itsVDB.getObjectMatches(vo, matches, VOMA_SIMPLE,
00181 100U,
00182 0.5F,
00183 0.5F,
00184 1.0F,
00185 3U,
00186 100U,
00187 false
00188 );
00189
00190 score = 0;
00191 float avgScore = 0, affineAvgDist = 0;
00192 int nkeyp = 0;
00193 int objId = -1;
00194 if (nmatches > 0)
00195 {
00196 rutz::shared_ptr<VisualObject> obj;
00197 rutz::shared_ptr<VisualObjectMatch> vom;
00198
00199 for (unsigned int i = 0; i < 1; ++i)
00200 {
00201 vom = matches[i];
00202 obj = vom->getVoTest();
00203 score = vom->getScore();
00204 nkeyp = vom->size();
00205 avgScore = vom->getKeypointAvgDist();
00206 affineAvgDist = vom->getAffineAvgDist();
00207
00208 Point2D<int> tl, tr, br, bl;
00209 vom->getTransfTestOutline(tl, tr, br, bl);
00210 LINFO("%ix%i %ix%i %ix%i %ix%i",
00211 tl.i, tl.j, tr.i, tr.j,
00212 br.i, br.j, bl.i, bl.j);
00213
00214
00215
00216
00217
00218
00219
00220
00221 objId = atoi(obj->getName().c_str()+3);
00222
00223 return obj->getName();
00224 LINFO("### Object match with '%s' score=%f ID:%i",
00225 obj->getName().c_str(), vom->getScore(), objId);
00226
00227
00228
00229
00230 double dist = 0;
00231 for (int keyp=0; keyp<nkeyp; keyp++)
00232 {
00233 const KeypointMatch kpm = vom->getKeypointMatch(keyp);
00234
00235 float refX = kpm.refkp->getX();
00236 float refY = kpm.refkp->getY();
00237
00238 float tstX = kpm.tstkp->getX();
00239 float tstY = kpm.tstkp->getY();
00240 dist += (refX-tstX) * (refX-tstX);
00241 dist += (refY-tstY) * (refY-tstY);
00242 }
00243
00244
00245
00246
00247
00248 }
00249
00250 }
00251
00252 return std::string("nomatch");
00253 }
00254