GSoC2011SfM
0.1
Google Summer of Code 2011: Structure from motion
|
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