00001 #ifndef Impala_Core_VideoSet_InterestPointProc_h
00002 #define Impala_Core_VideoSet_InterestPointProc_h
00003
00004 #include "Core/VideoSet/Reporter.h"
00005 #include "Core/VideoSet/Keyframes.h"
00006 #include "Core/Array/MakeFromValue.h"
00007 #include "Core/Array/ArrayListDelete.h"
00008 #include "Core/Array/WriteRaw.h"
00009 #include "Persistency/FeatureTableRepository.h"
00010 #include "Core/Feature/InterestPointFeature.h"
00011
00012 namespace Impala
00013 {
00014 namespace Core
00015 {
00016 namespace VideoSet
00017 {
00018
00019 class InterestPointProc : public Listener
00020 {
00021 public:
00022
00023 typedef Persistency::FeatureLocator FeatureLocator;
00024 typedef Persistency::FeatureTableRepository FeatureTableRepository;
00025 typedef Persistency::FileLocator FileLocator;
00026 typedef Persistency::File File;
00027
00028 InterestPointProc(Reporter* reporter, CmdOptions& options)
00029 : mInterestPointFeature(options), mOptions(options), mNoZIP(false),
00030 mSkipThisVideo(false)
00031 {
00032 mNoZIP = options.GetBool("noZIP");
00033 mCodebookSet = "";
00034 mFeatureTableResult.SetInfo("codebook=" + options.GetString("codebook"));
00035 mInterestPointFeature.SetResultOutput(&mFeatureTableResult);
00036 if (options.GetNrArg() > 2)
00037 mCodebookSet = options.GetArg(2);
00038 if (mNoZIP)
00039 {
00040 ILOG_INFO("NOT creating ZIP output files");
00041 }
00042 else
00043 {
00044 ILOG_INFO("Creating ZIP output files");
00045 }
00046 }
00047
00048 static void
00049 AddCmdOptions()
00050 {
00051 Feature::InterestPointFeature::AddCmdOptions();
00052
00053 CmdOptions& options = CmdOptions::GetInstance();
00054 options.AddOption(0, "noZIP", "", "0");
00055 options.AddOption(0, "interestPointPostProcess", "command", "");
00056 }
00057
00058 virtual void
00059 HandleNewWalk(VideoSet* vs)
00060 {
00061 if (!mOptions.GetString("codebook").empty())
00062 {
00063 Database::RawDataSet* bookSet = vs;
00064 if (!mCodebookSet.empty())
00065 {
00066 ILOG_INFO("Using separate codebook set: " << mCodebookSet);
00067 bookSet = Database::MakeRawDataSet(mCodebookSet);
00068 }
00069
00070 mInterestPointFeature.SetCodebook(mOptions.GetString("codebook"),
00071 bookSet->GetLocator());
00072 mFeatureTableResult.SetFeatureDefinition(
00073 mInterestPointFeature.GetFeatureDefinition());
00074 }
00075 }
00076
00077 virtual void
00078 HandleNewWalk(VideoSet* vs, String walkType)
00079 {
00080 mWalkType = walkType;
00081 }
00082
00083 virtual void
00084 HandleNewFile(VideoSet* vs, int fileId, Stream::RgbDataSrc* src)
00085 {
00086 ILOG_INFO("HandleNewFile: " << fileId);
00087 mTempFilenames.clear();
00088 mSkipThisVideo = false;
00089 if (CmdOptions::GetInstance().GetBool("override"))
00090 return;
00091
00092 if (!mNoZIP)
00093 {
00094
00095 FeatureLocator loc(vs->GetLocator(), false, false, mWalkType,
00096 mInterestPointFeature.GetFeatureName(),
00097 vs->GetContainer(fileId));
00098 loc.ExtendSuffix(".zip");
00099 if (FeatureTableRepository().Exists(loc))
00100 {
00101 mSkipThisVideo = true;
00102 ILOG_INFO("Skipping video " << fileId <<
00103 "; ZIP file already exists");
00104 }
00105 return;
00106 }
00107
00108 if (mInterestPointFeature.mClusterInput)
00109 {
00110
00111 Feature::FeatureDefinition def = mInterestPointFeature.GetFeatureName();
00112 def.AddParameter("clusterinput", "2");
00113 FeatureLocator loc(vs->GetLocator(), false, false, mWalkType,
00114 def.AsString(), vs->GetContainer(fileId));
00115 if (FeatureTableRepository().Exists(loc))
00116 {
00117 mSkipThisVideo = true;
00118 ILOG_INFO("Skipping folder " << fileId <<
00119 "; FeatureData:ClusterInput file already exists");
00120 }
00121 }
00122 else
00123 {
00124
00125 String f = mInterestPointFeature.GetFeatureDefinition().AsString();
00126 FeatureLocator loc(vs->GetLocator(), false, false, mWalkType, f,
00127 vs->GetContainer(fileId));
00128 if (FeatureTableRepository().Exists(loc))
00129 {
00130 mSkipThisVideo = true;
00131 ILOG_INFO("Skipping video " << fileId <<
00132 "; FeatureData file already exists");
00133 }
00134 }
00135 }
00136
00137 virtual void
00138 HandleNewFrame(VideoSet* vs, int fileId, Stream::RgbDataSrc* src)
00139 {
00140 if (mSkipThisVideo)
00141 return;
00142
00143 Array::Array2dVec3UInt8* im = Array::ArrayCreate<Array::Array2dVec3UInt8>
00144 (src->FrameWidth(), src->FrameHeight(), 0, 0, src->DataPtr(), true);
00145 String videoName = src->GetName();
00146 String::size_type p = videoName.rfind("/");
00147 if (p != String::npos)
00148 videoName = videoName.substr(p+1, videoName.size());
00149
00150 String imName = FileNameCtor(videoName, "frame", src->FrameNr(), "");
00151 imName = StringReplaceAll(imName, ".", "_");
00152
00153
00154 if (!im)
00155 {
00156 ILOG_ERROR("No image: fileId=" << fileId << "; imName=" << imName);
00157 return;
00158 }
00159
00160
00161 String outputFilename = PathJoin(GetTmpPath(), imName + "." +
00162 mInterestPointFeature.GetFeatureName());
00163
00164
00165 outputFilename = StringReplace(outputFilename, ".jpg", "");
00166 outputFilename = StringReplace(outputFilename, "/./", "/");
00167 outputFilename = StringReplace(outputFilename, "/./", "/");
00168 ILOG_DEBUG("fileId=" << fileId << "; imName=" << imName <<
00169 "; outputFilename=" << outputFilename);
00170
00171
00172 if (mNoZIP)
00173 {
00174 outputFilename = "";
00175 }
00176 mInterestPointFeature.mClusterInputImage =
00177 QuidObj(vs->GetQuidFrame(fileId, src->FrameNr())).ToString();
00178
00179 if (!mInterestPointFeature.FindInterestPoints(mOptions, im,
00180 vs->GetQuidFrame(fileId, src->FrameNr()), outputFilename, true))
00181 {
00182 ILOG_ERROR("Extracting interest points/descriptors failed: " <<
00183 imName);
00184 }
00185
00186
00187 if (mOptions.GetString("interestPointPostProcess") != "")
00188 {
00189 String cmd = mOptions.GetString("interestPointPostProcess")
00190 + " " + outputFilename;
00191 ILOG_INFO("Post-processing = " << cmd);
00192 system(cmd.c_str());
00193 }
00194 if (!mNoZIP)
00195 {
00196 mTempFilenames.push_back(outputFilename);
00197 }
00198
00199 delete im;
00200 }
00201
00202 virtual void
00203 HandleDoneFile(VideoSet* vs, int fileId, Stream::RgbDataSrc* src)
00204 {
00205 if (mSkipThisVideo)
00206 return;
00207
00208 FeatureLocator loc(vs->GetLocator(), false, false, mWalkType, "empty",
00209 vs->GetContainer(fileId));
00210
00211 if (mFeatureTableResult.GetTableSize() != 0)
00212 {
00213 for(int i = 0; i < mFeatureTableResult.Size(); i++)
00214 {
00215 loc.SetFeatureDef(mFeatureTableResult.GetFeatureDefinition(i));
00216 FeatureTableRepository().Add(loc, mFeatureTableResult.GetTable(i));
00217 }
00218 mFeatureTableResult.Delete();
00219 }
00220
00221
00222 if (!mNoZIP)
00223 {
00224 String featureName = mInterestPointFeature.GetFeatureName();
00225 String fName = PathJoin(GetTmpPath(), "tmp-" + featureName +
00226 "-" + MakeString(fileId) + ".zip");
00227 String txtName = StringReplace(fName, ".zip", ".txt");
00228 loc.SetFeatureString(featureName + ".zip");
00229 String serverName = FeatureTableRepository().ExposeFilePath(loc,
00230 true);
00231 serverName = StringReplace(serverName, ".zip.tab", ".tab.zip");
00232
00233
00234 std::ofstream fs(txtName.c_str());
00235 for (std::vector<String>::iterator iter = mTempFilenames.begin();
00236 iter != mTempFilenames.end(); iter++)
00237 {
00238 fs << (*iter) << std::endl;
00239 }
00240 fs.close();
00241
00242 String cmd = "zip ";
00243 cmd += fName;
00244 cmd += " -@ <";
00245 cmd += txtName;
00246
00247 if (!serverName.empty())
00248 {
00249
00250
00251 system(cmd.c_str());
00252 }
00253
00254
00255 if (std::remove(txtName.c_str()) != 0)
00256 {
00257 ILOG_WARN("Could not cleanup intermediate file: " << txtName);
00258 }
00259
00260
00261 File srcFile = Persistency::RepositoryGetFile(fName, false, false);
00262 FileLocator dstLoc(vs->GetLocator(), serverName);
00263 File dstFile = Persistency::RepositoryGetFile(dstLoc, true, false);
00264 dstFile.CopyFrom(srcFile);
00265
00266
00267 if (std::remove(fName.c_str()) != 0)
00268 {
00269 ILOG_WARN("Could not cleanup temporary ZIP file: " << fName);
00270 }
00271 }
00272
00273
00274 if (mInterestPointFeature.mClusterInput &&
00275 mInterestPointFeature.mClusterInputData)
00276 {
00277 loc.SetFeatureDef(mInterestPointFeature.mClusterInputData->GetFeatureDefinition());
00278 FeatureTableRepository().Add(loc, mInterestPointFeature.mClusterInputData);
00279 delete mInterestPointFeature.mClusterInputData;
00280 mInterestPointFeature.mClusterInputData = 0;
00281 }
00282
00283
00284 for (std::vector<String>::iterator iter = mTempFilenames.begin();
00285 iter != mTempFilenames.end(); iter++)
00286 {
00287 if (std::remove((*iter).c_str()) != 0)
00288 {
00289 ILOG_WARN("Could not cleanup intermediate file: " << (*iter));
00290 }
00291 }
00292 mTempFilenames.clear();
00293 ILOG_INFO("HandleDoneFile: " << fileId);
00294 }
00295
00296 private:
00297
00298 Feature::FeatureTableResult mFeatureTableResult;
00299 Feature::InterestPointFeature mInterestPointFeature;
00300 CmdOptions& mOptions;
00301 String mCodebookSet;
00302 std::vector<String> mTempFilenames;
00303 bool mNoZIP;
00304 bool mSkipThisVideo;
00305 String mWalkType;
00306
00307 ILOG_VAR_DEC;
00308 };
00309
00310 ILOG_VAR_INIT(InterestPointProc, Core.VideoSet);
00311
00312 }
00313 }
00314 }
00315
00316 #endif