00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include <libdirac_common/common.h>
00039 #include <algorithm>
00040 #ifndef _MOTION_H
00041 #define _MOTION_H
00042
00043 namespace dirac
00044 {
00046
00048
00049
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
00282 void InitMvData();
00283
00284
00285 OneDArray<MvArray*> m_vectors;
00286
00287
00288 OneDArray<MvArray*> m_gm_vectors;
00289
00290
00291 TwoDArray<PredMode> m_modes;
00292
00293
00294 OneDArray< TwoDArray<ValueType>* > m_dc;
00295
00296
00297 TwoDArray<int> m_mb_split;
00298
00299
00300 TwoDArray<bool> m_mb_common;
00301
00302
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
00387 void InitMEData();
00388
00389
00390 void FindTransitions( TwoDArray<bool>& trans_map , const int ref_num );
00391
00392
00393 OneDArray< TwoDArray<MvCostData>* > m_pred_costs;
00394
00395
00396 TwoDArray<float> m_intra_costs;
00397
00398
00399 TwoDArray<MvCostData> m_bipred_costs;
00400
00401
00402 TwoDArray<float> m_MB_costs;
00403
00404
00405 TwoDArray<float> m_lambda_map;
00406
00407
00408 OneDArray< TwoDArray<int>* > m_inliers;
00409
00410 };
00411
00412
00413
00415 inline MVector MvMedian(const MVector& mv1,const MVector& mv2,const MVector& mv3) {
00416
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
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
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 }
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 }
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
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 }
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 }
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
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){
00521 return mv.x*mv.x+mv.y*mv.y;
00522 }
00523
00525 inline int Norm1(const MVector& mv){
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 }
00549
00550 #endif