- Main Page
- Namespaces
- Classes
- Files
- Directories

- File List
- File Members

# motion.h

    00001 /* ***** BEGIN LICENSE BLOCK *****
    00002 *
    00003 * $Id: motion.h,v 1.2 2005/01/30 05:11:40 gabest Exp $ $Name:  $
    00004 *
    00005 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
    00006 *
    00007 * The contents of this file are subject to the Mozilla Public License
    00008 * Version 1.1 (the "License"); you may not use this file except in compliance
    00009 * with the License. You may obtain a copy of the License at
    00010 * http://www.mozilla.org/MPL/
    00011 *
    00012 * Software distributed under the License is distributed on an "AS IS" basis,
    00013 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
    00014 * the specific language governing rights and limitations under the License.
    00015 *
    00016 * The Original Code is BBC Research and Development code.
    00017 *
    00018 * The Initial Developer of the Original Code is the British Broadcasting
    00019 * Corporation.
    00020 * Portions created by the Initial Developer are Copyright (C) 2004.
    00021 * All Rights Reserved.
    00022 *
    00023 * Contributor(s): Thomas Davies (Original Author), Chris Bowley
    00024 *
    00025 * Alternatively, the contents of this file may be used under the terms of
    00026 * the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
    00027 * Public License Version 2.1 (the "LGPL"), in which case the provisions of
    00028 * the GPL or the LGPL are applicable instead of those above. If you wish to
    00029 * allow use of your version of this file only under the terms of the either
    00030 * the GPL or LGPL and not to allow others to use your version of this file
    00031 * under the MPL, indicate your decision by deleting the provisions above
    00032 * and replace them with the notice and other provisions required by the GPL
    00033 * or LGPL. If you do not delete the provisions above, a recipient may use
    00034 * your version of this file under the terms of any one of the MPL, the GPL
    00035 * or the LGPL.
    00036 * ***** END LICENSE BLOCK ***** */
    00037
    00038 #include <libdirac_common/common.h>
    00039 #include <algorithm>
    00040 #ifndef _MOTION_H
    00041 #define _MOTION_H
    00042
    00043 namespace dirac
    00044 {
    00046     //classes and functions for motion estimation and compensation//
    00048
    00049     //classes
    00050
    00052     template <class T>
    00053     class MotionVector
    00054     {
    00055     public:
    00056
    00058         MotionVector<T>(T a, T b) : x(a), y(b) {};
    00060         MotionVector<T>() : x(0), y(0) {};
    00062         MotionVector<T>(T a) : x(a), y(a) {};
    00063
    00065         inline MotionVector<T> operator+(const MotionVector<T>& argument) const;
    00066
    00068         inline MotionVector<T> operator-(const MotionVector<T>& argument) const;
    00069
    00071         inline MotionVector<T> operator*(const float argument) const;
    00072
    00074         inline MotionVector<T> operator*(const int argument) const;
    00075
    00077         inline MotionVector<T> operator<<(const int argument) const;
    00078
    00080         inline MotionVector<T> operator>>(const int argument) const;
    00081
    00082
    00084         T x,y;
    00085
    00086     };
    00087
    00088
    00089     template <class T>
    00090     inline MotionVector<T> MotionVector<T>::operator+(const MotionVector<T>& argument) const
    00091     {
    00092         MotionVector<T> temp;
    00093         temp.x = x + argument.x;
    00094         temp.y = y + argument.y;
    00095
    00096         return temp;
    00097     }
    00098
    00099     template <class T>
    00100     inline MotionVector<T>  MotionVector<T>::operator-(const MotionVector<T>& argument) const
    00101     {
    00102         MotionVector<T> temp;
    00103         temp.x = x-argument.x;
    00104         temp.y = y-argument.y;
    00105
    00106         return temp;
    00107     }
    00108
    00109     template <class T>
    00110     inline MotionVector<T>  MotionVector<T>::operator*(const float argument) const
    00111     {
    00112         MotionVector<T> temp;
    00113         temp.x = x*argument;
    00114         temp.y = y*argument;
    00115
    00116         return temp;
    00117     }
    00118
    00119     template <class T>
    00120     inline MotionVector<T>  MotionVector<T>::operator*(const int argument) const
    00121     {
    00122         MotionVector<T> temp;
    00123         temp.x = x*argument;
    00124         temp.y = y*argument;
    00125
    00126         return temp;
    00127     }
    00128
    00129     template <class T>
    00130     inline MotionVector<T>  MotionVector<T>::operator<<(const int argument) const
    00131     {
    00132         MotionVector<T> temp;
    00133         temp.x = x<<argument;
    00134         temp.y = y<<argument;
    00135
    00136         return temp;
    00137     }
    00138
    00139     template <class T>
    00140     inline MotionVector<T>  MotionVector<T>::operator>>(const int argument) const
    00141     {
    00142         MotionVector<T> temp;
    00143         temp.x = x>>argument;
    00144         temp.y = y>>argument;
    00145
    00146         return temp;
    00147     }
    00148
    00150     template <class T>
    00151     std::ostream & operator<< (std::ostream & stream, MotionVector<T> & mv)
    00152     {
    00153         stream << mv.x << " " << mv.y;
    00154
    00155         return stream;
    00156     }
    00157
    00159     template <class T>
    00160     std::istream & operator>> (std::istream & stream, MotionVector<T> & mv)
    00161     {
    00162         stream >> mv.x;
    00163         stream >> mv.y;
    00164
    00165         return stream;
    00166     }
    00167
    00169     typedef MotionVector<int> MVector;
    00170
    00172     typedef MotionVector<int> ImageCoords;
    00173
    00175     typedef TwoDArray<MVector> MvArray;
    00176
    00178     typedef TwoDArray< MotionVector<float> > MvFloatArray;
    00179
    00181     class MvCostData
    00182     {
    00183     public:
    00185         MvCostData():
    00186         SAD(0.0),
    00187         mvcost(0.0),
    00188         total(0.0){}
    00189
    00190         void SetTotal( const float lambda ){total = SAD + lambda*mvcost;}
    00191
    00193         float SAD;
    00194
    00196         float mvcost;
    00197
    00199         float total;
    00200     };
    00201
    00202
    00204
    00208     class MvData
    00209     {
    00210     public:
    00212
    00220         MvData( const int xnumMB, int ynumMB ,
    00221                 const int xnumblocks, int ynumblocks ,  const int num_refs = 2);
    00222
    00224
    00230         MvData( const int xnumMB, int ynumMB ,  const int num_refs = 2);
    00231
    00233         ~MvData();
    00234
    00236         MvArray& Vectors(const int ref_id){return *( m_vectors[ref_id] );}
    00237
    00239         const MvArray& Vectors(const int ref_id) const {return *( m_vectors[ref_id] );}
    00240
    00242         MvArray& GlobalMotionVectors(const int ref_id){return *( m_gm_vectors[ref_id] );}
    00243
    00245         const MvArray& GlobalMotionVectors(const int ref_id) const {return *( m_gm_vectors[ref_id] );}
    00246
    00248         TwoDArray<ValueType>& DC(CompSort cs){return *( m_dc[cs] );}
    00249
    00251         const TwoDArray<ValueType>& DC(CompSort cs) const {return *( m_dc[cs] );}
    00252
    00254         const OneDArray< TwoDArray<ValueType>* >& DC() const {return m_dc;}
    00255
    00257         TwoDArray<PredMode>& Mode(){return m_modes;}
    00258
    00260         const TwoDArray<PredMode>& Mode() const {return m_modes;}
    00261
    00263         TwoDArray<int>& MBSplit(){return m_mb_split;}
    00264
    00266         const TwoDArray<int>& MBSplit() const{return m_mb_split;}
    00267
    00269         TwoDArray<bool>& MBCommonMode(){return m_mb_common;}
    00270
    00272         const TwoDArray<bool>& MBCommonMode() const{return m_mb_common;}
    00273
    00275         OneDArray<float>& GlobalMotionParameters(const int ref_id) { return *( m_gm_params[ref_id] ); }
    00276
    00278         const OneDArray<float>& GlobalMotionParameters(const int ref_id) const { return *( m_gm_params[ref_id] ); }
    00279
    00280     private:
    00281         // Initialises the arrays of data
    00282         void InitMvData();
    00283
    00284         // The motion vectors
    00285         OneDArray<MvArray*> m_vectors;
    00286
    00287         // The global motion vectors
    00288         OneDArray<MvArray*> m_gm_vectors;
    00289
    00290         // The block modes
    00291         TwoDArray<PredMode> m_modes;
    00292
    00293         // The DC values
    00294         OneDArray< TwoDArray<ValueType>* > m_dc;
    00295
    00296         // The MB split levels
    00297         TwoDArray<int> m_mb_split;
    00298
    00299         // The MB common mode indicators
    00300         TwoDArray<bool> m_mb_common;
    00301
    00302         // Global motion model parameters
    00303         OneDArray< OneDArray<float>* > m_gm_params;
    00304     };
    00305
    00307
    00312     class MEData: public MvData
    00313     {
    00314     public:
    00315
    00317
    00325         MEData( const int xnumMB, const int ynumMB ,
    00326                 const int xnumblocks, const int ynumblocks , const int num_refs = 2);
    00327
    00329
    00335         MEData( const int xnumMB, const int ynumMB , const int num_refs = 2);
    00336
    00338         ~MEData();
    00339
    00341         TwoDArray<MvCostData>& PredCosts(const int ref_id){ return *( m_pred_costs[ref_id] ); }
    00342
    00344         const TwoDArray<MvCostData>& PredCosts(const int ref_id) const { return *( m_pred_costs[ref_id] ); }
    00345
    00347         TwoDArray<float>& IntraCosts(){ return m_intra_costs; }
    00348
    00350         const TwoDArray<float>& IntraCosts() const { return m_intra_costs; }
    00351
    00353         TwoDArray<MvCostData>& BiPredCosts(){ return m_bipred_costs; }
    00354
    00356         const TwoDArray<MvCostData>& BiPredCosts() const { return m_bipred_costs; }
    00357
    00359         TwoDArray<float>& MBCosts(){ return m_MB_costs; }
    00360
    00362         const TwoDArray<float>& MBCosts() const { return m_MB_costs; }
    00363
    00365         void SetLambdaMap( const int num_refs , const float lambda );
    00366
    00368         void SetLambdaMap( const int level , const TwoDArray<float>& l_map , const float wt );
    00369
    00371         const TwoDArray<float>& LambdaMap() const { return m_lambda_map; }
    00372
    00374         TwoDArray<int>& GlobalMotionInliers(const int ref_id){ return *( m_inliers[ref_id] ); }
    00375
    00377         const TwoDArray<int>& GlobalMotionInliers(const int ref_id) const { return *( m_inliers[ref_id] ); }
    00378
    00380         friend std::ostream &operator<< (std::ostream & stream, MEData & me_data);
    00381
    00383         friend std::istream &operator>> (std::istream & stream, MEData & me_data);
    00384
    00385     private:
    00386         // Initialises the arrays of data
    00387         void InitMEData();
    00388
    00389         // Finds transitions in the motion vectors
    00390         void FindTransitions( TwoDArray<bool>& trans_map , const int ref_num );
    00391
    00392         // The costs of predicting each block, for each reference
    00393         OneDArray< TwoDArray<MvCostData>* > m_pred_costs;
    00394
    00395         // The costs of predicting each block by DC
    00396         TwoDArray<float> m_intra_costs;
    00397
    00398         // The costs of predicting each block bidirectionally
    00399         TwoDArray<MvCostData> m_bipred_costs;
    00400
    00401         // The costs for each macroblock as a whole
    00402         TwoDArray<float> m_MB_costs;
    00403
    00404         // A map of the lambda values to use
    00405         TwoDArray<float> m_lambda_map;
    00406
    00407         // Global motion inliers
    00408         OneDArray< TwoDArray<int>* > m_inliers;
    00409
    00410     };
    00411
    00412     //motion estimation and coding stuff
    00413
    00415     inline MVector MvMedian(const MVector& mv1,const MVector& mv2,const MVector& mv3) {
    00416         //takes median of each vector component
    00417         MVector tmp_mv;
    00418
    00419         tmp_mv.x=mv1.x;
    00420         tmp_mv.x+=mv2.x;
    00421         tmp_mv.x+=mv3.x;
    00422
    00423         tmp_mv.x-=std::max(std::max(mv1.x,mv2.x),mv3.x);
    00424         tmp_mv.x-=std::min(std::min(mv1.x,mv2.x),mv3.x);
    00425
    00426         tmp_mv.y=mv1.y;
    00427         tmp_mv.y+=mv2.y;
    00428         tmp_mv.y+=mv3.y;
    00429
    00430         tmp_mv.y-=std::max(std::max(mv1.y,mv2.y),mv3.y);
    00431         tmp_mv.y-=std::min(std::min(mv1.y,mv2.y),mv3.y);
    00432
    00433         return tmp_mv;
    00434     }
    00435
    00437     inline MVector MvMedian(const std::vector<MVector>& vect_list){
    00438         //more general median. Takes the median of each vector component
    00439
    00440         MVector median;
    00441         int num_vals=int(vect_list.size());
    00442         if (num_vals>0)    {
    00443             int pos=0;
    00444             std::vector<int> ordered_vals(vect_list.size());
    00445             //do x first
    00446             ordered_vals[0]=vect_list[0].x;
    00447             for (int I=1;I<num_vals;++I){
    00448                 for (int K=0;K<I;++K){
    00449                     if (vect_list[I].x<ordered_vals[K]){
    00450                         pos=K;
    00451                         break;
    00452                     }
    00453                     else
    00454                         pos=K+1;
    00455                 }//K
    00456                 if (pos==I)
    00457                     ordered_vals[I]=vect_list[I].x;
    00458                 else{
    00459                     for (int K=pos;K>=I-1;--K){
    00460                         ordered_vals[K+1]=ordered_vals[K];
    00461                     }
    00462                     ordered_vals[pos]=vect_list[I].x;
    00463                 }
    00464             }//I
    00465             if (vect_list.size()%2!=0)
    00466                 median.x=ordered_vals[(num_vals-1)/2];
    00467             else
    00468                 median.x=(ordered_vals[(num_vals/2)-1]+ordered_vals[num_vals/2])/2;
    00469
    00470             //now do y
    00471             ordered_vals[0]=vect_list[0].y;
    00472             for (int I=1;I<num_vals;++I){
    00473                 for (int K=0;K<I;++K){
    00474                     if (vect_list[I].y<ordered_vals[K]){
    00475                         pos=K;
    00476                         break;
    00477                     }
    00478                     else
    00479                         pos=K+1;
    00480                 }//K
    00481                 if (pos==I)
    00482                     ordered_vals[I]=vect_list[I].y;
    00483                 else{
    00484                     for (int K=pos;K>=I-1;--K){
    00485                         ordered_vals[K+1]=ordered_vals[K];
    00486                     }
    00487                     ordered_vals[pos]=vect_list[I].y;
    00488                 }
    00489             }//I
    00490             if (num_vals%2!=0)
    00491                 median.y=ordered_vals[(num_vals-1)/2];
    00492             else
    00493                 median.y=(ordered_vals[(num_vals/2)-1]+ordered_vals[num_vals/2])/2;
    00494
    00495         }
    00496         else{
    00497             median.x=0;
    00498             median.y=0;
    00499         }
    00500         return median;
    00501     }
    00502
    00504     inline MVector MvMean(MVector& mv1,MVector& mv2) {
    00505         //takes median of each vector component
    00506         MVector tmp_mv;
    00507
    00508         tmp_mv.x=mv1.x;
    00509         tmp_mv.x+=mv2.x;
    00510         tmp_mv.x/=2;
    00511
    00512         tmp_mv.y=mv1.y;
    00513         tmp_mv.y+=mv2.y;
    00514         tmp_mv.y/=2;
    00515
    00516         return tmp_mv;
    00517     }
    00518
    00520     inline int Norm2(const MVector& mv){//L^2 norm of a motion vector
    00521         return mv.x*mv.x+mv.y*mv.y;
    00522     }
    00523
    00525     inline int Norm1(const MVector& mv){//L^1 norm of a motion vector
    00526         return abs(mv.x)+abs(mv.y);
    00527     }
    00528
    00530     inline int GetMean(std::vector<int>& values){
    00531         int sum=0;
    00532         for (unsigned int I=0;I<values.size();++I)
    00533             sum+=values[I];
    00534         sum/=int(values.size());
    00535         return sum;
    00536     }
    00537
    00539     inline unsigned int GetMean(std::vector<unsigned int>& values){
    00540         int sum=0;
    00541         for (unsigned int I=0;I<values.size();++I)
    00542             sum+=values[I];
    00543         sum+=(values.size()>>1);
    00544         sum/=values.size();
    00545         return sum;
    00546     }
    00547
    00548 } // namespace dirac
    00549
    00550 #endif