00001 #ifndef Impala_Core_VideoSet_HistogramExtractor_h
00002 #define Impala_Core_VideoSet_HistogramExtractor_h
00003
00004 #include "Core/VideoSet/Reporter.h"
00005 #include "Core/Vector/VectorTem.h"
00006 #include "Core/Feature/FeatureTable.h"
00007
00008 namespace Impala
00009 {
00010 namespace Core
00011 {
00012 namespace VideoSet
00013 {
00014
00015 class HistogramExtractor : public Listener
00016 {
00017
00018 protected:
00019
00020 typedef Vector::VectorTem<Real64> VectorReal64;
00021
00022 public:
00023
00024 HistogramExtractor(Reporter* reporter,
00025 CmdOptions& options, CString featureName, int binCount)
00026 {
00027 mReporter = reporter;
00028 mFeatureName = featureName;
00029 mBinCount = binCount;
00030 Feature::FeatureDefinition def(GetFeatureName());
00031 mHistogramTable = new Feature::FeatureTable(def, 1000, GetBinCount());
00032 }
00033
00034 virtual
00035 ~HistogramExtractor()
00036 {
00037 }
00038
00039 String
00040 GetFeatureName() const
00041 {
00042 return mFeatureName;
00043 }
00044
00045 virtual void
00046 HandleNewFrame(VideoSet* vs, int fileId, Stream::RgbDataSrc* src)
00047 {
00048 if (!src)
00049 {
00050 ILOG_ERROR("Not a valid source for fileId " << fileId);
00051 return;
00052 }
00053
00054 Array::Array2dVec3UInt8* im = Array::ArrayCreate<Array::Array2dVec3UInt8>
00055 (src->FrameWidth(), src->FrameHeight(), 0, 0, src->DataPtr(), true);
00056 if (!im)
00057 {
00058 ILOG_ERROR("Couldn't load image for fileId " << fileId);
00059 return;
00060 }
00061
00062 Quid quid = vs->GetQuidFrame(fileId, src->FrameNr());
00063
00064 VectorReal64 histogram = ComputeHistogram(im);
00065
00066 mHistogramTable->Add(quid, histogram);
00067
00068 delete im;
00069 }
00070
00071 virtual void
00072 HandleDoneFile(VideoSet* vs, int fileId, Stream::RgbDataSrc* src)
00073 {
00074 bool binary = true;
00075 Feature::FeatureDefinition def = mHistogramTable->GetFeatureDefinition();
00076 String fName = vs->GetFilePathFeatureData("Keyframes", def, fileId,
00077 false, -1, true, false);
00078 if (!fName.empty())
00079 Table::Write(mHistogramTable, fName, vs->GetDatabase(), binary);
00080 mHistogramTable->SetSize(0);
00081 }
00082
00083 protected:
00084
00085 int
00086 GetBinCount() const
00087 {
00088 return mBinCount;
00089 }
00090
00091 virtual VectorReal64
00092 ComputeHistogram(Array::Array2dVec3UInt8* image) = 0;
00093
00094 template <class T>
00095 int
00096 ComputeBin(const T val, const T low, const T high, const int nrBins) const
00097 {
00098 const int bin = (nrBins * (val - low)) / (high - low);
00099 if (bin >= 0 && bin < nrBins)
00100 return bin;
00101
00102 if (val == high)
00103 return nrBins - 1;
00104
00105 ILOG_WARN("Unexpected value: " << val <<
00106 " is not in range [" << low << ", " << high << "]");
00107 return (bin < 0) ? 0 : nrBins-1;
00108 }
00109
00110 private:
00111
00112 Reporter* mReporter;
00113 String mFeatureName;
00114 int mBinCount;
00115 Feature::FeatureTable* mHistogramTable;
00116
00117 ILOG_VAR_DECL;
00118 };
00119
00120 ILOG_VAR_INIT(HistogramExtractor, Impala.Core.VideoSet);
00121
00122 }
00123 }
00124 }
00125
00126 #endif