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