Home || Architecture || Video Search || Visual Search || Scripts || Applications || Important Messages || OGL || Src

InterestPointProc.h

Go to the documentation of this file.
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         // Make the feature data folder
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             // only support skipping if override is off
00089             if(!mNoZIP) 
00090             {
00091                 // does the ZIP exist already?
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                     // clusterInput mode
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                     // does the featuretable exist already?
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         // get frame and friendly frame name
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         // verify image is not null
00142         if (!im) {
00143             ILOG_ERROR("No image: fileId=" << fileId << "; imName=" << imName);
00144             return;
00145         }
00146 
00147         // create temporary output filename
00148         String outputFilename = PathJoin(GetTmpPath(), imName + "." + mInterestPointFeature.GetFeatureName());
00149 
00150         // clean up the filename: remove .jpg and ./ paths
00151         outputFilename = StringReplace(outputFilename, ".jpg", "");
00152         outputFilename = StringReplace(outputFilename, "/./", "/");
00153         outputFilename = StringReplace(outputFilename, "/./", "/");
00154         ILOG_DEBUG("fileId=" << fileId << "; imName=" << imName << "; outputFilename=" << outputFilename);
00155         
00156         // compute feature
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             // we have a projected feature vector
00170             if(mFeatureTables.size() < mInterestPointFeature.mLastCodebookVectors.size()) {
00171                 // first valid vector: allocate the table
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         // post-processing functionality
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         // Feature table logic
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         // ZIP-file logic
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             // put it all in fName
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             //TODO: call toZip.py here? Instead of Shell scripting?
00240             if (fName != String("")) {
00241                 // without override, fName will be empty if zip file already exists, so we cannot ZIP!
00242                 system(cmd.c_str());
00243             }
00244             
00245             // cleanup
00246             if(std::remove(txtName.c_str()) != 0) {
00247                 ILOG_WARN("Could not cleanup intermediate file: " << txtName);
00248             }
00249             
00250             // copy ZIP file to its final destination
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;      // this will force a write through a channel, if needed
00264 
00265             // cleanup
00266             if(std::remove(fName.c_str()) != 0) {
00267                 ILOG_WARN("Could not cleanup temporary ZIP file: " << fName);
00268             }
00269         }
00270 
00271         // clusterInput mode
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         // cleanup
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 } // namespace VideoSet
00311 } // namespace Core
00312 } // namespace Impala
00313 
00314 #endif

Generated on Fri Mar 19 09:31:13 2010 for ImpalaSrc by  doxygen 1.5.1