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_motionest/block_match.h>
00039 #include <libdirac_motionest/me_utils.h>
00040 using namespace dirac;
00041
00042 #include <cmath>
00043 using std::vector;
00044
00045 namespace dirac
00046 {
00047
00048 ValueType GetVar( const MVector& predmv , const MVector& mv )
00049 {
00050 MVector diff;
00051 diff.x = mv.x-predmv.x;
00052 diff.y = mv.y-predmv.y;
00053
00054 return std::max( Norm1( diff ) , 48 );
00055 }
00056
00057 ValueType GetVar( const std::vector<MVector>& pred_list , const MVector& mv)
00058 {
00059 ValueType sum=0;
00060 MVector diff;
00061 for (size_t i=0 ; i<pred_list.size() ; ++i)
00062 {
00063 diff.x = mv.x - pred_list[i].x;
00064 diff.y = mv.y - pred_list[i].y;
00065 sum += Norm1( diff );
00066 }
00067
00068 return sum;
00069 }
00070
00071 void AddNewVlist( CandidateList& vect_list, const MVector& mv, const int xr , const int yr , const int step )
00072 {
00073
00074
00075 vector<MVector> tmp_list;
00076 vect_list.push_back(tmp_list);
00077 int list_num=vect_list.size()-1;
00078
00079 MVector tmp_mv( mv );
00080 AddVect(vect_list , tmp_mv , list_num );
00081
00082 for ( int i=1 ; i<=xr ; ++i )
00083 {
00084 tmp_mv.x = mv.x + i*step;
00085 AddVect( vect_list , tmp_mv , list_num );
00086
00087 tmp_mv.x = mv.x - i*step;
00088 AddVect( vect_list , tmp_mv , list_num );
00089 }
00090
00091 for ( int j=1 ; j<=yr ; ++j)
00092 {
00093 for ( int i=-xr ; i<=xr ; ++i)
00094 {
00095 tmp_mv.x = mv.x + i*step;
00096 tmp_mv.y = mv.y + j*step;
00097 AddVect(vect_list,tmp_mv,list_num);
00098
00099 tmp_mv.y = mv.y -j*step;
00100 AddVect(vect_list,tmp_mv,list_num);
00101
00102 }
00103 }
00104
00105
00106
00107 if ( vect_list[list_num].size() == 0 )
00108 vect_list.erase( vect_list.begin() + list_num );
00109 }
00110
00111 void AddNewVlist( CandidateList& vect_list , const MVector& mv , const int xr , const int yr)
00112 {
00113
00114
00115 vector<MVector> tmp_list;
00116 vect_list.push_back(tmp_list);
00117 int list_num=vect_list.size()-1;
00118
00119 MVector tmp_mv(mv);
00120 AddVect(vect_list,tmp_mv,list_num);
00121
00122 for ( int i=1 ; i<=xr ; ++i)
00123 {
00124 tmp_mv.x = mv.x + i;
00125 AddVect( vect_list , tmp_mv , list_num );
00126
00127 tmp_mv.x = mv.x - i;
00128 AddVect( vect_list , tmp_mv , list_num );
00129 }
00130
00131 for ( int j=1 ; j<=yr ; ++j)
00132 {
00133 for ( int i=-xr ; i<=xr ; ++i)
00134 {
00135 tmp_mv.x = mv.x + i;
00136 tmp_mv.y = mv.y + j;
00137 AddVect( vect_list , tmp_mv , list_num );
00138
00139 tmp_mv.y = mv.y-j;
00140 AddVect( vect_list , tmp_mv , list_num );
00141 }
00142 }
00143
00144
00145
00146 if ( vect_list[list_num].size() == 0 )
00147 vect_list.erase( vect_list.begin() + list_num );
00148 }
00149
00150 void AddNewVlistD( CandidateList& vect_list , const MVector& mv , const int xr , const int yr )
00151 {
00152
00153
00154 vector<MVector> tmp_list;
00155 vect_list.push_back( tmp_list );
00156
00157 int list_num=vect_list.size()-1;
00158 int xlim;
00159
00160 MVector tmp_mv( mv );
00161 AddVect( vect_list , tmp_mv , list_num );
00162
00163 for ( int i=1 ; i<=xr ; ++i)
00164 {
00165 tmp_mv.x = mv.x + i;
00166 AddVect( vect_list , tmp_mv , list_num );
00167
00168 tmp_mv.x = mv.x - i;
00169 AddVect( vect_list , tmp_mv , list_num );
00170 }
00171
00172 for ( int j=1 ; j<=yr ; ++j)
00173 {
00174 xlim = xr * (yr-std::abs(j)) / yr;
00175 for ( int i=-xlim ; i<=xlim ; ++i)
00176 {
00177 tmp_mv.x = mv.x + i;
00178 tmp_mv.y = mv.y + j;
00179 AddVect( vect_list , tmp_mv , list_num );
00180
00181 tmp_mv.y = mv.y - j;
00182 AddVect( vect_list , tmp_mv , list_num );
00183 }
00184 }
00185
00186
00187
00188 if ( vect_list[list_num].size() == 0 )
00189 vect_list.erase( vect_list.begin() + list_num );
00190 }
00191
00192 void AddVect(CandidateList& vect_list,const MVector& mv,int list_num)
00193 {
00194
00195 bool is_in_list=false;
00196
00197 size_t lnum=0;
00198 size_t i;
00199
00200 while( !is_in_list && lnum<vect_list.size() )
00201 {
00202 i=0;
00203 while( !is_in_list && i<vect_list[lnum].size())
00204 {
00205 if ( vect_list[lnum][i].x == mv.x && vect_list[lnum][i].y == mv.y )
00206 is_in_list=true;
00207 ++i;
00208 }
00209 ++lnum;
00210 }
00211
00212 if ( !is_in_list )
00213 vect_list[list_num].push_back(mv);
00214
00215 }
00216
00217 BlockMatcher::BlockMatcher( const PicArray& pic_data , const PicArray& ref_data , const OLBParams& bparams ,
00218 const MvArray& mv_array , const TwoDArray< MvCostData >& cost_array):
00219 m_pic_data(pic_data),
00220 m_ref_data(ref_data),
00221 m_mv_array(mv_array),
00222 m_cost_array(cost_array),
00223 m_simplediff( ref_data , pic_data ),
00224 m_checkdiff( ref_data , pic_data ),
00225 m_simplediffup( ref_data , pic_data ),
00226 m_checkdiffup( ref_data , pic_data ),
00227 m_bparams(bparams)
00228 {}
00229
00230 void BlockMatcher::FindBestMatch(int xpos , int ypos ,
00231 const CandidateList& cand_list,
00232 const MVector& mv_prediction,
00233 float lambda)
00234 {
00235 BlockDiffParams dparams;
00236 dparams.SetBlockLimits( m_bparams , m_pic_data , xpos , ypos);
00237 lambda /= m_bparams.Xblen()*m_bparams.Yblen();
00238 lambda *= dparams.Xl()*dparams.Yl();
00239
00240
00241 BlockDiff* mydiff;
00242
00243
00245
00246
00247 vector<int> list_nums;
00248
00249
00250 OneDArray<float> list_costs( cand_list.size() );
00251
00252
00253 float min_cost;
00254
00255
00256
00257 MvCostData best_costs;
00258
00259 best_costs.total=100000000.0f;
00260 MVector best_mv( cand_list[0][0] );
00261
00262 MVector cand_mv;
00263 MvCostData cand_costs;
00264
00265 for (size_t lnum=0 ; lnum<cand_list.size() ; ++lnum )
00266 {
00267
00268 cand_mv = cand_list[lnum][0];
00269 cand_costs.mvcost = GetVar( mv_prediction , cand_mv );
00270
00271
00272 if (( dparams.Xp()+cand_mv.x )<0 || ( dparams.Xp()+dparams.Xl()+cand_mv.x) >= m_ref_data.LengthX() ||
00273 (dparams.Yp()+cand_mv.y)<0 || (dparams.Yp()+dparams.Yl()+cand_mv.y) >= m_ref_data.LengthY() )
00274 mydiff = &m_checkdiff;
00275 else
00276 mydiff = &m_simplediff;
00277
00278 cand_costs.SAD = mydiff->Diff( dparams , cand_mv );
00279 cand_costs.SetTotal( lambda );
00280
00281 if ( cand_costs.total < best_costs.total)
00282 {
00283 best_costs = cand_costs;
00284 best_mv = cand_mv ;
00285
00286 }
00287
00288 list_costs[lnum] = cand_costs.total;
00289
00290 }
00291
00292
00293
00295
00296 min_cost = list_costs[0];
00297
00298 for ( int lnum=1 ; lnum<list_costs.Length() ; ++lnum)
00299 {
00300 if ( list_costs[lnum]<min_cost )
00301 min_cost = list_costs[lnum];
00302 }
00303
00304 for ( int lnum=0 ; lnum<list_costs.Length() ; ++lnum)
00305 {
00306
00307 if ( list_costs[lnum] < 1.5*min_cost )
00308 list_nums.push_back( lnum );
00309 }
00310
00311
00312
00314 int list_num;
00315
00316 for ( size_t num=0 ; num<list_nums.size() ; ++num)
00317 {
00318 list_num = list_nums[num];
00319
00320 for (size_t i=1 ; i<cand_list[list_num].size() ; ++i)
00321 {
00322
00323 cand_mv = cand_list[list_num][i];
00324 cand_costs.mvcost = GetVar( mv_prediction , cand_mv);
00325
00326 if ((dparams.Xp()+cand_mv.x)<0 || (dparams.Xp()+dparams.Xl()+cand_mv.x) > m_ref_data.LengthX() ||
00327 (dparams.Yp()+cand_mv.y)<0 || (dparams.Yp()+dparams.Yl()+cand_mv.y) > m_ref_data.LengthY() )
00328 mydiff = &m_checkdiff;
00329 else
00330 mydiff = &m_simplediff;
00331
00332 cand_costs.SAD = mydiff->Diff( dparams , cand_mv );
00333 cand_costs.SetTotal( lambda );
00334
00335 if ( cand_costs.total < best_costs.total)
00336 {
00337 best_costs = cand_costs;
00338 best_mv = cand_mv;
00339
00340 }
00341 }
00342 }
00343
00344
00346
00347 m_mv_array[ypos][xpos] = best_mv;
00348 m_cost_array[ypos][xpos] = best_costs;
00349 }
00350
00351
00352
00353
00354 void BlockMatcher::FindBestMatchSubp(int xpos, int ypos,
00355 const CandidateList& cand_list,
00356 const MVector& mv_prediction,
00357 float lambda)
00358 {
00359
00360 BlockDiffParams dparams;
00361 dparams.SetBlockLimits( m_bparams , m_pic_data , xpos , ypos);
00362
00363
00364 BlockDiff* mydiff;
00365
00366
00368
00369
00370 vector<int> list_nums;
00371
00372
00373 OneDArray<float> list_costs( cand_list.size() );
00374
00375
00376 float min_cost;
00377
00378
00379 MvCostData best_costs( m_cost_array[ypos][xpos] );
00380 MVector best_mv( m_mv_array[ypos][xpos] );
00381
00382 MvCostData cand_costs;
00383 MVector cand_mv;
00384
00385 for (size_t list_num=0 ; list_num<cand_list.size() ; ++list_num )
00386 {
00387
00388 cand_mv = cand_list[list_num][0];
00389 cand_costs.mvcost = GetVar( mv_prediction , cand_mv );
00390
00391
00392 if ( (( dparams.Xp()<<1 )+(cand_mv.x>>2))<0
00393 || ((( dparams.Xp()+dparams.Xl() )<<1)+(cand_mv.x>>2)) >= m_ref_data.LengthX()
00394 || (( dparams.Yp()<<1)+(cand_mv.y>>2))<0
00395 || (((dparams.Yp()+dparams.Yl())<<1)+(cand_mv.y>>2)) >= m_ref_data.LengthY() )
00396 mydiff = &m_checkdiffup;
00397 else
00398 mydiff = &m_simplediffup;
00399
00400 cand_costs.SAD = mydiff->Diff( dparams , cand_mv );
00401 cand_costs.SetTotal( lambda );
00402
00403 if (cand_costs.total< best_costs.total)
00404 {
00405 best_costs = cand_costs;
00406 best_mv = cand_mv;
00407 }
00408
00409 list_costs[list_num] = cand_costs.total;
00410 }
00411
00412
00413
00415
00416 min_cost = list_costs[0];
00417
00418 for ( int lnum=1 ; lnum<list_costs.Length() ; ++lnum)
00419 {
00420 if ( list_costs[lnum]<min_cost )
00421 min_cost = list_costs[lnum];
00422 }
00423
00424 for ( int lnum=0 ; lnum<list_costs.Length() ; ++lnum )
00425 {
00426
00427 if ( list_costs[lnum] < 1.5*min_cost )
00428 list_nums.push_back( lnum );
00429 }
00430
00431
00433 int list_num;
00434
00435 for ( size_t num=0 ; num<list_nums.size() ; ++num)
00436 {
00437 list_num = list_nums[num];
00438
00439 for (size_t i=1 ; i<cand_list[list_num].size() ; ++i)
00440 {
00441
00442 cand_mv = cand_list[list_num][i];
00443 cand_costs.mvcost = GetVar( mv_prediction , cand_mv );
00444
00445 if ( (( dparams.Xp()<<1 )+( cand_mv.x>>2 ))<0
00446 || ((( dparams.Xp()+dparams.Xl() )<<1)+( cand_mv.x>>2 )) >= m_ref_data.LengthX()
00447 || (( dparams.Yp()<<1 )+( cand_mv.y>>2 ))<0
00448 || ((( dparams.Yp()+dparams.Yl() )<<1)+(cand_mv.y>>2)) >= m_ref_data.LengthY() )
00449 mydiff = &m_checkdiffup;
00450 else
00451 mydiff = &m_simplediffup;
00452
00453 cand_costs.SAD = mydiff->Diff( dparams , cand_mv );
00454 cand_costs.SetTotal( lambda );
00455
00456 if (cand_costs.total< best_costs.total)
00457 {
00458 best_costs = cand_costs;
00459 best_mv = cand_mv;
00460 }
00461
00462 }
00463 }
00464
00465
00467
00468 m_mv_array[ypos][xpos] = best_mv;
00469 m_cost_array[ypos][xpos] = best_costs;
00470
00471 }
00472 }