00001 #ifndef Impala_Core_ImageSet_InterestPointProc_h
00002 #define Impala_Core_ImageSet_InterestPointProc_h
00003
00004 #include "Core/ImageSet/Reporter.h"
00005 #include "Core/ImageSet/MakeImageSet.h"
00006 #include "Core/Array/MakeFromValue.h"
00007 #include "Core/Array/ArrayListDelete.h"
00008 #include "Core/Array/WriteRaw.h"
00009 #include "Core/Feature/FeatureTable.h"
00010 #include "Core/Feature/InterestPointFeature.h"
00011 #include "Core/Feature/DumpFeatureTableHistogram.h"
00012
00013 namespace Impala
00014 {
00015 namespace Core
00016 {
00017 namespace ImageSet
00018 {
00019
00020 class InterestPointProc : public Listener
00021 {
00022 public:
00023
00024 InterestPointProc(Reporter* reporter, CmdOptions& options)
00025 : mInterestPointFeature(options), mOptions(options), mNoZIP(false),
00026 mSkipThisFolder(false)
00027 {
00028 mReporter = reporter;
00029 mNoZIP = options.GetBool("noZIP");
00030 mTableInfoString = "codebook=" + options.GetString("codebook");
00031 mCodebookSet = "";
00032 if (options.GetNrArg() > 2)
00033 mCodebookSet = options.GetArg(2);
00034 if(mNoZIP) {
00035 ILOG_INFO("NOT creating ZIP output files");
00036 } else {
00037 ILOG_INFO("Creating ZIP output files");
00038 }
00039 }
00040
00041 static void
00042 AddCmdOptions()
00043 {
00044 Feature::InterestPointFeature::AddCmdOptions();
00045
00046 CmdOptions& options = CmdOptions::GetInstance();
00047 options.AddOption(0, "noZIP", "", "0");
00048 options.AddOption(0, "interestPointPostProcess", "command", "");
00049 options.AddOption(0, "useDetectorCache", "name", "");
00050 }
00051
00052 virtual void
00053 HandleNewWalk(ImageSet* is)
00054 {
00055 if(!mOptions.GetString("codebook").empty())
00056 {
00057 Database::RawDataSet* bookSet = is;
00058 if (!mCodebookSet.empty())
00059 {
00060 ILOG_INFO("Using separate codebook set: " << mCodebookSet);
00061 bookSet = Database::MakeRawDataSet(mCodebookSet);
00062 }
00063
00064 mInterestPointFeature.SetCodebook(mOptions.GetString("codebook"),
00065 bookSet->GetDatabase());
00066 }
00067 }
00068
00069 virtual void
00070 HandleNewWalk(ImageSet* is, String walkType)
00071 {
00072 mWalkType = walkType;
00073 }
00074
00075 virtual void
00076 HandleNewDir(ImageSet* is, int dirId)
00077 {
00078
00079 ILOG_INFO("HandleNewDir: " << dirId);
00080 int fileId = is->GetFirstFileId(dirId);
00081 is->MakeDirId("FeatureData", mInterestPointFeature.GetFeatureNameShort(),
00082 fileId, false);
00083 mTempFilenames.clear();
00084 mSkipThisFolder = false;
00085 if(!CmdOptions::GetInstance().GetBool("override"))
00086 {
00087
00088 if(!mNoZIP)
00089 {
00090
00091 String serverName = is->GetFilePathFeatureData
00092 (mInterestPointFeature.GetFeatureName(), dirId, false, -1,
00093 true, false) + ".zip";
00094 String temp =
00095 is->GetDatabase()->GetFilePath(serverName, false, true);
00096 if(!temp.empty())
00097 {
00098 mSkipThisFolder = true;
00099 ILOG_WARNING("Skipping folder " << dirId <<
00100 "; ZIP file already exists");
00101 }
00102 }
00103 else
00104 {
00105 if(mInterestPointFeature.mClusterInput)
00106 {
00107
00108 Feature::FeatureDefinition def = mInterestPointFeature.GetFeatureName();
00109 def.AddParameter("clusterinput", "2");
00110 String tableName = is->GetFilePathFeatureData
00111 (def, dirId, false, -1, false, true);
00112 if(!tableName.empty())
00113 {
00114 mSkipThisFolder = true;
00115 ILOG_WARNING("Skipping folder " << dirId <<
00116 "; FeatureData:ClusterInput file already exists");
00117 }
00118 }
00119 else
00120 {
00121
00122 String tableName = is->GetFilePathFeatureData
00123 (mInterestPointFeature.mFeatureDefinition, dirId, false,
00124 -1, false, true);
00125 if(!tableName.empty())
00126 {
00127 mSkipThisFolder = true;
00128 ILOG_WARNING("Skipping folder " << dirId <<
00129 "; FeatureData file already exists");
00130 }
00131 }
00132 }
00133 }
00134 }
00135
00136 virtual void
00137 HandleNewFile(ImageSet* is, int fileId, Array::Array2dVec3UInt8* im)
00138 {
00139 if(mSkipThisFolder)
00140 return;
00141 int dirId = is->GetDirIdOfFile(fileId);
00142
00143 String fileName = is->GetAsPath(fileId);
00144
00145 String outputFilename =
00146 PathJoin(GetTmpPath(), is->GetFileBase(fileId) + "." +
00147 mInterestPointFeature.GetFeatureName());
00148 ILOG_DEBUG(" outputFilename=" << outputFilename << "; fileId=" << fileId
00149 << "; dirId=" << dirId);
00150 if (im == 0)
00151 {
00152 ILOG_ERROR("No image " << fileName);
00153 return;
00154 }
00155
00156 String detectorCacheFilename = "";
00157 if(mOptions.GetString("useDetectorCache") != "")
00158 {
00159 detectorCacheFilename = is->GetFilePathId
00160 ("FeatureData", mOptions.GetString("useDetectorCache"), fileId,
00161 false, false, is->GetFileBase(fileId) + "." +
00162 mOptions.GetString("useDetectorCache"), false);
00163 ILOG_INFO("detectorCacheFilename = " << detectorCacheFilename);
00164 }
00165 if(mNoZIP) {
00166 outputFilename = "";
00167 }
00168 mInterestPointFeature.mClusterInputImage =
00169 QuidObj(is->GetQuidImage(fileId)).ToString();
00170
00171 if(!mInterestPointFeature.FindInterestPoints(mOptions, im,
00172 is->GetQuidImage(fileId),
00173 outputFilename,
00174 true, detectorCacheFilename))
00175 {
00176 ILOG_ERROR("Extracting interest points/descriptors failed: "<<fileName);
00177 }
00178
00179 if(mInterestPointFeature.mLastCodebookVectors.size() != 0)
00180 {
00181
00182 std::vector<Vector::VectorTem<Real64>*>& featureVectors =
00183 mInterestPointFeature.mLastCodebookVectors;
00184 if(mFeatureTables.size() < featureVectors.size())
00185 {
00186
00187 for(int i = mFeatureTables.size(); i < featureVectors.size(); i++)
00188 {
00189 String name = mInterestPointFeature.GetFeatureName();
00190 Feature::FeatureTable* t = new Feature::FeatureTable(name, 500,
00191 featureVectors[i]->Size());
00192 mFeatureTables.push_back(t);
00193 }
00194 }
00195 for(int i = 0; i < featureVectors.size(); i++)
00196 {
00197 Quid quid = is->GetQuidImage(fileId);
00198 mFeatureTables[i]->Add(quid, *featureVectors[i]);
00199 }
00200 }
00201
00202
00203 if(mOptions.GetString("interestPointPostProcess") != "")
00204 {
00205 String cmd = mOptions.GetString("interestPointPostProcess")
00206 + " " + outputFilename;
00207 ILOG_DEBUG("Post-processing = " << cmd);
00208 system(cmd.c_str());
00209 }
00210 if(!mNoZIP)
00211 {
00212 mTempFilenames.push_back(outputFilename);
00213 }
00214 }
00215
00217 virtual void
00218 HandleDoneDir(ImageSet* is, int dirId)
00219 {
00220 if(mSkipThisFolder) return;
00221 int fileId = is->GetFirstFileId(dirId);
00222
00223
00224 Feature::FeatureDefinition fdef = mInterestPointFeature.mFeatureDefinition;
00225 String tableName = is->GetFilePathFeatureData
00226 (fdef, dirId, false, -1, true, false);
00227 if(mFeatureTables.size() != 0)
00228 {
00229 for(int i = 0; i < mFeatureTables.size(); i++)
00230 {
00231 Feature::FeatureDefinition tempDef(fdef.AsString());
00232 if(i != 0)
00233 tempDef.AddParameter("sub", MakeString(i));
00234 String tempTableName = is->GetFilePathFeatureData
00235 (tempDef, dirId, false, -1, true, false);
00236 mFeatureTables[i]->SetInfo(mTableInfoString);
00237 Write(mFeatureTables[i], tempTableName, is->GetDatabase(), true);
00238
00239
00240 delete mFeatureTables[i];
00241 mFeatureTables[i] = 0;
00242 }
00243 mFeatureTables.clear();
00244 }
00245
00246
00247 if(!mNoZIP)
00248 {
00249 String featureName = mInterestPointFeature.GetFeatureName();
00250 String fName = PathJoin(GetTmpPath(), "tmp-" + featureName +
00251 "-" + MakeString(dirId) + ".zip");
00252 String txtName = StringReplace(fName, ".zip", ".txt");
00253 String serverName = is->GetFilePathFeatureData
00254 (featureName + ".zip", dirId, false, -1, true, false);
00255 if (fName == String(""))
00256 {
00257 ILOG_ERROR("Empty file name");
00258 }
00259 serverName = StringReplace(serverName, ".zip.tab", ".tab.zip");
00260
00261
00262 std::ofstream fs(txtName.c_str());
00263 for(std::vector<String>::iterator iter = mTempFilenames.begin();
00264 iter != mTempFilenames.end(); iter++)
00265 {
00266 fs << (*iter) << std::endl;
00267 }
00268 fs.close();
00269
00270 String cmd = "zip ";
00271 cmd += fName;
00272 cmd += " -@ <";
00273 cmd += txtName;
00274
00275 if (serverName != String(""))
00276 {
00277
00278
00279 system(cmd.c_str());
00280 }
00281
00282
00283 if(std::remove(txtName.c_str()) != 0) {
00284 ILOG_WARN("Could not cleanup intermediate file: " << txtName);
00285 }
00286
00287
00288 Util::IOBuffer* zip = new Util::IOBufferFile(fName, true, false);
00289 Util::Database* database = is->GetDatabase();
00290 Util::IOBuffer* destination = database->GetIOBuffer
00291 (serverName, false, false, "tmp", 0, true);
00292 static const int bufSize = 1024 * 1024;
00293 static unsigned char buffer[bufSize];
00294 while(true)
00295 {
00296 int bytesread = zip->Read(buffer, bufSize);
00297 if(bytesread == 0)
00298 break;
00299 destination->Write(buffer, bytesread);
00300 }
00301 delete zip;
00302 delete destination;
00303
00304
00305
00306 if(std::remove(fName.c_str()) != 0) {
00307 ILOG_WARN("Could not cleanup temporary ZIP file: " << fName);
00308 }
00309 }
00310
00311
00312 if(mInterestPointFeature.mClusterInput &&
00313 mInterestPointFeature.mClusterInputData)
00314 {
00315 String tableName = is->GetFilePathFeatureData
00316 (mInterestPointFeature.mClusterInputData->GetFeatureDefinition(),
00317 dirId, false, -1, true, false);
00318 Write(mInterestPointFeature.mClusterInputData, tableName,
00319 is->GetDatabase(), true);
00320 delete mInterestPointFeature.mClusterInputData;
00321 mInterestPointFeature.mClusterInputData = 0;
00322 }
00323
00324
00325 for(std::vector<String>::iterator iter = mTempFilenames.begin();
00326 iter != mTempFilenames.end(); iter++)
00327 {
00328 if(std::remove((*iter).c_str()) != 0)
00329 {
00330 ILOG_WARN("Could not cleanup intermediate file: " << (*iter));
00331 }
00332 }
00333 mTempFilenames.clear();
00334 ILOG_INFO("HandleDoneDir: " << dirId);
00335 }
00336
00337
00338 private:
00339
00340 Reporter* mReporter;
00341 std::vector<Feature::FeatureTable*> mFeatureTables;
00342 Feature::InterestPointFeature mInterestPointFeature;
00343 CmdOptions& mOptions;
00344 String mCodebookSet;
00345 std::vector<String> mTempFilenames;
00346 bool mNoZIP;
00347 bool mSkipThisFolder;
00348 String mTableInfoString;
00349 String mWalkType;
00350
00351 ILOG_VAR_DEC;
00352
00353 };
00354
00355 ILOG_VAR_INIT(InterestPointProc, Impala.Core.ImageSet);
00356
00357 }
00358 }
00359 }
00360
00361 #endif