00001 #ifndef Impala_Core_Feature_InterestPointFeature_h
00002 #define Impala_Core_Feature_InterestPointFeature_h
00003
00004 #include "Core/Array/MakeRoi.h"
00005 #include "Core/Geometry/Rectangle.h"
00006 #include "Core/Feature/FeatureDefinition.h"
00007 #include "Core/Feature/FeatureTable.h"
00008 #include "Core/Feature/Surf.h"
00009 #include "Core/Feature/RandomForest.h"
00010 #include "Basis/Timer.h"
00011
00012 #include "Core/Matrix/MatNorm2Dist.h"
00013 #include "Core/Matrix/VectorQuantize.h"
00014 #include "Core/Matrix/MatTrace.h"
00015 #include "Core/Matrix/MatEye.h"
00016 #include "Util/Random.h"
00017
00018 #include "Core/Feature/RegionDescriptor.h"
00019 #include "Core/Feature/KoenFIST2.h"
00020 #include "Core/Feature/HarrisLaplaceDetector.h"
00021 #include "Core/Feature/LaplacianDetector.h"
00022 #include "Core/Geometry/InterestPointSelector.h"
00023 #include "Core/Geometry/MaskedInterestPointSelector.h"
00024
00025 #include "Core/Feature/FeatureTableResult.h"
00026 #include "Core/Feature/PointDescriptorTable.h"
00027 #include "Core/Feature/ReadCodebook.h"
00028 #include "Core/Table/Select.h"
00029 #include "Core/Matrix/MatFunc.h"
00030 #include "Persistency/RepositoryInFileSystem.h"
00031
00032 #include <iostream>
00033 #include <fstream>
00034 #include <algorithm>
00035
00036 namespace Impala
00037 {
00038 namespace Core
00039 {
00040 namespace Feature
00041 {
00042
00043
00044 class InterestPointFeature
00045 {
00046 public:
00047 typedef Array::Array2dScalarReal64 Array2dScalarReal64;
00048 typedef Matrix::Mat Mat;
00049 typedef Geometry::InterestPointSelector InterestPointSelector;
00050 typedef std::vector<Vector::VectorTem<Real64>*> CodebookVectors;
00051 typedef Persistency::FileLocator FileLocator;
00052 typedef Persistency::File File;
00053
00054 bool mClusterInput;
00055 FeatureTable* mClusterInputData;
00056 String mClusterInputImage;
00057
00058 InterestPointFeature(CmdOptions& options) :
00059 mVerbose(0),
00060 mStripBorder(0),
00061 mUseRecGauss(false),
00062 mKeepLimited(0),
00063 mCodebook(0),
00064 mDescriptorReduce(0),
00065 mExtraBoxes(0),
00066 mResultOutput(0),
00067 mClusterInput(false),
00068 mClusterInputData(0),
00069 mDynamicPointSelector(false)
00070 {
00071 mVerbose = options.GetInt("verb");
00072 mUseRecGauss = options.GetBool("recGauss");
00073 mStripBorder = options.GetInt("borderWidth");
00074 mOutputFormat = options.GetString("outputFormat");
00075
00076 mClusterInput = options.GetBool("clusterInput");
00077 mKeepLimited = options.GetInt("keepLimited");
00078 if (!options.GetBool("noRandomizeSeed"))
00079 mRNG.RandomizeSeed();
00080 mTimeStats.AddGroup("detector");
00081 mTimeStats.AddGroup("descriptor");
00082 mTimeStats.AddGroup("projection");
00083
00084 String detector = options.GetString("detector");
00085 mName = detector + "-" + options.GetString("descriptor");
00086 mFeatureDefinition = FeatureDefinition(options.GetString("featurePrefix") + mName);
00087
00088 String descriptor = options.GetString("descriptor");
00089 if((descriptor.size() >= 4) &&
00090 (descriptor.substr(descriptor.size()-4,4) == "surf"))
00091 {
00092 Core::Feature::GetDSurfOptions(options, mSurfParams[0],
00093 mSurfParams[1], mSurfParams[2]);
00094 mFeatureDefinition.AddParameter
00095 ("sc", MakeString(mSurfParams[0]) + "-" +
00096 MakeString(mSurfParams[1]) + "-" + MakeString(mSurfParams[2]));
00097 }
00098 if((detector == "harrislaplace") || (detector == "harrislaplace2"))
00099 {
00100 if(options.GetString("harrisThreshold") != "1e-9")
00101 {
00102 mFeatureDefinition.AddParameter
00103 ("ht", options.GetString("harrisThreshold"));
00104 }
00105 }
00106 if((detector == "densesampling") || (detector == "denseall"))
00107 {
00108
00109 int spacing = options.GetInt("ds_spacing");
00110 String scales = options.GetString("ds_scales");
00111
00112 Util::StringParser sp(scales);
00113 while(!sp.TheEnd())
00114 {
00115 Real64 scale = sp.GetDouble('+', false, true);
00116 mDenseSamplingScales.push_back(scale);
00117 }
00118 if(mDenseSamplingScales.size() == 0)
00119 {
00120
00121 Real64 scale = Real64(spacing) / 5;
00122
00123
00124
00125 mDenseSamplingScales.push_back(scale);
00126 }
00127 String name = MakeString(spacing);
00128 for(int i = 0; i < mDenseSamplingScales.size(); i++)
00129 {
00130 name += "-" + MakeString(mDenseSamplingScales[i]);
00131 }
00132 mFeatureDefinition.AddParameter("ds", name);
00133 }
00134
00135 mDescriptorReduceFilename = options.GetString("descriptorReduce");
00136 if(!mDescriptorReduceFilename.empty())
00137 mFeatureDefinition.AddParameter("red", "1");
00138
00139 if(!options.GetString("descriptorOpponentWeight").empty())
00140 {
00141 mFeatureDefinition.AddParameter
00142 ("ow", options.GetString("descriptorOpponentWeight"));
00143 }
00144 if(StringStartsWith(options.GetString("pointSelector"), "dynamic-"))
00145 {
00146
00147 mDynamicPointSelector = true;
00148 String config = options.GetString("pointSelector");
00149 mFeatureDefinition.AddParameter("ps", config);
00150 config = StringReplace(config, "dynamic-", "");
00151 mDynamicPointSelectorConfig = config;
00152 }
00153 else if(options.GetString("pointSelector").size() != 0)
00154 {
00155
00156 String config = options.GetString("pointSelector");
00157 String configName = config;
00158 if(config == "pyramid-1x1-2x2")
00159 {
00160 config = "P1x1#0+P2x2#0+P2x2#1+P2x2#2+P2x2#3";
00161 }
00162 else if(config == "pyramid-1x1-2x2-3x1")
00163 {
00164 config = "P1x1#0+P2x2#0+P2x2#1+P2x2#2+P2x2#3+P3x1#0+P3x1#1+P3x1#2";
00165 }
00166 else if(config == "pyramid-1x1-2x2-1x3")
00167 {
00168
00169 config = "P1x1#0+P2x2#0+P2x2#1+P2x2#2+P2x2#3+P1x3#0+P1x3#1+P1x3#2";
00170 }
00171 else if(config == "pyramid-1x1-2x2-4x4")
00172 {
00173
00174 config = "P1x1#0+P2x2#0+P2x2#1+P2x2#2+P2x2#3+P4x4#0+P4x4#1+P4x4#2+P4x4#3+P4x4#4+P4x4#5+P4x4#6+P4x4#7+P4x4#8+P4x4#9+P4x4#10+P4x4#11+P4x4#12+P4x4#13+P4x4#14+P4x4#15";
00175 }
00176 else if(config == "pyramid-1x1-2x2-4x4-1x3")
00177 {
00178
00179 config = "P1x1#0+P2x2#0+P2x2#1+P2x2#2+P2x2#3+P4x4#0+P4x4#1+P4x4#2+P4x4#3+P4x4#4+P4x4#5+P4x4#6+P4x4#7+P4x4#8+P4x4#9+P4x4#10+P4x4#11+P4x4#12+P4x4#13+P4x4#14+P4x4#15+P1x3#0+P1x3#1+P1x3#2";
00180 }
00181 Util::StringParser sp(config);
00182 while(!sp.TheEnd())
00183 {
00184 String selectorConfig = sp.GetString('+', false);
00185 if(selectorConfig.size() == 0) break;
00186 InterestPointSelector* selector =
00187 new InterestPointSelector(selectorConfig, mStripBorder);
00188 mPointSelector.push_back(selector);
00189 }
00190 configName = StringReplaceAll(configName, "+", "");
00191 configName = StringReplaceAll(configName, "#", "x");
00192 mFeatureDefinition.AddParameter("ps", configName);
00193 }
00194 else
00195 {
00196
00197 InterestPointSelector* selector =
00198 new InterestPointSelector("P1x1#0", mStripBorder);
00199 mPointSelector.push_back(selector);
00200 }
00201 }
00202
00203 ~InterestPointFeature()
00204 {
00205 if(mCodebook)
00206 {
00207 delete mCodebook;
00208 mCodebook = 0;
00209 }
00210 }
00211
00212 static void AddCmdOptions()
00213 {
00214 CmdOptions& options = CmdOptions::GetInstance();
00215 options.AddOption(0, "borderWidth", "size", "0");
00216 options.AddOption(0, "recGauss", "", "0");
00217 options.AddOption(0, "loadRegions", "filename", "");
00218 options.AddOption(0, "saveRegions", "filename", "");
00219 options.AddOption(0, "descriptor", "mode", "");
00220 options.AddOption(0, "output", "filename", "");
00221 options.AddOption(0, "outputFormat", "mode", "");
00222 options.AddOption(0, "descriptorBinCount","bins", "15");
00223 options.AddOption(0, "descriptorPreSmoothing","", "0");
00224 options.AddOption(0, "descriptorOpponentWeight","weight","");
00225
00226
00227 options.AddOption(0, "clusterInput", "", "0");
00228 options.AddOption(0, "keepLimited", "count", "-1");
00229 options.AddOption(0, "noRandomizeSeed", "", "0");
00230
00231
00232 options.AddOption(0, "descriptorReduce", "filename", "");
00233 options.AddOption(0, "codebook", "filename", "");
00234 options.AddOption(0, "codebookMode", "name", "hard");
00235 options.AddOption(0, "codebookSigma", "sigma", "");
00236 options.AddOption(0, "codebookName", "name", "");
00237
00238
00239 options.AddOption(0, "pointSelector", "config", "");
00240 options.AddOption(0, "extraBoxes", "filename", "");
00241
00242
00243 options.AddOption(0, "detector", "mode", "harrislaplace");
00244
00245
00246 options.AddOption(0, "harrisThreshold", "threshold", "1e-9");
00247 options.AddOption(0, "harrisK", "k", "0.06");
00248 options.AddOption(0, "laplaceThreshold", "threshold", "0.03");
00249
00250
00251 options.AddOption(0, "ds_spacing", "pixels", "6");
00252 options.AddOption(0, "ds_scales", "scale1+scale2+...", "");
00253
00254 options.AddOption(0, "featurePrefix", "prefix", "");
00255
00256 Core::Feature::AddDSurfOptions(options);
00257 }
00258
00259
00260 FeatureDefinition
00261 GetFeatureDefinition()
00262 {
00263 return mFeatureDefinition;
00264 }
00265
00266 String
00267 GetFeatureName()
00268 {
00269 return mFeatureDefinition.AsString();
00270 }
00271
00272
00273 String
00274 GetFeatureNameShort()
00275 {
00276 return mFeatureDefinition.GetName();
00277 }
00278
00279
00280 void
00281 SetCodebook(String filename, const Persistency::Locator& locator)
00282 {
00283 mLocator = locator;
00284 FileLocator codebookLoc(mLocator, filename);
00285 File file = RepositoryGetFile(codebookLoc, false, false);
00286 Util::IOBuffer* buf = file.GetReadBuffer();
00287 if (!mDescriptorReduceFilename.empty())
00288 {
00289 FileLocator fLoc(mLocator, mDescriptorReduceFilename);
00290 File f = RepositoryGetFile(fLoc, false, false);
00291 ReadRaw(mDescriptorReduce, f);
00292 mFeatureDefinition.AddParameter("red", MakeString(Matrix::MatNrCol(mDescriptorReduce)));
00293 }
00294
00295 ILOG_DEBUG("SetCodebook after IOBuffer " << buf);
00296 if (!buf)
00297 {
00298 ILOG_ERROR("SetCodebook: IOBuffer is 0");
00299 return;
00300 }
00301 mCodebook = ReadCodebookFromBuffer(buf);
00302 mCodebook->SetFeatureDefinition(FeatureDefinition(filename));
00303 delete buf;
00304
00305 ILOG_INFO("Reading codebook: " << codebookLoc <<
00306 "; dimensionCount = " << mCodebook->GetFeatureVectorLength()
00307 << "; size = " << mCodebook->Size());
00308
00309 CmdOptions& options = CmdOptions::GetInstance();
00310 String CM = options.GetString("codebookMode");
00311 if(CM != "hard")
00312 {
00313 CM = StringReplace(CM, "llcdump", "llc");
00314 if(CM == "hardindex")
00315 {
00316 mFeatureDefinition.AddParameter
00317 ("cm", CM + "-" + FileNameBase(filename));
00318 }
00319 else
00320 {
00321 mFeatureDefinition.AddParameter("cm", CM);
00322 }
00323 }
00324 if(options.GetString("codebookSigma") != "")
00325 {
00326 mFeatureDefinition.AddParameter
00327 ("cs", options.GetString("codebookSigma"));
00328 }
00329 if(options.GetString("codebookName") != "")
00330 {
00331 mFeatureDefinition.AddParameter
00332 ("cn", options.GetString("codebookName"));
00333 }
00334
00335 if(!options.GetString("extraBoxes").empty())
00336 {
00337 FileLocator fLoc(mLocator, options.GetString("extraBoxes"));
00338 File f = RepositoryGetFile(fLoc, false, false);
00339 ReadRaw(mExtraBoxes, f);
00340 }
00341 }
00342
00343 void
00344 SetResultOutput(FeatureTableResult* result)
00345 {
00346 mResultOutput = result;
00347 }
00348
00349 bool
00350 FindInterestPoints(CmdOptions& options, Array::Array2dVec3UInt8* input,
00351 Quid quid,
00352 String outputFilename, bool borderAlreadyRemoved=false,
00353 Util::IOBuffer* loadRegionsFile=0)
00354 {
00355 ILOG_DEBUG("start FindInterestPoints");
00356 String saveRegionsFilename = options.GetString("saveRegions");
00357 String detectorMode = options.GetString("detector");
00358 String descriptorMode = options.GetString("descriptor");
00359 Timer timer;
00360 Array::Array2dVec3UInt8* inputNoBorder = input;
00361 if(!borderAlreadyRemoved)
00362 {
00363
00364 Geometry::Rectangle rect(mStripBorder, mStripBorder,
00365 input->CW() - mStripBorder - 1,
00366 input->CH() - mStripBorder - 1, true);
00367 inputNoBorder = MakeRoi(input, rect);
00368 }
00369
00370 PointDescriptorTable* pointData = 0;
00371
00372
00373 ILOG_DEBUG("applying detector");
00374 mTimeStats.MeasureFirst();
00375 if(loadRegionsFile)
00376 {
00377
00378 pointData = PointDescriptorTable::ImportFromBuffer(detectorMode,
00379 loadRegionsFile, mStripBorder);
00380 }
00381 else
00382 {
00383 pointData = ApplyDetector(inputNoBorder, detectorMode);
00384 }
00385 if(descriptorMode.empty())
00386 {
00387
00388
00389 pointData->ExportToFile(outputFilename, mStripBorder,
00390 mOutputFormat);
00391 }
00392 if(!saveRegionsFilename.empty())
00393 {
00394 ILOG_INFO("Writing to: " << saveRegionsFilename);
00395 pointData->ExportToFile(saveRegionsFilename, mStripBorder,
00396 mOutputFormat);
00397 }
00398
00399 ILOG_DEBUG("[Timing] Region loading / applying detector finished in "
00400 << timer.SplitTimeStr());
00401
00402
00403 ILOG_DEBUG("computing descriptor");
00404 mTimeStats.MeasureNext();
00405 if(descriptorMode.size() != 0)
00406 {
00407 ComputeDescriptors(pointData, inputNoBorder, descriptorMode);
00408
00409 ILOG_DEBUG("[Timing] Descriptors finished at " << timer.SplitTimeStr());
00410 if(mCodebook)
00411 {
00412 ILOG_DEBUG("preparing for codebook");
00413
00414 Timer timerProjection;
00415 if(mExtraBoxes)
00416 {
00417 for(int j = 0; j < mExtraBoxes->CH(); j++)
00418 {
00419 if(*mExtraBoxes->CPB(0, j) == quid)
00420 {
00421
00422 Quid boxQuid = *mExtraBoxes->CPB(1, j);
00423 UInt64 xlow = *mExtraBoxes->CPB(2, j);
00424 UInt64 ylow = *mExtraBoxes->CPB(3, j);
00425 UInt64 xhi = *mExtraBoxes->CPB(4, j);
00426 UInt64 yhi = *mExtraBoxes->CPB(5, j);
00427 UInt64 width = xhi - xlow;
00428 UInt64 height = yhi - ylow;
00429
00430 PointDescriptorTable* table = new PointDescriptorTable(pointData->GetFeatureDefinition());
00431 table->SetDescriptorLength(pointData->GetDescriptorLength());
00432 for(int i = 0; i < pointData->Size(); i++)
00433 {
00434 Real64 x = pointData->GetX(i) - xlow;
00435 Real64 y = pointData->GetY(i) - ylow;
00436 if((x < 0) || (y < 0) || (x > width) || (y > height))
00437 {
00438 continue;
00439 }
00440 table->Add(x, y, 0, 0, 0, pointData->Get6(i));
00441 }
00442 ILOG_DEBUG("extrabox:"<<xlow << " "<< ylow << " "<<xhi << " " << yhi << " " << table->Size() << " " << pointData->Size());
00443 table = ProjectOntoCodebook(table,
00444 options.GetString("codebookMode"),
00445 width, height, boxQuid);
00446 delete table;
00447 }
00448 }
00449 }
00450 else
00451 {
00452 mTimeStats.MeasureNext();
00453 pointData = ProjectOntoCodebook(pointData,
00454 options.GetString("codebookMode"),
00455 inputNoBorder->CW(), inputNoBorder->CH(),
00456 quid);
00457 mTimeStats.MeasureLast();
00458 ILOG_INFO("Overall " << mTimeStats.AsString());
00459 ILOG_DEBUG("Just codebook projection took: " <<
00460 timerProjection.SplitTimeStr());
00461 if(outputFilename.size() != 0)
00462 {
00463 pointData->ExportToFile(outputFilename, mStripBorder,
00464 mOutputFormat);
00465 }
00466 }
00467 }
00468 else
00469 {
00470
00471 if((mKeepLimited > 0) && (pointData->Size() > mKeepLimited))
00472 {
00473 ILOG_DEBUG("reducing point count");
00474
00475 pointData = ReducePointCount(pointData, mKeepLimited);
00476 }
00477
00478 if(mClusterInput)
00479 {
00480 ILOG_DEBUG("doing cluster input");
00481 int n = pointData->GetDescriptorLength();
00482 for(int i = 0; i < pointData->Size(); i++)
00483 {
00484 Vector::VectorTem<Real64> descriptor(n,
00485 pointData->GetDescriptorData(i), true);
00486
00487 if(!mClusterInputData)
00488 {
00489 ILOG_DEBUG("initializing mClusterInputData");
00490
00491 FeatureDefinition def = GetFeatureName();
00492 def.AddParameter("clusterinput", "2");
00493 mClusterInputData = new FeatureTable(def, 500, n);
00494 }
00495
00496
00497
00498
00499
00500
00501 mClusterInputData->Add(mClusterInputData->Size() + 1,
00502 descriptor);
00503 }
00504 ILOG_DEBUG("done with cluster input");
00505 }
00506 else
00507 {
00508 ILOG_DEBUG("writing point list");
00509 if(outputFilename.empty())
00510 {
00511 ILOG_WARN("Warning: no output file to write to. Did you forget to specify --output?");
00512 }
00513 else
00514 {
00515 pointData->ExportToFile(outputFilename, mStripBorder,
00516 mOutputFormat);
00517 }
00518 }
00519 }
00520 if(!borderAlreadyRemoved)
00521 {
00522 delete inputNoBorder;
00523 }
00524 }
00525
00526 ILOG_DEBUG("Completed " << GetFeatureName() << " in " <<
00527 timer.SplitTimeStr());
00528 delete pointData;
00529
00530 return true;
00531 }
00532 private:
00533 void
00534 AddToPyramids(CodebookVectors& codebookVectors, int codeword, double x,
00535 double y, int imageWidth, int imageHeight,
00536 std::vector<Real64>& regionCounts)
00537 {
00538 for(int ps = 0; ps < mPointSelector.size(); ps++)
00539 {
00540 InterestPointSelector* selector = mPointSelector[ps];
00541 if(selector->Accept(x, y, imageWidth, imageHeight))
00542 {
00543 codebookVectors[ps]->Elem(codeword) =
00544 codebookVectors[ps]->Elem(codeword) + 1;
00545 regionCounts[ps] = regionCounts[ps] + 1;
00546 }
00547 }
00548 }
00549
00550 void
00551 ProjectUNC(CodebookVectors& codebookVectors, Mat* matrixDescriptors,
00552 int imageWidth, int imageHeight, std::vector<int>& X,
00553 std::vector<int>& Y, std::vector<Real64>& regionCounts)
00554 {
00555 using namespace Matrix;
00556 Timer timerProjection;
00557 if(mDescriptorReduce)
00558 {
00559 matrixDescriptors = MatMul(matrixDescriptors, mDescriptorReduce);
00560 }
00561 Mat* matrixCodebook = mCodebook->GetColumn2()->GetStorage();
00562 ILOG_DEBUG(MatNrRow(matrixDescriptors) << " " <<
00563 MatNrCol(matrixDescriptors));
00564 ILOG_DEBUG(MatNrRow(matrixCodebook) << " " <<
00565 MatNrCol(matrixCodebook));
00566 ILOG_DEBUG("Codebook projection (init) took: " <<
00567 timerProjection.SplitTimeStr());
00568
00569 int step = Min(Int64(10000), Int64(20000000 / mCodebook->Size()));
00570 for(int k = 0; k < MatNrRow(matrixDescriptors); k += step)
00571 {
00572 int s = MatNrRow(matrixDescriptors) - k;
00573 if(step < s) s = step;
00574
00575 Mat* partial = MatCreate<Mat>(s, MatNrCol(matrixDescriptors),
00576 MatE(matrixDescriptors, k, 0), true);
00577
00578
00579 Mat* distances = MatNorm2DistTransposed(partial,
00580 matrixCodebook);
00581 delete partial;
00582
00583 ILOG_DEBUG("Codebook projection (matrix) took: " <<
00584 timerProjection.SplitTimeStr());
00585 CmdOptions& options = CmdOptions::GetInstance();
00586 Real64 sigma = options.GetDouble("codebookSigma");
00587
00588
00589 for(int vj = 0; vj < s; vj++)
00590 {
00591 for(int i = 0; i < mCodebook->Size(); i++)
00592 {
00593 Real64 value = *MatE(distances, vj, i);
00594 *MatE(distances, vj, i) = exp((-0.5 * value * value) /
00595 (sigma * sigma));
00596 }
00597 }
00598
00599
00600
00601 Mat* normalizationFactor = MatSumAxis1(distances);
00602 ILOG_DEBUG("normalizationFactor: " << MatNrRow(normalizationFactor)
00603 << " " << MatNrCol(normalizationFactor));
00604
00605
00606 for(int vj = 0; vj < s; vj++)
00607 {
00608 for(int i = 0; i < mCodebook->Size(); i++)
00609 {
00610 *MatE(distances, vj, i) = *MatE(distances, vj, i) /
00611 *MatE(normalizationFactor, vj, 0);
00612 }
00613 }
00614 delete normalizationFactor;
00615
00616
00617 for(int vj = 0; vj < s; vj++)
00618 {
00619 for(int ps = 0; ps < mPointSelector.size(); ps++)
00620 {
00621 if(mPointSelector[ps]->Accept(X[k+vj], Y[k+vj],
00622 imageWidth, imageHeight))
00623 {
00624 for(int i = 0; i < mCodebook->Size(); i++)
00625 {
00626 codebookVectors[ps]->Elem(i) =
00627 codebookVectors[ps]->Elem(i) +
00628 *MatE(distances, vj, i);
00629 }
00630 regionCounts[ps] = regionCounts[ps] + 1;
00631 }
00632 }
00633 }
00634 delete distances;
00635 ILOG_DEBUG("Codebook projection (piece) took: " <<
00636 timerProjection.SplitTimeStr() << " " << mPointSelector.size());
00637 }
00638 ILOG_INFO("Codebook projection (UNC/" << MatNrRow(matrixDescriptors) <<
00639 ") took: " << timerProjection.SplitTimeStr());
00640 if(mDescriptorReduce)
00641 {
00642 delete matrixDescriptors;
00643 }
00644 }
00645
00646 void
00647 ProjectLLC(CodebookVectors& codebookVectors, String codebookMode,
00648 Mat* matrixDescriptors, int imageWidth,
00649 int imageHeight, std::vector<int>& X, std::vector<int>& Y,
00650 std::vector<Real64>& regionCounts, Util::IOBuffer* dumpIndices=0)
00651 {
00652 using namespace Matrix;
00653 Timer timerProjection;
00654 if(mDescriptorReduce)
00655 {
00656 matrixDescriptors = MatMul(matrixDescriptors, mDescriptorReduce);
00657 }
00658 Mat* matrixCodebook = mCodebook->GetColumn2()->GetStorage();
00659 ILOG_DEBUG(MatNrRow(matrixDescriptors) << " " <<
00660 MatNrCol(matrixDescriptors));
00661 ILOG_DEBUG(MatNrRow(matrixCodebook) << " " <<
00662 MatNrCol(matrixCodebook));
00663 ILOG_DEBUG("Codebook projection (init) took: " <<
00664 timerProjection.SplitTimeStr());
00665
00666 int knn = CmdOptions::GetInstance().GetInt("codebookSigma");
00667 Real64 beta = 1e-4;
00668 int step = Min(Int64(10000), Int64(20000000 / mCodebook->Size()));
00669 Mat* II = MatEye<Mat>(knn);
00670 MulVal(II, II, beta);
00671 Mat* onesVector = MatCreate<Mat>(knn, 1);
00672 SetVal(onesVector, 1.0);
00673
00674 Mat* dumpedIndices = 0;
00675 if(dumpIndices)
00676 {
00677 dumpedIndices = MatCreate<Mat>(MatNrRow(matrixDescriptors), 2*knn+2);
00678 }
00679 String config = codebookMode;
00680 String absolute = StringSplit(config, '-');
00681 String aggregationMode = StringSplit(config, '-');
00682 String normMode = StringSplit(config, '-');
00683 ILOG_INFO("absolute=" << absolute << "; aggregationMode=" <<
00684 aggregationMode << "; normMode=" << normMode);
00685 for(int kkk = 0; kkk < MatNrRow(matrixDescriptors); kkk += step)
00686 {
00687 int s = MatNrRow(matrixDescriptors) - kkk;
00688 if(step < s) s = step;
00689
00690 Mat* partial = MatCreate<Mat>(s, MatNrCol(matrixDescriptors),
00691 MatE(matrixDescriptors, kkk, 0), true);
00692
00693
00694 Mat* distances = MatNorm2DistTransposed(partial,
00695 matrixCodebook);
00696
00697 ILOG_DEBUG("Euclidean distance matrix took: " <<
00698 timerProjection.SplitTimeStr());
00699
00700
00701 std::vector<std::pair<Real64, int> > distancesAndIndices;
00702
00703 for(int vj = 0; vj < s; vj++)
00704 {
00705 distancesAndIndices.clear();
00706 distancesAndIndices.reserve(mCodebook->Size());
00707 for(int i = 0; i < mCodebook->Size(); i++)
00708 {
00709 distancesAndIndices.push_back(
00710 std::make_pair(*MatE(distances, vj, i), i));
00711 }
00712 std::nth_element(distancesAndIndices.begin(),
00713 distancesAndIndices.begin() + knn,
00714 distancesAndIndices.end());
00715
00716
00717
00718
00719
00720 Mat* z = MatCreate<Mat>(knn, MatNrCol(matrixDescriptors));
00721 for(int kk = 0; kk < knn; kk++)
00722 {
00723 int closestCodebookIndex = distancesAndIndices[kk].second;
00724 for(int i = 0; i < MatNrCol(matrixDescriptors); i++)
00725 {
00726 *MatE(z, kk, i) = *MatE(matrixCodebook,
00727 closestCodebookIndex, i) -
00728 *MatE(partial, vj, i);
00729 }
00730 }
00731
00732
00733 Mat* zT = MatTranspose(z);
00734 Mat* C = MatMul(z, zT);
00735 delete z; delete zT;
00736
00737
00738 Mat* tmp = 0;
00739 MulVal(tmp, II, MatTrace(C));
00740 Add(C, C, tmp);
00741 delete tmp;
00742
00743 Mat* invertedC = MatInverse(C);
00744 Mat* w = MatMul(invertedC, onesVector);
00745 delete invertedC;
00746 delete C;
00747
00748
00749
00750 Real64 total = 0.0;
00751 if(absolute == "llca")
00752 {
00753 for(int kk = 0; kk < knn; kk++)
00754 total += fabs(*MatE(w, kk, 0));
00755 for(int kk = 0; kk < knn; kk++)
00756 {
00757 *MatE(w, kk, 0) = fabs(*MatE(w, kk, 0)) / total;
00758 }
00759 }
00760 else
00761 {
00762 for(int kk = 0; kk < knn; kk++)
00763 total += *MatE(w, kk, 0);
00764 for(int kk = 0; kk < knn; kk++)
00765 {
00766 *MatE(w, kk, 0) = *MatE(w, kk, 0) / total;
00767 }
00768 }
00769
00770 if(aggregationMode == "avg")
00771 {
00772 for(int ps = 0; ps < mPointSelector.size(); ps++)
00773 {
00774 if(mPointSelector[ps]->Accept(X[kkk+vj], Y[kkk+vj],
00775 imageWidth, imageHeight))
00776 {
00777 for(int kk = 0; kk < knn; kk++)
00778 {
00779 int closestCodebookIndex =
00780 distancesAndIndices[kk].second;
00781 codebookVectors[ps]->Elem(closestCodebookIndex) =
00782 codebookVectors[ps]->Elem(closestCodebookIndex) + *MatE(w, kk, 0);
00783 }
00784 regionCounts[ps] = regionCounts[ps] + 1;
00785 }
00786 }
00787 }
00788 else if(aggregationMode == "max" || aggregationMode.empty())
00789 {
00790 for(int ps = 0; ps < mPointSelector.size(); ps++)
00791 {
00792 if(mPointSelector[ps]->Accept(X[kkk+vj], Y[kkk+vj],
00793 imageWidth, imageHeight))
00794 {
00795 for(int kk = 0; kk < knn; kk++)
00796 {
00797 int closestCodebookIndex =
00798 distancesAndIndices[kk].second;
00799 codebookVectors[ps]->Elem(closestCodebookIndex) =
00800 Max(codebookVectors[ps]->Elem(closestCodebookIndex), *MatE(w, kk, 0));
00801 }
00802 regionCounts[ps] = 1;
00803 }
00804 }
00805 }
00806
00807
00808 if(dumpIndices)
00809 {
00810 *MatE(dumpedIndices, kkk+vj, 0) = X[kkk+vj];
00811 *MatE(dumpedIndices, kkk+vj, 1) = Y[kkk+vj];
00812 for(int kk = 0; kk < knn; kk++)
00813 {
00814 int closestCodebookIndex =
00815 distancesAndIndices[kk].second;
00816 *MatE(dumpedIndices, kkk+vj, kk*2 + 2) = closestCodebookIndex;
00817 *MatE(dumpedIndices, kkk+vj, kk*2 + 3) = *MatE(w, kk, 0);
00818 }
00819 }
00820 delete w;
00821 }
00822 delete partial;
00823 delete distances;
00824 ILOG_DEBUG("Codebook projection (piece) took: " <<
00825 timerProjection.SplitTimeStr() << " " << mPointSelector.size());
00826 }
00827 delete II;
00828 delete onesVector;
00829 ILOG_INFO("Codebook projection (LLC/" << MatNrRow(matrixDescriptors) <<
00830 ") took: " << timerProjection.SplitTimeStr());
00831 if(mDescriptorReduce)
00832 {
00833 delete matrixDescriptors;
00834 }
00835 if(normMode.empty())
00836 {
00837
00838 for(int ps = 0; ps < mPointSelector.size(); ps++)
00839 {
00840 regionCounts[ps] = 1;
00841 }
00842 }
00843 else if(normMode == "L2")
00844 {
00845 for(int ps = 0; ps < mPointSelector.size(); ps++)
00846 {
00847 Real64 tmp = 0.0;
00848 for(int i = 0; i < mCodebook->Size(); i++)
00849 {
00850 tmp += codebookVectors[ps]->Elem(i) * codebookVectors[ps]->Elem(i);
00851 }
00852 regionCounts[ps] = sqrt(tmp);
00853 }
00854 }
00855 else if(normMode == "L2a")
00856 {
00857 Real64 tmp = 0.0;
00858 for(int ps = 0; ps < mPointSelector.size(); ps++)
00859 {
00860 for(int i = 0; i < mCodebook->Size(); i++)
00861 {
00862 tmp += codebookVectors[ps]->Elem(i) * codebookVectors[ps]->Elem(i);
00863 }
00864 }
00865 for(int ps = 0; ps < mPointSelector.size(); ps++)
00866 regionCounts[ps] = sqrt(tmp);
00867 }
00868 else if(normMode == "L1")
00869 {
00870 for(int ps = 0; ps < mPointSelector.size(); ps++)
00871 {
00872 Real64 tmp = 0.0;
00873 for(int i = 0; i < mCodebook->Size(); i++)
00874 {
00875 tmp += codebookVectors[ps]->Elem(i);
00876 }
00877 regionCounts[ps] = tmp;
00878 }
00879 }
00880 else if(normMode == "L1a")
00881 {
00882 Real64 total = 0.0;
00883 for(int ps = 0; ps < mPointSelector.size(); ps++)
00884 {
00885 Real64 tmp = 0.0;
00886 for(int i = 0; i < mCodebook->Size(); i++)
00887 {
00888 tmp += codebookVectors[ps]->Elem(i);
00889 }
00890 regionCounts[ps] = tmp;
00891 total += tmp;
00892 }
00893 for(int ps = 0; ps < mPointSelector.size(); ps++)
00894 {
00895 regionCounts[ps] = total;
00896 }
00897 }
00898
00899 if(dumpIndices)
00900 {
00901 WriteRaw(dumpedIndices, dumpIndices, 3);
00902 delete dumpedIndices;
00903 }
00904 }
00905
00906 void
00907 ProjectHardMatrix(CodebookVectors& codebookVectors, Mat* matrixDescriptors,
00908 int imageWidth, int imageHeight, std::vector<int>& X,
00909 std::vector<int>& Y, std::vector<Real64>& regionCounts)
00910 {
00911 using namespace Matrix;
00912 Timer timerProjection;
00913 if(mDescriptorReduce)
00914 {
00915 matrixDescriptors = MatMul(matrixDescriptors, mDescriptorReduce);
00916 }
00917 Mat* matrixCodebook = mCodebook->GetColumn2()->GetStorage();
00918 ILOG_DEBUG(MatNrRow(matrixDescriptors) << " " <<
00919 MatNrCol(matrixDescriptors));
00920 ILOG_DEBUG(MatNrRow(matrixCodebook) << " " <<
00921 MatNrCol(matrixCodebook));
00922 ILOG_DEBUG("Codebook projection (init) took: " <<
00923 timerProjection.SplitTimeStr());
00924
00925 Mat* assignment =
00926 Core::Matrix::VectorQuantize(matrixDescriptors, matrixCodebook);
00927
00928 ILOG_DEBUG("Codebook projection (matrix) took: " <<
00929 timerProjection.SplitTimeStr());
00930 for(int vj = 0; vj < MatNrRow(matrixDescriptors); vj++)
00931 {
00932 Real64 bestDistance = *MatE(assignment, vj, 1);
00933 int bestIndex = static_cast<int>(*MatE(assignment, vj, 0));
00934 AddToPyramids(codebookVectors, bestIndex, X[vj], Y[vj], imageWidth,
00935 imageHeight, regionCounts);
00936
00937
00938 }
00939 ILOG_DEBUG("Codebook projection (matrix-form) took: " <<
00940 timerProjection.SplitTimeStr());
00941 delete assignment;
00942 if(mDescriptorReduce)
00943 {
00944 delete matrixDescriptors;
00945 }
00946 }
00947
00948
00949 void
00950 ProjectHardIndex(Mat* matrixDescriptors, PointDescriptorTable* pointData)
00951 {
00952 using namespace Matrix;
00953 Timer timerProjection;
00954 if(mDescriptorReduce)
00955 {
00956 matrixDescriptors = MatMul(matrixDescriptors, mDescriptorReduce);
00957 }
00958 Mat* matrixCodebook = mCodebook->GetColumn2()->GetStorage();
00959 ILOG_DEBUG("Codebook projection (init) took: " <<
00960 timerProjection.SplitTimeStr());
00961
00962 Mat* assignment =
00963 Core::Matrix::VectorQuantize(matrixDescriptors, matrixCodebook);
00964 ILOG_INFO("Codebook projection (matrix) took: " <<
00965 timerProjection.SplitTimeStr());
00966
00967 Array::Array2dScalarReal64* newDesc = new Array::Array2dScalarReal64(1,
00968 pointData->Size(), 0, 0);
00969 for(int vj = 0; vj < MatNrRow(matrixDescriptors); vj++)
00970 {
00971 Real64 bestDistance = *MatE(assignment, vj, 1);
00972 int bestIndex = static_cast<int>(*MatE(assignment, vj, 0));
00973 *MatE(newDesc, vj, 0) = bestIndex;
00974 }
00975
00976 pointData->ReplaceAllDescriptors(newDesc);
00977 delete assignment;
00978 if(mDescriptorReduce)
00979 {
00980 delete matrixDescriptors;
00981 }
00982 }
00983
00984
00985 void
00986 ProjectForest(CodebookVectors& codebookVectors, Mat* descriptors, int imageWidth,
00987 int imageHeight, std::vector<int>& X, std::vector<int>& Y,
00988 std::vector<Real64>& regionCounts)
00989 {
00990 using namespace Matrix;
00991
00992 ILOG_DEBUG("creating random forest from feature table");
00993 RandomForest forest = ReadRandomForest(mCodebook);
00994
00995
00996
00997 Timer timerProjection;
00998 for(int vj = 0; vj < MatNrRow(descriptors); vj++)
00999 {
01000 for(int i=0; i<forest.size(); ++i)
01001 {
01002 RandomTree* tree = forest[i];
01003 ILOG_DEBUG("getting codeword");
01004 int codeword = tree->GetCodeWord(Vector::VectorTem<Real64>(MatNrCol(descriptors), descriptors->CPB(0, vj), true));
01005 ILOG_DEBUG("got codeword");
01006 AddToPyramids(codebookVectors, codeword, X[vj], Y[vj],
01007 imageWidth, imageHeight, regionCounts);
01008 }
01009 }
01010 DeleteForest(forest);
01011 ILOG_DEBUG("Codebook projection (forest) took: " <<
01012 timerProjection.SplitTimeStr());
01013 }
01014
01015 PointDescriptorTable*
01016 ProjectOntoCodebook(PointDescriptorTable* pointData, String codebookMode,
01017 int imageWidth, int imageHeight, Quid quid)
01018 {
01025 using namespace Matrix;
01026 ILOG_DEBUG("ProjectOntoCodebook called");
01027 PointDescriptorTable* output = new PointDescriptorTable(
01028 pointData->GetFeatureDefinition());
01029 Array::Array2dScalarInt32* tempDynamic = 0;
01030 if(mDynamicPointSelector)
01031 {
01032
01033 String filename = "PointSelector/" + mDynamicPointSelectorConfig +
01034 "/" + MakeString(quid) + ".raw";
01035 FileLocator loc(mLocator, filename);
01036 File file = RepositoryGetFile(loc, false, false);
01037 Util::IOBuffer* buf = file.GetReadBuffer();
01038
01039
01040 ReadRaw(tempDynamic, buf);
01041 delete buf;
01042 for(int i = 0; i < tempDynamic->CH(); i++)
01043 {
01044 *tempDynamic->CPB(0, i) -= (mStripBorder + 1);
01045 *tempDynamic->CPB(1, i) -= (mStripBorder + 1);
01046 }
01047
01048 for(int ps = 0; ps < tempDynamic->CW() - 2; ps++)
01049 {
01050 mPointSelector.push_back
01051 (new Geometry::MaskedInterestPointSelector(tempDynamic, ps));
01052 }
01053 }
01054
01055 std::vector<Real64> regionCounts;
01056 int codebookLength = mCodebook->Size();
01057 if(codebookMode == "forest")
01058 {
01059 codebookLength = GetCodebookLength(mCodebook);
01060 ILOG_DEBUG("forest codebook length = "<< codebookLength);
01061 }
01062
01063 CodebookVectors codebookVectors;
01064 for(int ps = 0; ps < mPointSelector.size(); ps++)
01065 {
01066 Vector::VectorTem<Real64>* codebookVector =
01067 new Vector::VectorTem<Real64>(codebookLength);
01068 for(int i = 0; i < codebookLength; i++)
01069 {
01070 codebookVector->Elem(i) = 0.0;
01071 }
01072 codebookVectors.push_back(codebookVector);
01073 regionCounts.push_back(0);
01074 }
01075 ILOG_DEBUG("done making codebook vector");
01076 if(pointData->Size() == 0)
01077 {
01078 if(mResultOutput)
01079 {
01080 for(int i = 0; i < codebookVectors.size(); i++)
01081 {
01082 mResultOutput->AddVector(quid, i, *codebookVectors[i]);
01083 }
01084 }
01085 delete pointData;
01086 return output;
01087 }
01088 int descriptorLength = pointData->GetDescriptorLength();
01089 std::vector<int> X;
01090 std::vector<int> Y;
01091 X.reserve(pointData->Size());
01092 Y.reserve(pointData->Size());
01093
01094 ILOG_DEBUG("extracting descriptor data");
01095 for(int it = 0; it < pointData->Size(); it++)
01096 {
01097 X.push_back(static_cast<int>(pointData->GetX(it)));
01098 Y.push_back(static_cast<int>(pointData->GetY(it)));
01099 }
01100
01101
01102 if((codebookMode != "forest") &&
01103 (mCodebook->Get2(0).Size() != descriptorLength))
01104 {
01105 if(mDescriptorReduce)
01106 {
01107 if((mCodebook->Get2(0).Size() != MatNrCol(mDescriptorReduce))
01108 || (descriptorLength != MatNrRow(mDescriptorReduce)))
01109 {
01110 ILOG_ERROR("Reduced descriptor dimensionality mismatch");
01111 throw "bye";
01112 }
01113 }
01114 else
01115 {
01116 ILOG_ERROR("ProjectOntoCodebook found visual word"<<
01117 " and descriptor of different sizes!\n\t\t"<<
01118 "codebook: "<< mCodebook->Get2(0).Size() <<
01119 ", descriptor:"<< descriptorLength);
01120 throw "Dimensionality mismatch!";
01121 }
01122 }
01123
01124
01125 Array2dScalarReal64* descriptors =
01126 new Array2dScalarReal64(descriptorLength, pointData->Size(), 0, 0,
01127 pointData->GetColumn6()->GetStorage()->mData, true);
01128
01129 ILOG_DEBUG("extracted descriptor data");
01130
01131
01132 if(codebookMode == "unc")
01133 ProjectUNC(codebookVectors, descriptors, imageWidth, imageHeight,
01134 X, Y, regionCounts);
01135
01136 if((codebookMode == "hardmatrix") || (codebookMode == "hard"))
01137 ProjectHardMatrix(codebookVectors, descriptors, imageWidth,
01138 imageHeight, X, Y, regionCounts);
01139
01140 if(codebookMode == "hardindex")
01141 {
01142 ProjectHardIndex(descriptors, pointData);
01143 delete descriptors;
01144 delete output;
01145 for(int i = 0; i < codebookVectors.size(); i++)
01146 delete codebookVectors[i];
01147 codebookVectors.clear();
01148 return pointData;
01149 }
01150 if(codebookMode == "forest")
01151 ProjectForest(codebookVectors, descriptors, imageWidth, imageHeight,
01152 X, Y, regionCounts);
01153
01154 if(StringStartsWith(codebookMode, "llcdump"))
01155 {
01156 String folder = "ClusterIndices/" + GetFeatureName();
01157 String filename = PathJoin(folder, MakeString(quid) + ".raw");
01158 FileLocator loc(mLocator, filename);
01159 File file = RepositoryGetFile(loc, true, false);
01160 Util::IOBuffer* buf = file.GetWriteBuffer();
01161 codebookMode = StringReplace(codebookMode, "llcdump", "llc");
01162 ProjectLLC(codebookVectors, codebookMode, descriptors, imageWidth,
01163 imageHeight, X, Y, regionCounts, buf);
01164 delete buf;
01165 }
01166 else if(StringStartsWith(codebookMode, "llc"))
01167 {
01168 ProjectLLC(codebookVectors, codebookMode, descriptors, imageWidth,
01169 imageHeight, X, Y, regionCounts);
01170 }
01171 delete descriptors;
01172
01173
01174
01175
01176 for(int ps = 0; ps < mPointSelector.size(); ps++)
01177 {
01178
01179 Real64 regionCount = regionCounts[ps];
01180 ILOG_DEBUG("regCount " << regionCount);
01181 if(regionCount == 0)
01182 regionCount = 1;
01183 for(int i = 0; i < codebookLength; i++)
01184 {
01185 codebookVectors[ps]->Elem(i) =
01186 codebookVectors[ps]->Elem(i) / regionCount;
01187 }
01188 }
01189 if(mPointSelector.size() > 0)
01190 output->SetDescriptorLength(codebookLength);
01191 output->Reserve(mPointSelector.size(), false);
01192 for(int ps = 0; ps < mPointSelector.size(); ps++)
01193 {
01194 output->Add(0, 0, 0, 0, 0);
01195
01196
01197 output->SetDescriptor(ps, *(codebookVectors[ps]));
01198 }
01199
01200 if(mResultOutput)
01201 {
01202 for(int i = 0; i < codebookVectors.size(); i++)
01203 {
01204 mResultOutput->AddVector(quid, i,
01205 *codebookVectors[i]);
01206 }
01207 }
01208
01209 if(mDynamicPointSelector)
01210 {
01211 for(int ps = 0; ps < mPointSelector.size(); ps++)
01212 {
01213 delete mPointSelector[ps];
01214 }
01215 mPointSelector.clear();
01216 delete tempDynamic;
01217 }
01218 delete pointData;
01219 return output;
01220 }
01221
01222
01223 PointDescriptorTable*
01224 ReducePointCount(PointDescriptorTable* pointData, int keepCount)
01225 {
01226 std::vector<int> indices;
01227 bool* keepers = new bool[pointData->Size()];
01228 for(int j = 0; j < pointData->Size(); j++)
01229 {
01230 indices.push_back(j);
01231 keepers[j] = false;
01232 }
01233 std::random_shuffle(indices.begin(), indices.end(), mRNG);
01234
01235 for(int j = 0; j < keepCount; j++)
01236 {
01237 keepers[indices[j]] = true;
01238 }
01239
01240 PointDescriptorTable* output = new PointDescriptorTable(pointData->GetFeatureDefinition());
01241 output->SetDescriptorLength(pointData->GetDescriptorLength());
01242 Select(output, pointData, keepers, false);
01243 delete pointData;
01244 return output;
01245 }
01246
01247
01248 template<class SrcArrayT>
01249 PointDescriptorTable*
01250 DenseAllDetector(SrcArrayT* input)
01251 {
01252 PointDescriptorTable* output = new PointDescriptorTable();
01253 int w = input->CW();
01254 int h = input->CH();
01255 output->SetEmpty();
01256 output->Reserve(w * h * mDenseSamplingScales.size(), false);
01257 for(int y = 0; y < h; y += 1)
01258 {
01259 for(int x = 0; x < w; x++)
01260 {
01261 for(int q = 0; q < mDenseSamplingScales.size(); q++)
01262 {
01263 output->Add(x, y, mDenseSamplingScales[q], 0, 0);
01264 }
01265 }
01266 }
01267 ILOG_INFO("Points detected: " << output->Size());
01268 return output;
01269 }
01270
01271
01272 template<class SrcArrayT>
01273 PointDescriptorTable*
01274 DenseSamplingDetector(SrcArrayT* input, int spacing)
01275 {
01276 PointDescriptorTable* output = new PointDescriptorTable();
01277 int halfspacing = spacing / 2;
01278 int w = input->CW();
01279 int h = input->CH();
01280 int i = 0;
01281 for(int y = spacing; y < h - spacing; y += spacing)
01282 {
01283 int x = spacing;
01284 if(i % 2 == 0)
01285 {
01286 x += halfspacing;
01287 }
01288 for(; x < w - spacing; x += spacing)
01289 {
01290 for(int q = 0; q < mDenseSamplingScales.size(); q++)
01291 {
01292
01293
01298
01299 output->Add(x, y, mDenseSamplingScales[q], 0, 0);
01300 }
01301 }
01302 i += 1;
01303 }
01304 return output;
01305 }
01306
01307
01308 PointDescriptorTable*
01309 ApplyDetector(Array::Array2dVec3UInt8* inputNoBorder, String detectorMode)
01310 {
01311 CmdOptions& options = CmdOptions::GetInstance();
01312 Real64 harrisThreshold = options.GetDouble("harrisThreshold");
01313 Real64 harrisK = options.GetDouble("harrisK");
01314 Real64 laplaceThreshold = options.GetDouble("laplaceThreshold");
01315
01316 PointDescriptorTable* output = 0;
01317
01318 if((detectorMode == "harrislaplace") || (detectorMode == "harrislaplace2"))
01319 {
01320 HarrisLaplaceDetector detector(mUseRecGauss);
01321 detector.mBackwardsCompatible = false;
01322 output = detector.HLDetector(inputNoBorder, harrisThreshold,
01323 harrisK, laplaceThreshold);
01324 }
01325 else if(detectorMode == "colorharrislaplace")
01326 {
01327
01328
01329 HarrisLaplaceDetector detector(mUseRecGauss);
01330 detector.mBackwardsCompatible = false;
01331 output = detector.CHLDetector(inputNoBorder, harrisThreshold,
01332 harrisK, laplaceThreshold);
01333 }
01334 else if(detectorMode == "laplacian")
01335 {
01336 output = LaplacianDetector(inputNoBorder, true);
01337 }
01338 else if(detectorMode == "densesampling")
01339 {
01340 int spacing = options.GetInt("ds_spacing");
01341 output = DenseSamplingDetector(inputNoBorder, spacing);
01342 }
01343 else if(detectorMode == "denseall")
01344 {
01345 output = DenseAllDetector(inputNoBorder);
01346 }
01347 else if(detectorMode == "none")
01348 {
01349
01350
01351 output = new PointDescriptorTable();
01352 }
01353 else
01354 {
01355 ILOG_ERROR("[ERROR] Unknown detector mode: " << detectorMode);
01356 return 0;
01357 }
01358 output->SetFeatureDefinition(FeatureDefinition(detectorMode));
01359 return output;
01360 }
01361
01362
01363 void
01364 ComputeDescriptors(PointDescriptorTable* pointData,
01365 Array::Array2dVec3UInt8* inputNoBorder,
01366 String descriptorMode)
01367 {
01368 if((descriptorMode == "huesift") || (descriptorMode == "huefist"))
01369 {
01370 using namespace Core::Matrix;
01371 CalculateRegionDescriptors(inputNoBorder, pointData,
01372 "huehistogram");
01373
01374
01375 Mat* part1 = MatCreate<Mat>(pointData->Size(), pointData->GetDescriptorLength());
01376 for(int i = 0; i < pointData->Size(); i++)
01377 {
01378 Real64* ptr = pointData->GetDescriptorData(i);
01379 for(int j = 0; j < MatNrCol(part1); j++)
01380 {
01381 *MatE(part1, i, j) = static_cast<int>(ptr[j] * 512);
01382 }
01383 }
01384
01385 CalculateFISTDescriptors(inputNoBorder, pointData, "sift");
01386 Mat* part0 = pointData->GetDescriptorMatrix();
01387 std::vector<Mat*> matrices;
01388 matrices.push_back(part0);
01389 matrices.push_back(part1);
01390 Matrix::Mat* descriptors =
01391 Matrix::MatConcatenateHorizontal(matrices);
01392
01393
01394 pointData->ReplaceAllDescriptors(descriptors);
01395
01396 delete part1;
01397 }
01398 else if((descriptorMode.size() >= 4) &&
01399 (descriptorMode.substr(descriptorMode.size()-4,4) == "fist"))
01400 {
01401 CalculateFISTDescriptors
01402 (inputNoBorder, pointData, descriptorMode);
01403 }
01404 else if((descriptorMode.size() >= 4) &&
01405 (descriptorMode.substr(descriptorMode.size()-4,4) == "sift"))
01406 {
01407 CalculateFISTDescriptors
01408 (inputNoBorder, pointData, descriptorMode);
01409 }
01410 else if((descriptorMode.size() >= 4) &&
01411 (descriptorMode.substr(descriptorMode.size()-4,4) == "surf"))
01412 {
01413 CalculateSurfDescriptors
01414 (inputNoBorder, pointData, descriptorMode, mSurfParams[0],
01415 mSurfParams[1], mSurfParams[2]);
01416 }
01417 else if(descriptorMode == "none")
01418 {
01419
01420 }
01421 else
01422 {
01423 CalculateRegionDescriptors
01424 (inputNoBorder, pointData, descriptorMode);
01425 }
01426 }
01427
01428
01429 int mVerbose;
01430 int mStripBorder;
01431 bool mUseRecGauss;
01432 String mName;
01433 FeatureDefinition mFeatureDefinition;
01434 int mKeepLimited;
01435 String mOutputFormat;
01436 FeatureTable* mCodebook;
01437 Mat* mDescriptorReduce;
01438 String mDescriptorReduceFilename;
01439
01440 FeatureTableResult* mResultOutput;
01441 Array::Array2dScalarUInt64* mExtraBoxes;
01442
01443 std::vector<InterestPointSelector*> mPointSelector;
01444 bool mDynamicPointSelector;
01445 String mDynamicPointSelectorConfig;
01446 Persistency::Locator mLocator;
01447 std::vector<Real64> mDenseSamplingScales;
01448 int mSurfParams[3];
01449
01450 Util::Random mRNG;
01451 Util::TimeStats mTimeStats;
01452
01453 ILOG_VAR_DEC;
01454 };
01455
01456 ILOG_VAR_INIT(InterestPointFeature, Core.Feature);
01457
01458 }
01459 }
01460 }
01461
01462 #endif