00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef Impala_Application_SDash_RegionsOfInterestInfo_h
00012 #define Impala_Application_SDash_RegionsOfInterestInfo_h
00013
00014 #include <string>
00015 #include <vector>
00016 #include <map>
00017
00018 #include "Util/IOBuffer.h"
00019 #include "Util/IOBufferFile.h"
00020
00021 #include "Core/Geometry/Rectangle.h"
00022
00023 #include "Application/sdash/RoiInfo.h"
00024
00025 namespace Impala {
00026 namespace Application {
00027 namespace SDash {
00028
00029 class RegionsOfInterestInfo {
00030
00031 public:
00032
00033 typedef Core::Geometry::Rectangle Rectangle;
00034
00035 struct ScaledRegion
00036 {
00037 float left, top, width, height;
00038 };
00039
00040 RegionsOfInterestInfo(
00041 std::string roiInfoFile,
00042 int nrOfVideosToCollectRoisFor,
00043 const int* const maxFrames,
00044 bool invertYaxis = false,
00045 bool makeSizesEven = false) :
00046 mNrOfVideos(nrOfVideosToCollectRoisFor),
00047 mFrameWidth(ROI_FRAME_WIDTH),
00048 mFrameHeight(ROI_FRAME_HEIGHT)
00049 {
00050 std::cout << "reading regions of interest info from " << roiInfoFile << std::endl;
00051
00052
00053
00054 for (int v = 0; v < mNrOfVideos; v++)
00055 {
00056 mRois.push_back(std::map< int, std::vector<Rectangle> >());
00057 mRoiCountPerVideo[v] = 0;
00058 }
00059
00060 const bool readOnly = true;
00061 const bool readIntoMem = false;
00062 Util::IOBufferFile ioBuffer(roiInfoFile, readOnly, readIntoMem);
00063 const int REC_SIZE = 6172;
00064
00065
00066
00067
00068
00069
00070
00071
00072 unsigned char byteBuffer[REC_SIZE];
00073 long position = 0;
00074 for (int i = 0; i < ROI_INFO_COUNT; i++)
00075 {
00076 const int bytesOfInterest = REC_SIZE;
00077 ioBuffer.SetPosition(position);
00078 int bytesRead = ioBuffer.Read(byteBuffer, bytesOfInterest);
00079 if (bytesRead < bytesOfInterest)
00080 throw std::logic_error("unable to read complete roi info record ");
00081
00082 int video = byteBuffer[2] * 256 + byteBuffer[3];
00083 int frame = byteBuffer[6] * 256 + byteBuffer[7] - 1;
00084
00085
00086 if (video < nrOfVideosToCollectRoisFor && frame <= maxFrames[video])
00087 {
00088 int top = byteBuffer[10] * 256 + byteBuffer[11];
00089 int left = byteBuffer[14] * 256 + byteBuffer[15];
00090 int bottom = byteBuffer[18] * 256 + byteBuffer[19];
00091 int right = byteBuffer[22] * 256 + byteBuffer[23];
00092 Rectangle region(left, top, right, bottom);
00093
00094 if (makeSizesEven)
00095 {
00096 int origWidth = region.Width();
00097 int origHeight= region.Height();
00098
00099 if (origWidth % 2 != 0)
00100 {
00101 region.mRight -= 1;
00102 region.mBottom = region.mTop + (2 * region.Width()) - 1;
00103 }
00104 else if (origHeight % 4 != 0)
00105 {
00106 region.mBottom -= origHeight % 4;
00107 region.mRight = region.mLeft + (region.Height() / 2) - 1;
00108 }
00109
00110
00111
00112 }
00113
00114 if (invertYaxis)
00115 {
00116 int topUpward = mFrameHeight - region.mBottom - 1;
00117 int bottomUpward = mFrameHeight - region.mTop - 1;
00118 region.mTop = topUpward;
00119 region.mBottom = bottomUpward;
00120 }
00121
00122 std::map<int, std::vector<Rectangle> >& roisInVideo = mRois[video];
00123 std::vector<Rectangle>& roisInFrame = roisInVideo[frame];
00124 roisInFrame.push_back(region);
00125 }
00126
00127 mRoiCountPerVideo[video] += 1;
00128 position += REC_SIZE;
00129 }
00130
00131 std::cout << "finished reading regions of interest info" << std::endl;
00132 }
00133
00134 ~RegionsOfInterestInfo()
00135 {
00136 }
00137
00138 int GetFrameWidth() const
00139 {
00140 return mFrameWidth;
00141 }
00142
00143 int GetFrameHeight() const
00144 {
00145 return mFrameHeight;
00146 }
00147
00148 int GetAbsRoiNr(int videoId, int frameNr, int roiNr) const
00149 {
00150 int absRoiNr = 0;
00151
00152 if (videoId >= mNrOfVideos)
00153 return -1;
00154
00155 for (int v = 0; v < videoId; v++)
00156 absRoiNr += ROIS_PER_VIDEO[v];
00157
00158
00159 const std::map<int, std::vector<Rectangle> >& roisForVideo = mRois[videoId];
00160
00161 std::map<int, std::vector<Rectangle> >::const_iterator frameIter = roisForVideo.begin();
00162 while (frameIter != roisForVideo.end())
00163 {
00164 if (frameIter->first < frameNr)
00165 absRoiNr += frameIter->second.size();
00166 else
00167 break;
00168 frameIter++;
00169 }
00170
00171 if (frameIter == roisForVideo.end() || frameIter->first > frameNr)
00172 return -1;
00173
00174 if (frameIter->second.size() < roiNr)
00175 return -1;
00176
00177
00178 absRoiNr += roiNr;
00179
00180 return absRoiNr;
00181 }
00182
00183
00184
00185
00186 RoiInfo GetRoiInfo(int absRoiNr) const
00187 {
00188 RoiInfo roiInfo;
00189
00190 int runningRoiNr = absRoiNr;
00191
00192
00193 for (int v = 0; v < mNrOfVideos; v++)
00194 {
00195 if (runningRoiNr < ROIS_PER_VIDEO[v])
00196 {
00197 roiInfo.videoId = v;
00198 break;
00199 }
00200 runningRoiNr -= ROIS_PER_VIDEO[v];
00201 }
00202
00203
00204 const std::map<int, std::vector<Rectangle> >& roisForVideo = mRois[roiInfo.videoId];
00205
00206 std::map<int, std::vector<Rectangle> >::const_iterator frameIter = roisForVideo.begin();
00207 while (frameIter != roisForVideo.end())
00208 {
00209 int frameRois = frameIter->second.size();
00210 if (runningRoiNr < frameRois)
00211 break;
00212 runningRoiNr -= frameRois;
00213 frameIter++;
00214 }
00215
00216 if (frameIter != roisForVideo.end() && runningRoiNr >= 0 && runningRoiNr < frameIter->second.size())
00217 {
00218 roiInfo.frameNr = frameIter->first;
00219 roiInfo.roiNr = runningRoiNr;
00220 }
00221 else
00222 {
00223 roiInfo.videoId = -1;
00224 roiInfo.frameNr = -1;
00225 roiInfo.roiNr = -1;
00226 }
00227
00228 return roiInfo;
00229 }
00230
00231 const std::vector<Rectangle>& GetRois(int video, int frame) const
00232 {
00233 if (video < mNrOfVideos)
00234 {
00235 const std::map<int, std::vector<Rectangle> >& roisForVideo = mRois[video];
00236 std::map<int, std::vector<Rectangle> >::const_iterator pos = roisForVideo.find(frame);
00237 if (pos == roisForVideo.end())
00238 return mEmptyList;
00239 else
00240 return pos->second;
00241 }
00242 else
00243 return mEmptyList;
00244 }
00245
00246 std::vector<ScaledRegion> GetRoisScaled(int video, int frame, float scale = 1.0f) const
00247 {
00248 std::vector<ScaledRegion> result;
00249 const std::vector<Rectangle>& frameRois = GetRois(video, frame);
00250 int nrOfRois = frameRois.size();
00251 for (int i = 0; i < nrOfRois; i++)
00252 {
00253 const Rectangle& roi = frameRois[i];
00254 ScaledRegion scaledRoi;
00255 scaledRoi.left = (float) roi.mLeft * scale;
00256 scaledRoi.top = (float) roi.mTop * scale;
00257 scaledRoi.width = (float) roi.Width() * scale;
00258 scaledRoi.height = (float) roi.Height() * scale;
00259 result.push_back(scaledRoi);
00260 }
00261 return result;
00262 }
00263
00264 private:
00265
00266 static const int ROI_FRAME_WIDTH;
00267 static const int ROI_FRAME_HEIGHT;
00268 static const int ROI_INFO_COUNT;
00269 static const int ROIS_PER_VIDEO[12];
00270
00271 int mNrOfVideos;
00272 int mFrameWidth;
00273 int mFrameHeight;
00274
00275 std::vector< std::map<int, std::vector<Rectangle> > > mRois;
00276 const std::vector<Rectangle> mEmptyList;
00277 std::map<int, int> mRoiCountPerVideo;
00278
00279 };
00280
00281 const int RegionsOfInterestInfo::ROI_FRAME_WIDTH = 696;
00282 const int RegionsOfInterestInfo::ROI_FRAME_HEIGHT = 576;
00283 const int RegionsOfInterestInfo::ROI_INFO_COUNT = 33494;
00284 const int RegionsOfInterestInfo::ROIS_PER_VIDEO[12] = {2472, 452, 3473, 2921, 653, 4147, 3328, 4542, 25, 4707, 3794, 2980};
00285
00286 }
00287 }
00288 }
00289
00290 #endif
00291