00001 #ifndef Impala_Core_VideoSet_Segmentation_h
00002 #define Impala_Core_VideoSet_Segmentation_h
00003
00004 #include "Core/Table/MakeGroupIndex.h"
00005 #include "Core/VideoSet/VideoSet.h"
00006 #include "Core/Table/TableTem.h"
00007 #include "Core/Table/Read.h"
00008 #include "Core/Table/Write.h"
00009 #include "Core/Column/Find.h"
00010 #include "Core/Column/Contains.h"
00011
00012 namespace Impala
00013 {
00014 namespace Core
00015 {
00016 namespace VideoSet
00017 {
00018
00019
00020 typedef Table::TableTem<Column::ColumnTem<Int32>,
00021 Column::ColumnTem<Int32>,
00022 Column::ColumnTem<Int32>,
00023 Column::ColumnTem<String> > SegmentationBaseType;
00024
00025
00026 class Segmentation : public SegmentationBaseType
00027 {
00028 typedef Impala::Core::Table::GroupIndex GroupIndex;
00029
00030 public:
00031
00032 Segmentation(VideoSet* vidSet, String name) : SegmentationBaseType(0)
00033 {
00034 mVidSet = vidSet;
00035 mName = name;
00036 mVideoGroups = 0;
00037 SetColName(1, "videoId");
00038 SetColName(2, "startFrame");
00039 SetColName(3, "endFrame");
00040 SetColName(4, "name");
00041 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00042 if (!mName.empty())
00043 Load();
00044 #else // REPOSITORY_USED
00045 if (!mName.empty())
00046 ILOG_ERROR("Load segmentation via repository");
00047 #endif // REPOSITORY_USED
00048 }
00049
00050
00051
00052 int
00053 GetNrShots()
00054 {
00055 return Size();
00056 }
00057
00058 int
00059 GetVideoId(int shotId)
00060 {
00061 return Get1(shotId);
00062 }
00063
00064 int
00065 GetStart(int shotId)
00066 {
00067 return Get2(shotId);
00068 }
00069
00070 int
00071 GetEnd(int shotId)
00072 {
00073 return Get3(shotId);
00074 }
00075
00076 String
00077 GetName(int shotId)
00078 {
00079 return Get4(shotId);
00080 }
00081
00082 Quid
00083 GetQuidShot(int shotId)
00084 {
00085 int vidId = GetVideoId(shotId);
00086 return MakeQuidShot(mVidSet->GetSetId(), vidId,
00087 shotId - GetFirstShotVideo(vidId));
00088 }
00089
00090 Quid
00091 GetQuidShot(int videoId, int frameNr)
00092 {
00093 int shotId = GetShotId(videoId, frameNr);
00094 if (shotId == Size())
00095 return 0;
00096 if (shotId == -1)
00097 return 0;
00098 return GetQuidShot(shotId);
00099 }
00100
00101 int
00102 GetShotId(String name)
00103 {
00104 int rank = Find(GetColumn4(), name, 0, Size());
00105 if (rank == Size())
00106 return -1;
00107 return rank;
00108 }
00109
00110 int
00111 GetShotId(int videoId, int frameNr)
00112 {
00113 int first = GetFirstShotVideo(videoId);
00114 int number = GetNrShotsVideo(videoId);
00115 for (int s=first ; s<first+number ; s++)
00116 if ((frameNr >= GetStart(s)) && (frameNr <= GetEnd(s)))
00117 return s;
00118 return -1;
00119 }
00120
00121 int
00122 GetShotId(Quid quid)
00123 {
00124 if (QuidClass(quid) == QUID_CLASS_SHOT)
00125 {
00126 int vidId = QuidObject(quid);
00127 int shot = QuidId(quid);
00128 return GetFirstShotVideo(vidId) + shot;
00129 }
00130 if (QuidClass(quid) == QUID_CLASS_FRAME)
00131 {
00132 int vidId = QuidObject(quid);
00133 int frame = QuidId(quid);
00134 return GetShotId(vidId, frame);
00135 }
00136 ILOG_ERROR("GetShotId: Unknown quid : " << QuidObj(quid));
00137 return -1;
00138 }
00139
00140 std::vector<int>
00141 GetShotIds(int videoId, int startFrame, int endFrame, int minimalOverlap)
00142 {
00143 std::vector<int> res;
00144 int first = GetShotId(videoId, startFrame);
00145 int last = GetShotId(videoId, endFrame);
00146 if ((first == Size()) || (last == Size()))
00147 return res;
00148
00149 if (first == last)
00150 {
00151 if (endFrame - startFrame + 1 > minimalOverlap)
00152 res.push_back(first);
00153 return res;
00154 }
00155
00156 if (GetEnd(first) - startFrame + 1 > minimalOverlap)
00157 res.push_back(first);
00158 if (last - first > 1)
00159 {
00160 for (int s=first+1 ; s<last ; s++)
00161 res.push_back(s);
00162 }
00163 if (endFrame - GetStart(last) + 1 > minimalOverlap)
00164 res.push_back(last);
00165 return res;
00166 }
00167
00168 VideoSet*
00169 GetVideoSet()
00170 {
00171 return mVidSet;
00172 }
00173
00174
00175
00176 void
00177 UpdateGroups()
00178 {
00179 if (mVideoGroups == 0)
00180 mVideoGroups = new GroupIndex(0);
00181 MakeGroupIndex(mVideoGroups, GetColumn1(), 0, Size());
00182 }
00183
00184 int
00185 GetNrVideos()
00186 {
00187 return mVideoGroups->Size();
00188 }
00189
00190 int
00191 GetFirstShotVideo(int videoId)
00192 {
00193 return mVideoGroups->Get1(videoId);
00194 }
00195
00196 int
00197 GetNrShotsVideo(int videoId)
00198 {
00199 return mVideoGroups->Get2(videoId);
00200 }
00201
00202
00203 int
00204 GetNrFramesVideo(int videoId)
00205 {
00206 int lastShot = GetFirstShotVideo(videoId) + GetNrShotsVideo(videoId) - 1;
00207 return GetEnd(lastShot) + 1;
00208 }
00209
00210
00211 int
00212 GetTotalNrFrames()
00213 {
00214 int res = 0;
00215 for (int i=0 ; i<GetNrVideos() ; i++)
00216 res += GetNrFramesVideo(i);
00217 return res;
00218 }
00219
00220
00221
00222 int
00223 Diff(Segmentation* arg)
00224 {
00225 if (GetNrShots() != arg->GetNrShots())
00226 {
00227 ILOG_ERROR("Diff: nrShots differs: " << GetNrShots() << " vs " <<
00228 arg->GetNrShots());
00229 return 1;
00230 }
00231 int nDiff = 0;
00232 for (int i=0 ; i<GetNrShots() ; i++)
00233 {
00234 if (GetVideoId(i) != arg->GetVideoId(i))
00235 {
00236 ILOG_DEBUG("Id " << i << " differs " << GetVideoId(i) <<
00237 " vs " << arg->GetVideoId(i));
00238 nDiff++;
00239 }
00240 else if (GetStart(i) != arg->GetStart(i))
00241 {
00242 ILOG_DEBUG("Start " << i << " differs " << GetStart(i) <<
00243 " vs " << arg->GetStart(i));
00244 nDiff++;
00245 }
00246 else if (GetEnd(i) != arg->GetEnd(i))
00247 {
00248 ILOG_DEBUG("End " << i << " differs " << GetEnd(i) <<
00249 " vs " << arg->GetEnd(i));
00250 nDiff++;
00251 }
00252 else if (GetName(i) != arg->GetName(i))
00253 {
00254 ILOG_DEBUG("Name " << i << " differs " << GetName(i) <<
00255 " vs " << arg->GetName(i));
00256 nDiff++;
00257 }
00258 }
00259 if (nDiff > 0)
00260 ILOG_ERROR("Found " << nDiff << " differences");
00261 return nDiff;
00262 }
00263
00264
00265
00266 #ifndef REPOSITORY_USED // Here comes the deprecated stuff
00267 void
00268 Load()
00269 {
00270 String fName = mVidSet->GetFilePathVideoIndex("", mName + ".tab",
00271 false, false);
00272 Read(this, fName, mVidSet->GetDatabase());
00273 UpdateGroups();
00274 }
00275
00276 void
00277 Save(String name, bool binary)
00278 {
00279 if (!name.empty())
00280 mName = name;
00281 String fName = mVidSet->GetFilePathVideoIndex("", mName + ".tab",
00282 true, false);
00283 Write(this, fName, mVidSet->GetDatabase(), binary);
00284 }
00285
00286 void
00287 Update(String name)
00288 {
00289 if (!name.empty())
00290 mName = name;
00291 String fName = mVidSet->GetFilePathVideoIndex("", mName + ".tab",
00292 true, true);
00293 if (fName.empty())
00294 fName = mVidSet->GetFilePathVideoIndex("", mName + ".tab",
00295 false, false);
00296 Write(this, fName, mVidSet->GetDatabase(), true);
00297 }
00298 #endif // REPOSITORY_USED
00299
00300 private:
00301
00302 VideoSet* mVidSet;
00303 String mName;
00304 GroupIndex* mVideoGroups;
00305
00306 ILOG_VAR_DEC;
00307
00308 };
00309
00310 ILOG_VAR_INIT(Segmentation, Impala.Core.VideoSet);
00311
00312 }
00313 }
00314 }
00315
00316 #endif