motion.cpp
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:15k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2. *
  3. * $Id: motion.cpp,v 1.2 2005/01/30 05:11:40 gabest Exp $ $Name:  $
  4. *
  5. * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  6. *
  7. * The contents of this file are subject to the Mozilla Public License
  8. * Version 1.1 (the "License"); you may not use this file except in compliance
  9. * with the License. You may obtain a copy of the License at
  10. * http://www.mozilla.org/MPL/
  11. *
  12. * Software distributed under the License is distributed on an "AS IS" basis,
  13. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
  14. * the specific language governing rights and limitations under the License.
  15. *
  16. * The Original Code is BBC Research and Development code.
  17. *
  18. * The Initial Developer of the Original Code is the British Broadcasting
  19. * Corporation.
  20. * Portions created by the Initial Developer are Copyright (C) 2004.
  21. * All Rights Reserved.
  22. *
  23. * Contributor(s): Thomas Davies (Original Author), Chris Bowley
  24. *
  25. * Alternatively, the contents of this file may be used under the terms of
  26. * the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
  27. * Public License Version 2.1 (the "LGPL"), in which case the provisions of
  28. * the GPL or the LGPL are applicable instead of those above. If you wish to
  29. * allow use of your version of this file only under the terms of the either
  30. * the GPL or LGPL and not to allow others to use your version of this file
  31. * under the MPL, indicate your decision by deleting the provisions above
  32. * and replace them with the notice and other provisions required by the GPL
  33. * or LGPL. If you do not delete the provisions above, a recipient may use
  34. * your version of this file under the terms of any one of the MPL, the GPL
  35. * or the LGPL.
  36. * ***** END LICENSE BLOCK ***** */
  37. ////////////////////////////////////////////////////////////////
  38. //classes and functions for motion estimation and compensation//
  39. ////////////////////////////////////////////////////////////////
  40. #include <libdirac_common/motion.h>
  41. using namespace dirac;
  42. #include <cmath>
  43. using namespace std;
  44. //Motion vector and Motion Estimation structures//
  45. //////////////////////////////////////////////////
  46. MvData::MvData( const int xnumMB, const int ynumMB , 
  47.                 const int xnumblocks, const int ynumblocks , const int num_refs ):
  48.     m_vectors( Range(1 , num_refs) ),
  49.     m_gm_vectors( Range(1 , num_refs) ),
  50.     m_modes( ynumblocks , xnumblocks ),
  51.     m_dc( 3 ),
  52.     m_mb_split( ynumMB , xnumMB ),
  53.     m_mb_common( ynumMB , xnumMB ),
  54.     m_gm_params( Range(1 , num_refs) )
  55. {
  56.     InitMvData();
  57. }
  58. MvData::MvData( const int xnumMB , const int ynumMB , const int num_refs ):
  59.     m_vectors( Range(1 , num_refs) ),
  60.     m_gm_vectors( Range(1 , num_refs) ),
  61.     m_modes( 4*ynumMB , 4*xnumMB ),
  62.     m_dc( 3 ),
  63.     m_mb_split( ynumMB , xnumMB ),
  64.     m_mb_common( ynumMB , xnumMB ),
  65.     m_gm_params( Range(1 , num_refs) )
  66. {
  67.     InitMvData();
  68. }
  69. void MvData::InitMvData()
  70. {
  71.     // Create the arrays of vectors
  72.      for ( int i=m_vectors.First() ; i<=m_vectors.Last() ; ++i ){
  73.          m_vectors[i] = new MvArray( Mode().LengthY() , Mode().LengthX() );
  74.          m_gm_vectors[i] = new MvArray( Mode().LengthY() , Mode().LengthX() );
  75.      }
  76.     // create global motion parameter arrays
  77.     for ( int i=m_gm_params.First() ; i<=m_gm_params.Last() ; ++i ){
  78.          m_gm_params[i] = new OneDArray<float> ( 8 );
  79.     }
  80.      // Create the arrays of dc values
  81.      for ( int i=0 ; i<3 ; ++i )
  82.          m_dc[i] = new TwoDArray<ValueType>( Mode().LengthY() , Mode().LengthX() );
  83. }
  84. MvData::~MvData()
  85. {
  86.    // Delete the arrays of vectors
  87.     for ( int i=m_vectors.First() ; i<=m_vectors.Last() ; ++i ){
  88.         delete m_vectors[i];
  89.         delete m_gm_vectors[i];
  90.     }
  91.      // delete array of global motion parameters
  92.      for ( int i=m_gm_params.First() ; i<=m_gm_params.Last() ; ++i ){
  93.          delete m_gm_params[i];
  94.      }
  95.      // Delete the arrays of dc values
  96.      for ( int i=0 ; i<3 ; ++i )
  97.          delete m_dc[i];
  98. }
  99. MEData::MEData(const int xnumMB , const int ynumMB ,
  100.                 const int xnumblocks , const int ynumblocks , const int num_refs ):
  101.      MvData( xnumMB , ynumMB , xnumblocks , ynumblocks , num_refs ),
  102.      m_pred_costs( Range( 1 , num_refs ) ),
  103.      m_intra_costs( ynumblocks , xnumblocks ),
  104.      m_bipred_costs( ynumblocks , xnumblocks ),
  105.      m_MB_costs( ynumMB , xnumMB ),
  106.      m_lambda_map( ynumblocks , xnumblocks ),
  107.      m_inliers( Range( 1 , num_refs ) )
  108. {
  109.     InitMEData();
  110. }
  111. MEData::MEData( const int xnumMB , const int ynumMB ,  const int num_refs ):
  112.      MvData( xnumMB , ynumMB , num_refs ),
  113.      m_pred_costs( Range( 1 , num_refs ) ),
  114.      m_intra_costs( 4*ynumMB , 4*xnumMB ),
  115.      m_bipred_costs( 4*ynumMB , 4*xnumMB ),
  116.      m_MB_costs( ynumMB , xnumMB ),
  117.      m_lambda_map( 4*ynumMB , 4*xnumMB ),
  118.      m_inliers( Range( 1 , num_refs ) )
  119. {
  120.     InitMEData();
  121. }
  122. void MEData::InitMEData()
  123. {
  124.    // Create the arrays of prediction costs
  125.     for ( int i=m_pred_costs.First() ; i<=m_pred_costs.Last() ; ++i )
  126.         m_pred_costs[i] = new TwoDArray<MvCostData>( Mode().LengthY() , Mode().LengthX() );
  127.     // Create the arrays of vectors
  128.      for ( int i=m_inliers.First() ; i<=m_inliers.Last() ; ++i )
  129.          m_inliers[i] = new TwoDArray<int>( Mode().LengthY() , Mode().LengthX() );
  130. }
  131. void MEData::SetLambdaMap( const int num_refs , const float lambda )
  132. {
  133.     TwoDArray<bool> transition_map1( Mode().LengthY() , Mode().LengthX() );
  134.     TwoDArray<bool> transition_map2( Mode().LengthY() , Mode().LengthX() );
  135.     FindTransitions( transition_map1 , 1 );
  136.     for ( int j=0 ; j<m_lambda_map.LengthY() ; j++)
  137.     {
  138.         for ( int i=0 ; i<m_lambda_map.LengthX() ; i++)
  139.         {
  140.             if ( transition_map1[j][i] )
  141.                 m_lambda_map[j][i] = 0.0;
  142.             else
  143.                 m_lambda_map[j][i] = lambda;
  144.             if ( i<4 || j<4 )
  145.                 m_lambda_map[j][i] /= 5.0; 
  146.         }// i
  147.     }// j
  148.     if ( num_refs > 1 )
  149.     {
  150.         FindTransitions( transition_map2 , 2 );
  151.         for ( int j=0 ; j<m_lambda_map.LengthY() ; j++)
  152.         {
  153.             for ( int i=0 ; i<m_lambda_map.LengthX() ; i++)
  154.             {
  155.                 if ( transition_map1[j][i] || transition_map2[j][i] )
  156.                     m_lambda_map[j][i] = 0.0;
  157.                 else
  158.                     m_lambda_map[j][i] = lambda;
  159.             }// i
  160.         }// j
  161.     }
  162. }
  163. void MEData::SetLambdaMap( const int level , const TwoDArray<float>& l_map , const float wt )
  164. {
  165.     const int factor = 1<<(2-level);
  166.     int xstart , xend , ystart , yend;
  167.  
  168.     for (int j = 0 ; j<m_lambda_map.LengthY() ; ++j )
  169.     {
  170.         for (int i = 0 ; i<m_lambda_map.LengthX() ; ++i )
  171.         {
  172.             xstart = factor * i;
  173.             ystart = factor * j;
  174.             xend = factor * ( i + 1 );
  175.             yend = factor * ( j + 1 );
  176.             m_lambda_map[j][i] = l_map[ystart][xstart];
  177.             for (int q = ystart ; q<yend ; ++q )
  178.                 for (int p = xstart ; p<xend ; ++p )
  179.                       m_lambda_map[j][i] = std::max( l_map[q][p] , m_lambda_map[j][i] );
  180.            m_lambda_map[j][i] *= wt;
  181.         }// i
  182.     }// j
  183. }
  184. void MEData::FindTransitions( TwoDArray<bool>& trans_map , const int ref_num )
  185. {
  186.     const MvArray& mv_array = Vectors( ref_num );
  187.     // Start with a statistical approach - determine thresholds later
  188.     // Compute mean and standard deviation of local motion vector variance //
  189.     /////////////////////////////////////////////////////////////////////////
  190.     long double total_cost = 0.0;
  191.     long double mean_cost;
  192.  
  193.     // first, mean
  194.     for ( int j=0 ; j<mv_array.LengthY() ; ++j )
  195.         for ( int i=0 ; i<mv_array.LengthX() ; ++i )
  196.             total_cost += PredCosts( ref_num )[j][i].SAD;
  197.     mean_cost = total_cost / 
  198.                    static_cast<long double>( mv_array.LengthX()*mv_array.LengthY() );
  199.     // next , Standard Deviation
  200.     long double sd_cost = 0.0;
  201.     double diff;
  202.     
  203.     for ( int j=0 ; j<mv_array.LengthY() ; ++j )
  204.     {
  205.         for ( int i=0 ; i<mv_array.LengthX() ; ++i )
  206.         {
  207.             diff = PredCosts( ref_num )[j][i].SAD - mean_cost;
  208.             diff *= diff;
  209.             sd_cost += diff;
  210.         }// i
  211.     }// j
  212.     // Get the variance ...
  213.     sd_cost /= static_cast<long double>( mv_array.LengthX()*mv_array.LengthY() );
  214.     // ... and then the SD
  215.     sd_cost = std::sqrt( sd_cost );
  216.     float threshold = static_cast<float>( mean_cost + 1.5*sd_cost );
  217.     // now go through and mark those that go above the threshold
  218.     for ( int j=0 ; j<mv_array.LengthY() ; ++j )
  219.         for ( int i=0 ; i<mv_array.LengthX() ; ++i )
  220.             trans_map[j][i] = ( PredCosts( ref_num )[j][i].SAD >= threshold )? true : false;
  221. //
  222.     // Next look at motion-vector costs
  223.     TwoDArray<double> val_array( mv_array.LengthY() , mv_array.LengthX() );
  224.     // first, mean
  225.     total_cost = 0.0;
  226.     for ( int i=0 ; i<mv_array.LengthX() ; ++i )
  227.     {
  228.         val_array[0][i] = 0.0;
  229.         val_array[val_array.LastY()][i] = 0.0;
  230.     }// i
  231.     for ( int j=1 ; j<mv_array.LengthY()-1 ; ++j )
  232.     {
  233.         val_array[j][0] = 0.0;
  234.         val_array[j][val_array.LastX()] = 0.0;
  235.         for ( int i=1 ; i<mv_array.LengthX()-1 ; ++i )
  236.         {
  237.             val_array[j][i] =0.0;
  238.             for (int q=-1 ; q<=1 ; ++q)
  239.                 for (int p=-1 ; p<=1 ; ++p)
  240.                     val_array[j][i] = std::max( val_array[j][i] , (double)Norm1( mv_array[j+q][i+p] - mv_array[j][i] ) );
  241.             total_cost += val_array[j][i];
  242.         }// i
  243.     }// j
  244.     mean_cost = total_cost / 
  245.                    static_cast<long double>( mv_array.LengthX()*mv_array.LengthY() );
  246.     // next , Standard Deviation
  247.     sd_cost = 0.0;
  248.     
  249.     for ( int j=1 ; j<mv_array.LengthY()-1 ; ++j )
  250.     {
  251.         for ( int i=1 ; i<mv_array.LengthX()-1 ; ++i )
  252.         {
  253.             diff = val_array[j][i] - mean_cost;
  254.             diff *= diff;
  255.             sd_cost += diff;
  256.         }// i
  257.     }// j
  258.     // Get the variance ...
  259.     sd_cost /= static_cast<long double>( mv_array.LengthX()*mv_array.LengthY() );
  260.     // ... and then the SD
  261.     sd_cost = std::sqrt( sd_cost );
  262.     threshold = static_cast<float>( mean_cost + 1.5*sd_cost );
  263.     // now go through and mark those that go above the threshold
  264.     for ( int j=0 ; j<mv_array.LengthY() ; ++j )
  265.         for ( int i=0 ; i<mv_array.LengthX() ; ++i )
  266. //            trans_map[j][i] = ( val_array[j][i] >= threshold )? true : false;
  267. trans_map[j][i] = false;
  268. //     bool contains_trans;
  269. //     for ( int j=0 ; j<mv_array.LengthY()/4 ; ++j )
  270. //     {
  271. //         for ( int i=0 ; i<mv_array.LengthX()/4 ; ++i )
  272. //         {     
  273. //             contains_trans = false;
  274. //             for ( int q=4*j ; q<4*(j+1) ; ++q )
  275. //             {
  276. //                 for ( int p=4*i ; p<4*(i+1) ; ++p )
  277. //                 {
  278. //                     if (trans_map[q][p])
  279. //                         contains_trans = true;
  280. //                 }// p
  281. //             }// q
  282. //             for ( int q=4*j ; q<4*(j+1) ; ++q )
  283. //                 for ( int p=4*i ; p<4*(i+1) ; ++p )
  284. //                     trans_map[q][p] = contains_trans;
  285. //         }// i
  286. //     }// j
  287.      
  288. }
  289. MEData::~MEData()
  290. {
  291.     // Delete the arrays of prediction costs
  292.      for ( int i=m_pred_costs.First() ; i<=m_pred_costs.Last() ; ++i )
  293.          delete m_pred_costs[i];
  294.      for ( int i=m_inliers.First() ; i<=m_inliers.Last() ; ++i )
  295.         delete m_inliers[i];
  296. }
  297. namespace dirac
  298. {
  299. //! Overloaded operator<< for MvCostData
  300. /*!
  301.     Only writes SAD value to stream
  302. */
  303. ostream & operator<< (ostream & stream, MvCostData & cost)
  304. {
  305.     stream << cost.SAD << " " << cost.mvcost;
  306.     return stream;
  307. }
  308. //! Overloaded operator>> for MvCostData
  309. /*!
  310.     Only reads SAD value from stream
  311. */
  312. istream & operator>> (istream & stream, MvCostData & cost)
  313. {
  314.     stream >> cost.SAD >> cost.mvcost;
  315.     return stream;
  316. }
  317. //! Overloaded operator>> for PredMode
  318. /*!
  319.     No operator<< is specified as enumeration is written as integers
  320.     operator>> required to specify PredMode input
  321. */
  322. istream & operator>> (istream & stream, PredMode & mode)
  323. {
  324.     int temp;
  325.     stream >> temp;
  326.     mode = (PredMode)temp;
  327.     return stream;
  328. }
  329. // Overriden extractor operator for reading MvData data members
  330. istream &operator>> (istream & stream, MEData & me_data)
  331. {
  332.     stream.ignore(1000, 'n');
  333.     
  334.     // input reference-independent information
  335.     stream >> me_data.MBSplit();
  336.     stream >> me_data.MBCommonMode();
  337.     stream >> me_data.MBCosts();
  338.     stream >> me_data.Mode();
  339.     stream >> me_data.IntraCosts();
  340.     if (me_data.m_pred_costs.Length() > 1)
  341.         stream >> me_data.BiPredCosts();
  342.     if (me_data.DC().Length() == 1)
  343.     {
  344.         stream >> me_data.DC( Y_COMP );
  345.     }
  346.     else if (me_data.DC().Length() == 3)
  347.     {
  348.         stream >> me_data.DC( Y_COMP );
  349.         stream >> me_data.DC( U_COMP );
  350.         stream >> me_data.DC( V_COMP );
  351.     }
  352.     // input reference information
  353.     for (int i=1; i<=me_data.m_pred_costs.Length(); ++i)
  354.     {
  355.         stream >> me_data.Vectors(i);
  356.         stream >> me_data.PredCosts(i);
  357.         //stream >> me_data.GlobalMotionParameters(i);
  358.         //stream >> me_data.GlobalMotionVectors(i);
  359.         //stream >> me_data.GlobalMotionInliers(i);
  360.     }
  361.     return stream;
  362. }
  363. // Overriden operator for output of MvData member data (to file)
  364. ostream &operator<< (ostream & stream, MEData & me_data)
  365. {
  366.     // output reference-independent information
  367.     stream << endl << endl << me_data.MBSplit();
  368.     stream << endl << me_data.MBCommonMode();
  369.     stream << endl << me_data.MBCosts();
  370.     stream << endl << me_data.Mode();
  371.     stream << endl << me_data.IntraCosts() << endl;
  372.     if (me_data.m_pred_costs.Length() > 1)
  373.         stream << me_data.BiPredCosts();
  374.     // output component DC values
  375.     if (me_data.DC().Length() == 1)
  376.     {
  377.         stream << endl << me_data.DC( Y_COMP );
  378.     }
  379.     else if (me_data.DC().Length() == 3)
  380.     {
  381.         stream << endl << me_data.DC( Y_COMP );
  382.         stream << endl << me_data.DC( U_COMP );
  383.         stream << endl << me_data.DC( V_COMP );
  384.     }
  385.     // output reference information
  386.     for (int i=1; i<=me_data.m_pred_costs.Length(); ++i)
  387.     {
  388.         stream << endl << me_data.Vectors(i);
  389.         stream << endl << me_data.PredCosts(i) << endl;
  390.         //stream << endl << me_data.GlobalMotionParameters(i) << endl;
  391.         //stream << endl << me_data.GlobalMotionVectors(i) << endl;
  392.         //stream << endl << me_data.GlobalMotionInliers(i) << endl;
  393.     }
  394.     
  395.     return stream;
  396. }
  397. } // namespace dirac