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

RegionsOfInterestInfo.h

Go to the documentation of this file.
00001 /******************************************************************************
00002  *
00003  * Application: An instance of this class may hold meta-information on regions 
00004  *              of interest for multiple frames of multiple video's.
00005  *              This implementation uses a description file as used by Thang
00006  *              Viet Pham on person detection.
00007  *
00008  * Primary author(s): Sander Kruseman
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         // create an empty map for every video;
00053         // silly impl; should add maps on the fly
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; // record size for detected person information
00064 
00065         // limitation of metadata to store:
00066         //static const float ESTIMATED_FPS = 2.6f; // SK: to be on the safe side
00067         //static const int ESTIMATED_FPM = (int) (ESTIMATED_FPS * 60.0f);
00068         //static const int MAX_FRAME_NR = MAX_MINUTES_OF_VIDEO * ESTIMATED_FPM;
00069         //int maxFrameNr = videoLengthSecs * ESTIMATED_FPM;
00070         //int maxFrameNr = videoLengthSecs * ESTIMATED_FPS;
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             //if (video < nrOfVideosToCollectRoisFor && frame <= MAX_FRAME_NR)
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                     //int newWidth = region.Width();
00111                     //int newHeight= region.Height();
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         // add roi counts for all lower frame nrs for specified video id
00159         const std::map<int, std::vector<Rectangle> >& roisForVideo = mRois[videoId];
00160         // note that the map is ordered by frame nr
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; // no frames for requested video, or no roi's for requested frame
00173 
00174         if (frameIter->second.size() < roiNr)
00175             return -1; // roi nr invalid for requested frame
00176 
00177         // add roi nr for the specified frame
00178         absRoiNr += roiNr;
00179 
00180         return absRoiNr;
00181     }
00182 
00183     // parameter should be based on valid result of call to 
00184     // GetAbsRoiNr(). This mainly follows from the implementation
00185     // using nr of video's to collect roi's for.
00186     RoiInfo GetRoiInfo(int absRoiNr) const
00187     {
00188         RoiInfo roiInfo; // data structure to return
00189 
00190         int runningRoiNr = absRoiNr;
00191 
00192         // determine roi nr relative to video:
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         // determine roi nr relative to frame:
00204         const std::map<int, std::vector<Rectangle> >& roisForVideo = mRois[roiInfo.videoId];
00205         // note that the map is ordered by frame nr
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; // total nr of defined roi's
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 }; //class RegionsOfInterestInfo
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; // total nr of defined roi's
00284 const int RegionsOfInterestInfo::ROIS_PER_VIDEO[12] = {2472, 452, 3473, 2921, 653, 4147, 3328, 4542, 25, 4707, 3794, 2980};
00285 
00286 } // namespace SDash
00287 } // namespace Application
00288 } // namespace Impala
00289 
00290 #endif
00291 

Generated on Fri Mar 19 09:30:38 2010 for ImpalaSrc by  doxygen 1.5.1