Created by the British Broadcasting Corporation.
00001 /* ***** BEGIN LICENSE BLOCK ***** 00002 * 00003 * $Id: motion.h,v 1.14 2004/11/22 13:16:20 asuraparaju Exp $ $Name: Dirac_0_5_2 $ 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
© 2004 British Broadcasting Corporation.
Dirac code licensed under the Mozilla Public License (MPL) Version 1.1.
HTML documentation generated by Dimitri van Heesch's
excellent Doxygen tool.