GSoC2011SfM  0.1
Google Summer of Code 2011: Structure from motion
D:/Travail/These/Determination caracteristiques camera/GSoC/SfM/src/PCL_mapping.h
00001 
00002 #ifndef PCL_MAPPING_H
00003 #define PCL_MAPPING_H
00004 
00005 #include <pcl/point_types.h>
00006 #include <pcl/point_cloud.h>
00007 #include <opencv2/core/core.hpp>
00008 #include <opencv2/features2d/features2d.hpp>
00009 #include <vector>
00010 /*
00011 type not yet taken into account:
00012 Normal : float[ 4 ] + float[ 4 ]
00013 PointNormal : float[ 4 ] * 3
00014 PointWithViewpoint : float[ 4 ] + float[ 4 ]
00015 PointXYZRGBNormal : ( same as before )
00016 PointXYZINormal : ( same as before )
00017 */
00018 
00019 /*
00020 cv::Matx can't be used in an union ( due to constructors )
00021 As cv::Matx's datas are allocated in stack ( as PCL too ),
00022 we have to find a way to use union or use bad cast like I do here:
00023 */
00024 namespace OpencvSfM{
00025 
00026   namespace mapping{
00027 
00034     template<typename OpencvType>
00035     float* convert_to_float( const OpencvType& t )
00036     {
00037       CV_DbgAssert( OpencvType::cols == 1 );
00038       //we have to convert data:
00039       float* out = new float[ OpencvType::rows ];
00040       for( int i = 0; i < OpencvType::rows; ++i )
00041         out[ i ] = ( float ) t.val[ i ];
00042       return out;
00043     }
00050     template<typename Type>
00051     Type* convert_to_( const float* data, int sizeOfBuf = 8 )
00052     {
00053       //we have to convert data:
00054       Type* out = new Type[ sizeOfBuf ];
00055       for( int i = 0; i < sizeOfBuf; ++i )
00056         out[ i ] = ( Type ) data[ i ];
00057       return out;
00058     }
00068     template<typename Type, typename Map_type>
00069     inline Type* convert_without_cast( Map_type* mapped )
00070     {
00071       CV_DbgAssert( mapped->size_of_data >= sizeof( Type ) / sizeof( float ) );
00072       return reinterpret_cast< Type* >( mapped->data_ );
00073     }
00080     template<typename Map_type>
00081     inline void initData( Map_type* mapped,
00082       int sizeOfBuf = 0, float *data = NULL )
00083     {
00084       if( sizeOfBuf <= 0 || data == NULL )
00085       {
00086         if( sizeOfBuf <= 0 )
00087           mapped->size_of_data = 8;
00088         else
00089           mapped->size_of_data = sizeOfBuf;
00090         mapped->data_ = new float[ mapped->size_of_data ];
00091         mapped->should_remove=true;
00092       }
00093       else
00094       {
00095         mapped->size_of_data = ( unsigned int ) sizeOfBuf;
00096         mapped->data_ = data;
00097         mapped->should_remove=false;
00098       }
00099     }
00105     template<typename Map_type>
00106     inline void setDistinctMemory( Map_type* mapped,
00107       int new_mem_size = 8, float* newData = NULL )
00108     {
00109       int newSize = MAX( new_mem_size, mapped->size_of_data );
00110       float* data = newData;
00111       if( data == NULL )
00112       {
00113         data = new float[ newSize ];
00114         memcpy( data, mapped->data_, mapped->size_of_data*sizeof( float ) );
00115       }
00116       if( mapped->should_remove ) delete mapped->data_;
00117       mapped->should_remove = true;
00118       mapped->size_of_data = newSize;
00119       mapped->data_ = data;
00120     }
00128     template<typename LowDataType, typename Type, typename Map_type>
00129     inline void convert_( Map_type* mapped, Type* out )
00130     {
00131       CV_DbgAssert( mapped->size_of_data >= sizeof( Type ) / sizeof( float ) );
00132       LowDataType* data = convert_to_<LowDataType>( mapped->data_, mapped->size_of_data );
00133       memcpy( reinterpret_cast< char* >( out ), data, sizeof( Type ) );
00134       delete data;
00135     }
00136 
00140     struct EIGEN_ALIGN16 Point
00141     {
00142       float *data_;
00143       unsigned char size_of_data;
00144       bool should_remove;
00145 
00149       Point( const Point& otherP ){
00150         initData( this, otherP.size_of_data );
00151         memcpy( data_, otherP.data_, size_of_data * sizeof( float ) );
00152       };
00153 
00157       Point& operator =( const Point& otherP ){
00158         int dataSize = otherP.size_of_data * sizeof( float );
00159         if( otherP.size_of_data > size_of_data )
00160         {
00161           if( should_remove ) delete data_;
00162           initData( this, otherP.size_of_data );
00163         }
00164         else
00165         {
00166           if( otherP.size_of_data < size_of_data )
00167           {//init the range outside the copy:
00168             int diff = ( size_of_data - otherP.size_of_data ) *
00169               sizeof( float );
00170             dataSize = ( ( size_of_data * sizeof( float ) ) - diff );
00171             memset ( ( (char* )data_ ) + dataSize, 0, diff );
00172           }
00173         }
00174         memcpy( data_, otherP.data_, dataSize );
00175         return *this;
00176       };
00177 
00181       Point( ){ initData( this ); };
00182 
00188       Point( float *data, int sizeOfBuf = 4 ){
00189         initData( this, sizeOfBuf, data );
00190       };
00191 
00196       template<typename Type, int size>
00197       Point( cv::Vec<Type,size>& v ){
00198         if( sizeof( Type ) == sizeof( float ) )
00199           initData( this, v.rows, ( float* ) v.val );
00200         else
00201         {
00202           initData( this, v.rows, convert_to_float( v ) );
00203           should_remove=true;//convert_to_float create a buffer
00204         }
00205       };
00206       
00211       template<typename Type, int size>
00212       Point( cv::Matx<Type,size,1>& matX ){
00213         if( sizeof( Type::value_type ) == sizeof( float ) )
00214           initData( this, Type::rows, ( float* ) matX.val );
00215         else
00216         {
00217           initData( this, Type::rows, convert_to_float( matX ) );
00218           should_remove=true;//convert_to_float create a buffer
00219         }
00220       };
00221       
00226       Point( cv::KeyPoint& kp ){
00227         initData( this, 6, reinterpret_cast< float* >( &kp ) );
00228       };
00229       
00234       Point( pcl::PointXY& pXY ){
00235         initData( this, 2, reinterpret_cast< float* >( &pXY ) );
00236       };
00241       Point( pcl::PointXYZ& pXYZ ){ initData( this, 4, pXYZ.data ); };
00246       Point( pcl::PointXYZI& pXYZi ){ initData( this, 8, pXYZi.data ); };
00251       Point( pcl::InterestPoint& iP ){ initData( this, 8, iP.data ); };
00256       Point( pcl::PointWithRange& pPWR ){ initData( this, 8, pPWR.data ); };
00261       Point( pcl::PointXYZRGBA& pXYZ1 ){ initData( this, 8, pXYZ1.data ); };
00266       Point( pcl::PointXYZRGB& pXYZ2 ){ initData( this, 8, pXYZ2.data ); };
00267 
00272       ~Point( ){ if( should_remove ) delete data_; };
00273 
00274 
00278       template<typename Type, int size>
00279       inline operator cv::Matx<Type,size,1>&( ) {
00280         CV_DbgAssert( sizeof( Type ) == sizeof( float ) );
00281         return * convert_without_cast< cv::Matx<Type,size,1> >( this );
00282       };
00286       template<typename Type, int size>
00287       inline operator cv::Vec<Type,size>&( ) {
00288         CV_DbgAssert( sizeof( Type ) == sizeof( float ) );
00289         return * convert_without_cast< cv::Vec<Type,size> >( this );
00290       };
00294       template<typename Type>
00295       inline operator cv::Point3_<Type>&( ) {
00296         CV_DbgAssert( sizeof( Type ) == sizeof( float ) );
00297         return * convert_without_cast< cv::Point3_<Type> >( this );
00298       };
00302       inline operator cv::KeyPoint&( ) {
00303       return * convert_without_cast< cv::KeyPoint >( this );};
00304 
00305       
00309       inline operator pcl::PointXY&( ) {
00310         return * convert_without_cast< pcl::PointXY >( this );
00311       };
00315       inline operator pcl::PointXYZ&( ) {
00316         return * convert_without_cast< pcl::PointXYZ >( this );
00317       };
00321       inline operator pcl::PointXYZI&( ) {
00322         return * convert_without_cast< pcl::PointXYZI >( this );
00323       };
00327       inline operator pcl::InterestPoint&( ) {
00328         return * convert_without_cast< pcl::InterestPoint >( this );
00329       };
00333       inline operator pcl::PointWithRange&( ) {
00334         return * convert_without_cast< pcl::PointWithRange >( this );
00335       };
00339       inline operator pcl::PointXYZRGBA&( ) {
00340         return * convert_without_cast< pcl::PointXYZRGBA >( this );
00341       };
00345       inline operator pcl::PointXYZRGB&( ) {
00346         return * convert_without_cast< pcl::PointXYZRGB >( this );
00347       };
00348 
00349 
00350       EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00351     };
00352     
00357     template<typename TypeFrom, typename TypeTo,
00358       typename allocatorFrom, typename allocatorTo>
00359     void convertToMappedVector(
00360       const std::vector<TypeFrom,allocatorFrom>& vectFrom,
00361       std::vector<TypeTo,allocatorTo>& vectTo )
00362     {
00363       vectTo.clear( );
00364       unsigned int it = 0,
00365         end = vectFrom.size( );
00366       vectTo.reserve( end );
00367 
00368       while ( it < end )
00369       {
00370         //can't create directly the new value because of the const arg...
00371         TypeTo convertor( NULL, sizeof( TypeFrom ) / sizeof( float ) );
00372         const TypeFrom& val = vectFrom[ it ];
00373 
00374         memcpy( reinterpret_cast<char*>( convertor.data_ ),
00375           reinterpret_cast<const char*>( &val ),
00376           sizeof( TypeFrom ) );//assign the new value
00377 
00378         vectTo.push_back( convertor );//create an empty value
00379         it++;
00380       }
00381     }
00382     
00387     template<typename TypeFrom, typename TypeTo,
00388       typename allocatorFrom, typename allocatorTo>
00389     void convertFromMappedVector(
00390       std::vector<TypeFrom,allocatorFrom>& vectFrom,
00391       std::vector<TypeTo,allocatorTo>& vectTo )
00392     {
00393       vectTo.clear( );
00394       unsigned int it = 0,
00395         end = vectFrom.size( );
00396       vectTo.reserve( end );
00397 
00398       while ( it < end )
00399       {
00400         vectTo.push_back( TypeTo( ) );//create an empty value
00401         int minSize = sizeof( vectTo[ it ] ) / sizeof( float );
00402         //We must have enough space in mapped memory:
00403         if( minSize > vectFrom[ it ].size_of_data )
00404           setDistinctMemory( &vectFrom[ it ], minSize );
00405 
00406 
00407         memcpy( reinterpret_cast<char*>( &vectTo[ it ] ),
00408           reinterpret_cast<const char*>( vectFrom[ it ].data_ ),
00409           minSize * sizeof( float ) );//assign the new value
00410         it++;
00411       }
00412     }
00413     
00417     template<typename TypeFrom, typename TypeTo,
00418       typename allocatorFrom, typename allocatorTo>
00419     void convert_OpenCV_vector(
00420       const std::vector<TypeFrom,allocatorFrom>& vectFrom,
00421       std::vector<TypeTo,allocatorTo>& vectTo )
00422     {
00423       vectTo.clear( );
00424       unsigned int it = 0,
00425         end = vectFrom.size( );
00426       vectTo.reserve( end );
00427 
00428       while ( it < end )
00429       {
00430         vectTo.push_back( TypeTo( ) );//create an empty value
00431         float* datas = convert_to_float( vectFrom[ it ] );
00432 
00433         memcpy( reinterpret_cast<char*>( &vectTo[ it ] ),
00434           reinterpret_cast<const char*>( datas ),
00435           sizeof( TypeFrom ) );//assign the new value
00436 
00437         delete datas;
00438         it++;
00439       }
00440     }
00441     
00445     template<typename TypeFrom, typename TypeTo,
00446       typename allocatorFrom, typename allocatorTo>
00447     void convert_PCL_vector(
00448       const std::vector<TypeFrom,allocatorFrom>& vectFrom,
00449       std::vector<TypeTo,allocatorTo>& vectTo )
00450     {
00451       vectTo.clear( );
00452       unsigned int it = 0,
00453         end = vectFrom.size( );
00454       vectTo.reserve( end );
00455       int sizeOfData = sizeof( TypeFrom ) / sizeof( float );
00456 
00457       while ( it < end )
00458       {
00459         vectTo.push_back( TypeTo( ) );//create an empty value
00460         const float* datas = reinterpret_cast<const float*>( &vectFrom[ it ] );
00461         void *valConverted;
00462         int sizeOfType;
00463 
00464         //copy data using type:
00465         switch( TypeTo::depth )
00466         {
00467         case CV_8U:
00468           valConverted = convert_to_<uchar>( datas, sizeOfData );
00469           sizeOfType = sizeof( uchar );
00470           break;
00471         case CV_8S:
00472           valConverted = convert_to_<char>( datas, sizeOfData );
00473           sizeOfType = sizeof( char );
00474           break;
00475         case CV_16U:
00476           valConverted = convert_to_<ushort>( datas, sizeOfData );
00477           sizeOfType = sizeof( ushort );
00478           break;
00479         case CV_16S:
00480           valConverted = convert_to_<short>( datas, sizeOfData );
00481           sizeOfType = sizeof( short );
00482           break;
00483         case CV_32S:
00484           valConverted = convert_to_<int>( datas, sizeOfData );
00485           sizeOfType = sizeof( int );
00486           break;
00487         case CV_32F:
00488           valConverted = convert_to_<float>( datas, sizeOfData );
00489           sizeOfType = sizeof( float );
00490           break;
00491         case CV_64F:
00492           valConverted = convert_to_<double>( datas, sizeOfData );
00493           sizeOfType = sizeof( double );
00494           break;
00495         case CV_USRTYPE1:
00496           CV_Error( CV_StsBadFunc, "User type is not allowed!" );
00497           break;
00498         }
00499 
00500         memcpy( reinterpret_cast<char*>( &vectTo[ it ] ),
00501           reinterpret_cast<const char*>( valConverted ),
00502           sizeof( TypeFrom ) );//assign the new value
00503 
00504         switch( TypeTo::depth )
00505         {
00506         case CV_8U:
00507           delete reinterpret_cast<uchar*>(valConverted);
00508           break;
00509         case CV_8S:
00510           delete reinterpret_cast<char*>(valConverted);
00511           break;
00512         case CV_16U:
00513           delete reinterpret_cast<ushort*>(valConverted);
00514           break;
00515         case CV_16S:
00516           delete reinterpret_cast<short*>(valConverted);
00517           break;
00518         case CV_32S:
00519           delete reinterpret_cast<int*>(valConverted);
00520           break;
00521         case CV_32F:
00522           delete reinterpret_cast<float*>(valConverted);
00523           break;
00524         case CV_64F:
00525           delete reinterpret_cast<double*>(valConverted);
00526           break;
00527           break;
00528         }
00529         it++;
00530       }
00531     }
00532     
00536     template<typename TypeFrom, typename allocatorFrom>
00537     void convert_PCL_vector(
00538       std::vector<TypeFrom,allocatorFrom>& vectFrom,
00539       cv::Mat& output, bool copyValues = false )
00540     {
00541       //PCL data are ALWAYS float, just the number of elements can change:
00542       int nbCol = sizeof( TypeFrom ) / sizeof( float );
00543       output = cv::Mat( vectFrom.size( ), nbCol,
00544         CV_32F, ( void* )&vectFrom[ 0 ] );
00545       if( copyValues )
00546         output = output.clone( );
00547     }
00548     
00552     template<typename TypeFrom, typename allocatorFrom,
00553       typename PCL_point>
00554     void convert_OpenCV_vector(
00555       const std::vector<TypeFrom,allocatorFrom>& vectFrom,
00556       pcl::PointCloud< PCL_point >& output )
00557     {
00558       int sizeOfData = sizeof( PCL_point ) / sizeof( float );
00559       sizeOfData = MIN( sizeOfData, TypeFrom::rows );
00560 
00561       size_t itTrack = 0,
00562       max_size = vectFrom.size( );
00563       while ( itTrack < max_size )
00564       {
00565         float* datas = convert_to_float( vectFrom[ itTrack ] );
00566         PCL_point p;
00567         for( int i=0; i<sizeOfData; ++i )
00568           p.data[ i ] = datas[ i ];
00569 
00570         output.points.push_back( p );
00571         delete datas;
00572         itTrack++;
00573       }
00574     }
00575   }
00576 
00577 }
00578 #endif
 All Classes Functions Variables