/** * @file CachedExample.h * @brief data caching of several feature images and many more * @author Erik Rodner, Sven Sickert * @date 04/21/2008 (modified 03/18/2016) */ #ifndef CACHEDEXAMPLEINCLUDE #define CACHEDEXAMPLEINCLUDE #include #include #include "core/vector/SparseVectorT.h" #include "core/image/MultiChannelImageT.h" #include "core/image/MultiChannelImage3DT.h" #include "core/basics/FileMgt.h" namespace OBJREC { /** data caching of several feature images and many more, can be used in conjunction with Example to share image data between different sliding windows within an image @see Example */ class CachedExample { protected: /** resize image to this fixed width */ int newWidth; /** resize image to this fixed height */ int newHeight; /** resize image to this fixed depth */ int newDepth; /** original image width */ int oxsize; /** original image height */ int oysize; /** original image depth */ int ozsize; /** list of filenames of images */ std::vector imgfn; /** array of double images */ // NICE::MultiChannelImageT *dchannels; NICE::MultiChannelImage3DT *dchannels; /** array of integer images */ // NICE::MultiChannelImageT *ichannels; NICE::MultiChannelImage3DT *ichannels; /** array of histogram images */ // NICE::MultiChannelImageT *lchannels; NICE::MultiChannelImage3DT *lchannels; /** maps for temporary files */ std::map dtemps; std::map itemps; std::map ltemps; /** read standard image data from file */ void readImageData (); /** read rgb image data from file */ void readImageDataRGB (); /** calc grayvalue integral image */ void calcIntegralImage (); /** array of histogram images */ NICE::SparseVector **svmap; /** sizes of histogram images */ int *svmap_xsize; int *svmap_ysize; bool hasColorInformation; public: /** whether one can obtain color information */ bool colorInformationAvailable() const; enum { L_INTEGRALIMAGE = 0, L_NUMCHANNELS }; /** integer channel types */ enum { I_GRAYVALUES = 0, I_COLOR, I_EDGES, I_NUMCHANNELS }; /** double value channels */ enum { D_EOH = 0, D_INTEGRALPRIOR, D_INTEGRALEOH, D_INTEGRALCOLOR, D_NUMCHANNELS }; /** sparse histogram channel types */ enum { SVTEXTON = 0, SVNUMCHANNELS }; /** default init method */ void init (); /** simple constructor @param imgfn image filename @param newWidth resize raw image to this width @param newHeight resize raw image to this height */ CachedExample ( const std::string & imgfn, int newWidth = -1, int newHeight = -1 ); /** simple 3d constructor @param imgfn image filename @param newWidth resize raw image to this width @param newHeight resize raw image to this height @param newDepth resize raw image to this depth */ CachedExample ( const std::vector & imgfn, int newWidth = -1, int newHeight = -1, int newDepth = -1 ); /** constructor (disabled buffering) @param img gray-value image */ CachedExample ( const NICE::Image & img ); /** constructor (disabled buffering) @param img gray-value multi channel image */ CachedExample ( const NICE::MultiChannelImageT & img ); /** constructor (disabled buffering) @param img rgb image @param disableGrayConversion whether to provide gray values or not */ CachedExample ( const NICE::ColorImage & img, bool disableGrayConversion = false ); /** constructor (disabled buffering) @param img multi channel image 3D @param disableGrayConversion whether to provide gray values or not */ CachedExample ( const NICE::MultiChannelImage3DT & img, bool disableGrayConversion = false ); /** simple destructor */ virtual ~CachedExample(); /** * get the NICE::Image Filename * @return NICE::Image Filename */ inline std::string getFilename(const int z = 0); /** * @brief get amount of images * @return amount of images */ inline int getNumImages (); /** get double image channel @param channel channel type (choose from enum type) @return buffer to image data */ // inline NICE::MultiChannelImageT & getDChannel ( int channel ); /** get double image channel 3d @param channel channel type (choose from enum type) @return buffer to image data */ inline NICE::MultiChannelImage3DT & getDChannel ( int channel ); /** get integer image channel @param channel channel type (choose from enum type) @param[out] xsize width of image @param[out] ysize height of image @return buffer to image data */ // inline NICE::MultiChannelImageT & getIChannel ( int channel ); /** get integer image channel 3d @param channel channel type (choose from enum type) @return buffer to image data */ inline NICE::MultiChannelImage3DT & getIChannel ( int channel ); /** get long image channel @param channel channel type (choose from enum type) @param[out] xsize width of image @param[out] ysize height of image @return buffer to image data */ // inline NICE::MultiChannelImageT & getLChannel ( int channel ); /** get long image channel 3d @param channel channel type (choose from enum type) @return buffer to image data */ inline NICE::MultiChannelImage3DT & getLChannel ( int channel ); /** get histogram image @param svchannel channel type (choose from histogram channel enum) @param[out] xsize width of raw image @param[out] ysize height of raw image @param[out] tm_xsize width of histogram channel buffer @param[out] tm_ysize height of histogram channel buffer @remark buffer will be not copied !! @return pointer to histogram channel buffer */ NICE::SparseVector *getSVMap ( int svchannel, int & xsize, int & ysize, int & tm_xsize, int & tm_ysize ) const; /** assign histogram channel buffer and compute integral image @param svchannel @param _map pointer to histogram channel buffer @param xsize_s width of histogram channel buffer @param ysize_s height of histogram channel buffer @remark buffer will be not copied !! */ void buildIntegralSV ( int svchannel, NICE::SparseVector *_map, int xsize_s, int ysize_s ); /** assign histogram channel buffer @param svchannel @param _map pointer to histogram channel buffer @param xsize_s width of histogram channel buffer @param ysize_s height of histogram channel buffer @remark buffer will be not copied !! */ void setSVMap ( int svchannel, NICE::SparseVector *_map, int xsize_s, int ysize_s ); /** get image sizes */ void getImageSize ( int & xsize, int & ysize ) const { xsize = oxsize; ysize = oysize; } /** get image sizes 3d */ void getImageSize3 ( int & xsize, int & ysize, int & zsize ) const { xsize = oxsize; ysize = oysize; zsize = ozsize; } /** drop precached data: (1) this is only possible if an image filename is given (2) only data channels are deleted that can be reproduced by CachedExample itself */ void dropPreCached(); template void dropImages ( NICE::MultiChannelImage3DT *images, std::map & temps, int numImages ); }; /********************** INLINE FUNCTIONS *****************************/ inline std::string CachedExample::getFilename( const int z ) { return imgfn[z]; } inline int CachedExample::getNumImages () { return imgfn.size(); } /* inline NICE::MultiChannelImageT & CachedExample::getDChannel ( int channel ) { assert ( ( channel >= 0 ) && ( channel < D_NUMCHANNELS ) ); if ( dchannels[channel].channels() == 0 ) { std::map::const_iterator j = dtemps.find ( channel ); if ( j == dtemps.end() ) { //fprintf (stderr, "NICE::MultiChannelImageT: unable to recover data channel %s (double %d)!\n", // imgfn.c_str(), channel); } else { //fprintf (stderr, "NICE::MultiChannelImageT: restoring data from %s ", j->second.c_str() ); dchannels[channel].restore ( j->second ); //fprintf (stderr, "(%d x %d)\n", dchannels[channel].xsize, dchannels[channel].ysize ); } } return dchannels[channel]; } */ inline NICE::MultiChannelImage3DT & CachedExample::getDChannel ( int channel ) { assert ( ( channel >= 0 ) && ( channel < D_NUMCHANNELS ) ); if ( dchannels[channel].channels() == 0 ) { std::map::const_iterator j = dtemps.find ( channel ); if ( j == dtemps.end() ) { //fprintf (stderr, "NICE::MultiChannelImageT: unable to recover data channel %s (double %d)!\n", //imgfn[0].c_str(), channel); } else { //fprintf (stderr, "NICE::MultiChannelImageT: restoring data from %s ", j->second.c_str() ); dchannels[channel].restore ( j->second ); //fprintf (stderr, "(%d x %d)\n", dchannels[channel].xsize, dchannels[channel].ysize ); } } return dchannels[channel]; } /* inline NICE::MultiChannelImageT & CachedExample::getIChannel ( int channel ) { assert ( ( channel >= 0 ) && ( channel < I_NUMCHANNELS ) ); if ( ( ichannels[channel].channels() == 0 ) ) { if ( ( imgfn[0] != "" ) && ( channel == I_GRAYVALUES ) ) { readImageData(); } else if ( ( imgfn[0] != "" ) && ( channel == I_COLOR ) ) { readImageDataRGB(); assert ( hasColorInformation ); } else { std::map::const_iterator j = itemps.find ( channel ); if ( j == itemps.end() ) { //fprintf (stderr, "NICE::MultiChannelImageT: unable to recover data channel (int %d)!\n", channel); //exit(-1); } else { //fprintf (stderr, "NICE::MultiChannelImageT: restoring data from %s\n", j->second.c_str() ); ichannels[channel].restore ( j->second ); } } } return ichannels[channel]; } */ inline NICE::MultiChannelImage3DT & CachedExample::getIChannel ( int channel ) { assert ( ( channel >= 0 ) && ( channel < I_NUMCHANNELS ) ); if ( ( ichannels[channel].channels() == 0 ) ) { if ( ( imgfn[0] != "" ) && ( channel == I_GRAYVALUES ) ) { readImageData(); } else if ( ( imgfn[0] != "" ) && ( channel == I_COLOR ) ) { readImageDataRGB(); assert ( hasColorInformation ); } else { std::map::const_iterator j = itemps.find ( channel ); if ( j == itemps.end() ) { //fprintf (stderr, "NICE::MultiChannelImageT: unable to recover data channel (int %d)!\n", channel); //exit(-1); } else { //fprintf (stderr, "NICE::MultiChannelImageT: restoring data from %s\n", j->second.c_str() ); ichannels[channel].restore ( j->second ); } } } return ichannels[channel]; } /* inline NICE::MultiChannelImageT & CachedExample::getLChannel ( int channel ) { assert ( ( channel >= 0 ) && ( channel < L_NUMCHANNELS ) ); if ( lchannels[channel].channels() == 0 ) { std::map::const_iterator j = ltemps.find ( channel ); if ( j == ltemps.end() ) { if ( channel == L_INTEGRALIMAGE ) { calcIntegralImage(); } else { //fprintf (stderr, "NICE::MultiChannelImageT: unable to recover data channel (long %d)!\n", channel); //exit(-1); } } else { //fprintf (stderr, "NICE::MultiChannelImageT: restoring data from %s\n", j->second.c_str() ); lchannels[channel].restore ( j->second ); } } return lchannels[channel]; } */ inline NICE::MultiChannelImage3DT & CachedExample::getLChannel ( int channel ) { assert ( ( channel >= 0 ) && ( channel < L_NUMCHANNELS ) ); if ( lchannels[channel].channels() == 0 ) { std::map::const_iterator j = ltemps.find ( channel ); if ( j == ltemps.end() ) { if ( channel == L_INTEGRALIMAGE ) { calcIntegralImage(); } else { //fprintf (stderr, "NICE::MultiChannelImageT: unable to recover data channel (long %d)!\n", channel); //exit(-1); } } else { //fprintf (stderr, "NICE::MultiChannelImageT: restoring data from %s\n", j->second.c_str() ); lchannels[channel].restore ( j->second ); } } return lchannels[channel]; } template void CachedExample::dropImages ( NICE::MultiChannelImage3DT *images, std::map & temps, int numImages ) { for ( int i = 0 ; i < numImages; i++ ) { std::map::iterator j = temps.find ( i ); if ( j == temps.end() ) { std::string tempfilename = NICE::FileMgt::createTempFile ( "tmp/cachedexample_%s" ); //fprintf (stderr, "CachedExample: dumping channel %d/%d to %s (%d x %d)\n", i, numImages, tempfilename.c_str(), // images[i].xsize, images[i].ysize ); images[i].store ( tempfilename ); temps[i] = tempfilename; } images[i].freeData(); } } } // namespace #endif