GSoC2011SfM  0.1
Google Summer of Code 2011: Structure from motion
D:/Travail/These/Determination caracteristiques camera/GSoC/SfM/src/MotionProcessor.cpp
00001 
00002 #include "macro.h" //SFM_EXPORTS
00003 
00004 #include <opencv2/core/core.hpp>
00005 #include <opencv2/imgproc/imgproc.hpp>
00006 #ifdef HAVE_BOOST
00007 #include <boost/filesystem.hpp>   // includes all needed Boost.Filesystem declarations
00008 #endif
00009 #include <sstream>
00010 
00011 #include "MotionProcessor.h"
00012 
00013 using cv::Mat;
00014 using cv::Size;
00015 using cv::Vec;
00016 using cv::Ptr;
00017 using cv::VideoCapture;
00018 using std::string;
00019 using cv::imread;
00020 using std::ostringstream;
00021 using std::vector;
00022 #ifdef HAVE_BOOST
00023 using boost::filesystem::path;
00024 #endif
00025 
00026 namespace cv{
00027   CVAPI( int ) cvHaveImageReader( const char* filename );
00028 }
00029 
00030 namespace OpencvSfM{
00031 
00032   MotionProcessor::MotionProcessor( void )
00033   {
00034     numFrame_=0;
00035     pos_in_loading_process_ = 0;
00036     wantedWidth_=-1;
00037     wantedHeight_=-1;
00038     convertToRGB_=-1;
00039   }
00040 
00041   MotionProcessor::~MotionProcessor( void )
00042   {
00043     switch( type_of_input_ )
00044     {
00045     case IS_WEBCAM:
00046     case IS_VIDEO:
00047       capture_.release( );
00048       break;
00049     case IS_DIRECTORY:
00050     case IS_LIST_FILES:
00051     case IS_SINGLE_FILE:
00052       nameOfFiles_.clear( );
00053       break;
00054     }
00055   }
00056 
00057   bool MotionProcessor::setInputSource( int idWebCam )
00058   {
00059     if( this->capture_.open( idWebCam ))
00060     {
00061       this->type_of_input_=IS_WEBCAM;
00062       //if we have some properties, set them to the webcam:
00063       this->capture_.set( CV_CAP_PROP_CONVERT_RGB,this->convertToRGB_>0 );
00064       if( wantedHeight_>0 )
00065         this->capture_.set( CV_CAP_PROP_FRAME_HEIGHT,this->wantedHeight_ );
00066       if( wantedWidth_>0 )
00067         this->capture_.set( CV_CAP_PROP_FRAME_WIDTH,this->wantedWidth_ );
00068       return true;
00069     };
00070     return false;
00071   };
00072 
00073   bool MotionProcessor::setInputSource( std::vector< std::string > list_images )
00074   {
00075     this->type_of_input_=IS_LIST_FILES;
00076     nameOfFiles_ = list_images;
00077     suffix_ = "Not a dynamic list";
00078     return true;
00079   };
00080 
00081   bool MotionProcessor::setInputSource( std::string nameOfFile,
00082     TypeOfMotionProcessor inputType/*=IS_VIDEO*/ )
00083   {//IS_DIRECTORY, IS_VIDEO or IS_SINGLE_FILE
00084     this->sourceName_=nameOfFile;
00085     this->type_of_input_=inputType;
00086 
00087     if( inputType == IS_VIDEO )
00088       return this->capture_.open( nameOfFile );
00089 
00090     if( inputType == IS_DIRECTORY )
00091     {
00092 #ifdef HAVE_BOOST
00093       path dirTmp( nameOfFile.c_str( ) );
00094       if ( !boost::filesystem::exists( dirTmp ) || !boost::filesystem::is_directory( dirTmp ) ) {
00095         return false;
00096       }
00097 
00098       boost::filesystem::directory_iterator iter= boost::filesystem::directory_iterator( dirTmp );
00099       while( iter != boost::filesystem::directory_iterator( ) )
00100       {
00101         string name_of_file = iter->path( ).string( );
00102         if( cv::cvHaveImageReader( (const char* )name_of_file.c_str( ) ) )
00103           nameOfFiles_.push_back( name_of_file );
00104         iter++;
00105       }
00106       //if we don't have loaded files, return an error!
00107       if( nameOfFiles_.empty( ) )
00108         return false;
00109 
00110       // sort, since directory iteration
00111       // is not ordered on some file systems
00112       std::sort( nameOfFiles_.begin( ), nameOfFiles_.end( ) );
00113 #else
00114       return false;
00115 #endif
00116     }
00117     return true;
00118   };
00119 
00120   bool MotionProcessor::setInputSource( std::string prefix, std::string suffix,
00121     int startNumber/*=0*/ )
00122   {
00123     this->sourceName_ = prefix;
00124     this->suffix_ = suffix;
00125     pos_in_loading_process_ = startNumber;
00126     this->type_of_input_ = IS_LIST_FILES;
00127     return true;
00128     //always true because the error will occur when user will try to get the frame, not now...
00129   };
00130 
00131   cv::Mat MotionProcessor::getFrame( )
00132   {
00133     Mat imgTmp;
00134 
00135     //Is the current cursor in the middle of the video?
00136     if( type_of_input_==IS_LIST_FILES && numFrame_<nameOfFiles_.size( ) )
00137     {
00138       //Someone as changed the position of cursor...
00139       //Reload the wanted file:
00140       imgTmp=imread( nameOfFiles_[ numFrame_ ],convertToRGB_ );
00141       this->numFrame_++;//and move to the next frame
00142     }
00143     else
00144     {
00145       switch( type_of_input_ )
00146       {
00147       case IS_WEBCAM:
00148       case IS_VIDEO:
00149         {
00150           //Get the current image from file:
00151           bool aNewFrameIsAvailable=capture_.grab( );
00152           if( aNewFrameIsAvailable )
00153           {
00154             capture_.retrieve( imgTmp );
00155           }
00156         }
00157         break;
00158       case IS_LIST_FILES:
00159         {
00160           ostringstream oss;
00161           oss<<this->sourceName_<<this->numFrame_<<this->suffix_;
00162 
00163           imgTmp=imread( oss.str( ).c_str( ),convertToRGB_ );
00164           this->numFrame_++;
00165 
00166           unsigned int stop=this->numFrame_+10;
00167           while( imgTmp.empty( )&&stop>this->numFrame_ ){
00168             oss.str( "" );
00169             oss<<this->sourceName_<<this->numFrame_<<this->suffix_;
00170             imgTmp=imread( oss.str( ).c_str( ),convertToRGB_ );
00171             this->numFrame_++;
00172           }
00173           if( ! imgTmp.empty( ) )
00174             nameOfFiles_.push_back( oss.str( ) );//add the new file
00175         }
00176         break;
00177       case IS_DIRECTORY:
00178         {
00179           if( numFrame_<nameOfFiles_.size( ) )
00180           {
00181             imgTmp=imread( nameOfFiles_[ numFrame_ ],convertToRGB_ );
00182             this->numFrame_++;//and move to the next frame
00183           }
00184         }
00185         break;
00186       case IS_SINGLE_FILE:
00187         {
00188           imgTmp=imread( this->sourceName_.c_str( ),convertToRGB_ );
00189         }
00190         break;
00191       }
00192     }
00193 
00194     if( !imgTmp.empty( ) )
00195     {
00196       //now we ensure the file as the good properties:
00197       //First the colors:
00198       if( (( (convertToRGB_>0) && imgTmp.channels( )<=1 ) ||
00199         ( (convertToRGB_==0) && imgTmp.channels( )!=1 )) )
00200       {
00201         Mat correctImg;
00202         if( convertToRGB_==0 )
00203           cvtColor( imgTmp,correctImg,CV_RGB2GRAY );
00204         else
00205           cvtColor( imgTmp,correctImg,CV_GRAY2RGB );
00206         imgTmp=correctImg;
00207       }
00208       //then the width and height:
00209       if( (( wantedHeight_>0 )&&( wantedHeight_!=imgTmp.rows ))||
00210         ( (wantedWidth_>0 )&&( wantedWidth_!=imgTmp.cols )) )
00211       {
00212         Mat correctImg;
00213         int widthTmp=wantedWidth_;
00214         if( wantedWidth_<=0 )
00215           widthTmp=imgTmp.cols;
00216         int heightTmp=wantedHeight_;
00217         if( wantedHeight_<=0 )
00218           heightTmp=imgTmp.cols;
00219         cv::resize( imgTmp,correctImg,Size( widthTmp,heightTmp ));
00220         imgTmp=correctImg;
00221       }
00222     }
00223 
00224     return imgTmp;
00225   }
00226 
00227   bool MotionProcessor::setProperty( int _idProp,double _value )
00228   {
00229     bool videoCaptureLikeThisProperty=true;
00230     if( type_of_input_==IS_WEBCAM||type_of_input_==IS_VIDEO )
00231       videoCaptureLikeThisProperty = capture_.set( _idProp,_value );
00232     if( ! videoCaptureLikeThisProperty )
00233       return false;//as the VideoCapture object don't want this property, don't do anything else.
00234 
00235     //First store the property using attributs:
00236     switch ( _idProp )
00237     {
00238     case CV_CAP_PROP_CONVERT_RGB://Boolean flags indicating whether images should be converted to RGB
00239       convertToRGB_ = ( int )_value;
00240       break;
00241     case CV_CAP_PROP_FRAME_HEIGHT://Height of the frames in the video stream
00242       wantedHeight_= ( int )_value;
00243       break;
00244     case CV_CAP_PROP_FRAME_WIDTH://Width of the frames in the video stream
00245       wantedWidth_= ( int )_value;
00246       break;
00247     case CV_CAP_PROP_POS_FRAMES:// 0-based index of the frame to be decoded/captured next
00248       {
00249         if( type_of_input_==IS_LIST_FILES||type_of_input_==IS_SINGLE_FILE )
00250         {
00251           if( _value>=0&&_value<=nameOfFiles_.size( ) )
00252             numFrame_=( unsigned int )_value;
00253           else
00254             CV_Error( CV_StsBadArg, "CV_CAP_PROP_POS_FRAMES: _value out of range!" );
00255         }
00256       };
00257       break;
00258     case CV_CAP_PROP_FORMAT://The format of the Mat objects returned by retrieve( )
00259     case CV_CAP_PROP_POS_MSEC://Film current position in milliseconds or video capture timestamp
00260     case CV_CAP_PROP_FPS://Frame rate
00261     case CV_CAP_PROP_FOURCC://4-character code of codec
00262     case CV_CAP_PROP_MODE:// A backend-specific value indicating the current capture mode
00263     case CV_CAP_PROP_BRIGHTNESS:// Brightness of the image ( only for cameras )
00264     case CV_CAP_PROP_CONTRAST:// Contrast of the image ( only for cameras )
00265     case CV_CAP_PROP_SATURATION:// Saturation of the image ( only for cameras )
00266     case CV_CAP_PROP_HUE:// Hue of the image ( only for cameras )
00267     case CV_CAP_PROP_GAIN:// Gain of the image ( only for cameras )
00268     case CV_CAP_PROP_EXPOSURE:// Exposure ( only for cameras )
00269     case CV_CAP_PROP_FRAME_COUNT://Number of frames in the video file
00270       //case CV_CAP_PROP_WHITE_BALANCE://Currently unsupported
00271     case CV_CAP_PROP_RECTIFICATION://TOWRITE ( note: only supported by DC1394 v 2.x backend currently )
00272       {
00273         if( type_of_input_==IS_LIST_FILES||type_of_input_==IS_SINGLE_FILE||type_of_input_==IS_DIRECTORY )
00274           return false;
00275         //else, do nothing as the property is already assigned
00276       }
00277       break;
00278     case CV_CAP_PROP_POS_AVI_RATIO:
00279       //Relative position of the video file ( 0 - start of the film, 1 - end of the film )
00280       {
00281         if( (type_of_input_==IS_LIST_FILES && suffix_ != "Not a dynamic list" )||
00282           type_of_input_== IS_SINGLE_FILE )
00283           return false;
00284         else
00285         {
00286           if( type_of_input_==IS_DIRECTORY )
00287           {
00288             numFrame_=( unsigned int ) ( _value*nameOfFiles_.size( ) );
00289           }
00290         }
00291       }
00292       break;
00293     default:
00294       return false;
00295       break;
00296     }
00297 
00298     //if the motion stream come from capture_, update the structure too:
00299     return true;
00300   };
00301 
00302   double MotionProcessor::getProperty( int idProp )
00303   {
00304     double valOut=0;
00305     switch( type_of_input_ )
00306     {
00307     case IS_WEBCAM:
00308     case IS_VIDEO:
00309       valOut = capture_.get( idProp );
00310       break;
00311     case IS_LIST_FILES:
00312     case IS_SINGLE_FILE:
00313       {
00314         switch ( idProp )
00315         {
00316         case CV_CAP_PROP_CONVERT_RGB://Boolean flags indicating whether images should be converted to RGB
00317           {
00318             valOut=convertToRGB_;
00319           };
00320           break;
00321         case CV_CAP_PROP_FRAME_HEIGHT://Height of the frames in the video stream
00322           {
00323             valOut=wantedHeight_;
00324           };
00325           break;
00326         case CV_CAP_PROP_FRAME_WIDTH://Width of the frames in the video stream
00327           {
00328             valOut=wantedWidth_;
00329           };
00330           break;
00331         case CV_CAP_PROP_POS_FRAMES:// 0-based index of the frame to be decoded/captured next
00332           {
00333             valOut=numFrame_;
00334           };
00335           break;
00336         case CV_CAP_PROP_POS_AVI_RATIO://Relative position of the video file ( 0 - start of the film, 1 - end of the film )
00337           {
00338             if( type_of_input_==IS_LIST_FILES||type_of_input_==IS_SINGLE_FILE )
00339               CV_Error( CV_StsBadArg, "MotionProcessor unknow property !" );
00340             else
00341             {
00342               if( type_of_input_==IS_DIRECTORY )
00343               {
00344                 valOut=( (double )numFrame_/nameOfFiles_.size( ) );
00345               }
00346             }
00347           }
00348           break;
00349         case CV_CAP_PROP_FRAME_COUNT://Number of frames in the video file
00350           {
00351             if( type_of_input_==IS_LIST_FILES||type_of_input_==IS_SINGLE_FILE )
00352               CV_Error( CV_StsBadArg, "MotionProcessor unknow property !" );
00353             else
00354             {
00355               if( type_of_input_==IS_DIRECTORY )
00356               {
00357                 numFrame_=( unsigned int )idProp;
00358               }
00359             }
00360           }
00361           break;
00362         case CV_CAP_PROP_FORMAT://The format of the Mat objects returned by retrieve( )
00363         case CV_CAP_PROP_POS_MSEC://Film current position in milliseconds or video capture timestamp
00364         case CV_CAP_PROP_FPS://Frame rate
00365         case CV_CAP_PROP_FOURCC://4-character code of codec
00366         case CV_CAP_PROP_MODE:// A backend-specific value indicating the current capture mode
00367         case CV_CAP_PROP_BRIGHTNESS:// Brightness of the image ( only for cameras )
00368         case CV_CAP_PROP_CONTRAST:// Contrast of the image ( only for cameras )
00369         case CV_CAP_PROP_SATURATION:// Saturation of the image ( only for cameras )
00370         case CV_CAP_PROP_HUE:// Hue of the image ( only for cameras )
00371         case CV_CAP_PROP_GAIN:// Gain of the image ( only for cameras )
00372         case CV_CAP_PROP_EXPOSURE:// Exposure ( only for cameras )
00373           //case CV_CAP_PROP_WHITE_BALANCE://Currently unsupported
00374         case CV_CAP_PROP_RECTIFICATION://TOWRITE ( note: only supported by DC1394 v 2.x backend currently )
00375         default:
00376           CV_Error( CV_StsBadArg, "MotionProcessor unknow property !" );
00377           break;
00378         }
00379       }
00380       break;
00381     }
00382 
00383     return valOut;
00384   }
00385 
00386 }
 All Classes Functions Variables