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
00039
00040
00041
00043
00044 #include <libdirac_motionest/me_utils.h>
00045 #include <libdirac_common/common.h>
00046 using namespace dirac;
00047
00048 #include <algorithm>
00049
00050 void BlockDiffParams::SetBlockLimits( const OLBParams& bparams ,
00051 const PicArray& pic_data ,
00052 const int xbpos , const int ybpos)
00053 {
00054 const int loc_xp = xbpos * bparams.Xbsep() - bparams.Xoffset();
00055 const int loc_yp = ybpos * bparams.Ybsep() - bparams.Yoffset();
00056
00057 m_xp=std::max( loc_xp , 0 );
00058 m_yp=std::max( loc_yp , 0 );
00059
00060 m_xl = bparams.Xblen() - m_xp + loc_xp;
00061 m_yl = bparams.Yblen() - m_yp + loc_yp;
00062
00063
00064 m_xl = ( ( m_xp + m_xl - 1) > pic_data.LastX() ) ? ( pic_data.LastX() + 1 - m_xp ): m_xl;
00065 m_yl = ( ( m_yp + m_yl - 1) > pic_data.LastY() ) ? ( pic_data.LastY() + 1 - m_yp ) : m_yl;
00066
00067 }
00068
00069
00070
00071
00072
00073 BlockDiff::BlockDiff(const PicArray& ref,const PicArray& pic) :
00074 pic_data( pic ),
00075 ref_data( ref )
00076 {}
00077
00078 SimpleBlockDiff::SimpleBlockDiff( const PicArray& ref , const PicArray& pic ) :
00079 BlockDiff( ref , pic )
00080 {}
00081
00082 BChkBlockDiff::BChkBlockDiff( const PicArray& ref , const PicArray& pic ) :
00083 BlockDiff( ref , pic )
00084 {}
00085
00086 IntraBlockDiff::IntraBlockDiff( const PicArray& pic ) :
00087 pic_data( pic )
00088 {}
00089
00090 BiBlockDiff::BiBlockDiff( const PicArray& ref1 , const PicArray& ref2 ,
00091 const PicArray& pic) :
00092 pic_data( pic ),
00093 ref_data1( ref1 ),
00094 ref_data2( ref2 )
00095 {}
00096
00097 BiSimpleBlockDiff::BiSimpleBlockDiff( const PicArray& ref1 , const PicArray& ref2 ,
00098 const PicArray& pic) :
00099 BiBlockDiff(ref1 , ref2 , pic)
00100 {}
00101
00102 BiBChkBlockDiff::BiBChkBlockDiff( const PicArray& ref1 , const PicArray& ref2 ,
00103 const PicArray& pic ) :
00104 BiBlockDiff(ref1 , ref2 , pic)
00105 {}
00106
00107 BlockDiffUp::BlockDiffUp( const PicArray& ref , const PicArray& pic):
00108 BlockDiff( ref , pic )
00109 {}
00110
00111 SimpleBlockDiffUp::SimpleBlockDiffUp( const PicArray& ref , const PicArray& pic ) :
00112 BlockDiffUp( ref , pic )
00113 {}
00114
00115 BChkBlockDiffUp::BChkBlockDiffUp(const PicArray& ref,const PicArray& pic) :
00116 BlockDiffUp( ref , pic )
00117 {}
00118
00119 BiBlockDiffUp::BiBlockDiffUp( const PicArray& ref1 , const PicArray& ref2 ,
00120 const PicArray& pic) :
00121 BiBlockDiff( ref1 , ref2 , pic )
00122 {}
00123
00124 BiSimpleBlockDiffUp::BiSimpleBlockDiffUp( const PicArray& ref1 , const PicArray& ref2 ,
00125 const PicArray& pic ):
00126 BiBlockDiffUp( ref1 , ref2 , pic)
00127 {}
00128
00129 BiBChkBlockDiffUp::BiBChkBlockDiffUp( const PicArray& ref1 , const PicArray& ref2 ,
00130 const PicArray& pic ) :
00131 BiBlockDiffUp( ref1 , ref2 , pic)
00132 {}
00133
00134
00135
00136 float SimpleBlockDiff::Diff( const BlockDiffParams& dparams, const MVector& mv )
00137 {
00138
00139 ValueType diff;
00140
00141 CalcValueType sum( 0 );
00142
00143 for (int j=dparams.Yp() ; j != dparams.Yp()+dparams.Yl() ; ++j )
00144 {
00145 for(int i=dparams.Xp() ; i!= dparams.Xp()+dparams.Xl() ; ++i )
00146 {
00147 diff = pic_data[j][i]-ref_data[j+mv.y][i+mv.x];
00148 sum += std::abs( diff );
00149 }
00150 }
00151
00152 return static_cast<float>( sum );
00153 }
00154
00155 float BChkBlockDiff::Diff( const BlockDiffParams& dparams, const MVector& mv )
00156 {
00157
00158 const int xmax = ref_data.LengthX();
00159 const int ymax = ref_data.LengthY();
00160
00161 ValueType diff;
00162
00163 CalcValueType sum( 0 );
00164
00165 for ( int j=dparams.Yp() ; j!=dparams.Yp()+dparams.Yl() ; ++j )
00166 {
00167 for( int i=dparams.Xp() ; i!=dparams.Xp()+dparams.Xl() ; ++i )
00168 {
00169 diff = pic_data[j][i] - ref_data[BChk(j+mv.y , ymax)][BChk(i+mv.x , xmax)];
00170 sum += std::abs( diff );
00171
00172 }
00173 }
00174
00175 return static_cast<float>( sum );
00176 }
00177
00178 float IntraBlockDiff::Diff( const BlockDiffParams& dparams , ValueType& dc_val )
00179 {
00180
00181
00182
00183 CalcValueType int_dc( 0 );
00184
00185 for ( int j=dparams.Yp() ; j!=dparams.Yp()+dparams.Yl() ; ++j)
00186 for(int i=dparams.Xp(); i!=dparams.Xp()+dparams.Xl() ; ++i )
00187 int_dc += static_cast<int>( pic_data[j][i] );
00188
00189 int_dc /= ( dparams.Xl() * dparams.Yl() );
00190
00191
00192 dc_val = static_cast<ValueType>( (int_dc+2)>>2 );
00193
00194
00195 ValueType dc( dc_val<<2 );
00196 CalcValueType intra_cost( 0 );
00197
00198 for (int j=dparams.Yp(); j!=dparams.Yp()+dparams.Yl() ; ++j)
00199 for( int i=dparams.Xp() ; i!=dparams.Xp()+dparams.Xl() ;++i )
00200 intra_cost += std::abs( pic_data[j][i] - dc );
00201
00202 return static_cast<float>( intra_cost );
00203 }
00204
00205 float BiSimpleBlockDiff::Diff( const BlockDiffParams& dparams, const MVector& mv1,const MVector& mv2){
00206
00207 CalcValueType sum( 0 );
00208
00209 ValueType diff;
00210
00211 for ( int j=dparams.Yp(); j!=dparams.Yp()+dparams.Yl(); ++j )
00212 {
00213 for( int i=dparams.Xp() ; i!=dparams.Xp()+dparams.Xl() ; ++i )
00214 {
00215 diff = pic_data[j][i]-( ( ref_data1[j+mv1.y][i+mv1.x] + 1 )>>1 );
00216 diff -= ( ( ref_data2[j+mv2.y][i+mv2.x] + 1 )>>1 );
00217
00218 sum += std::abs( diff );
00219 }
00220 }
00221
00222 return static_cast<float>( sum );
00223 }
00224
00225 float BiBChkBlockDiff::Diff( const BlockDiffParams& dparams, const MVector& mv1,const MVector& mv2){
00226
00227 ValueType diff;
00228 const int xmax1 = ref_data1.LengthX();
00229 const int ymax1 = ref_data1.LengthY();
00230
00231 const int xmax2 = ref_data2.LengthX();
00232 const int ymax2 = ref_data2.LengthY();
00233
00234 CalcValueType sum( 0 );
00235
00236 for ( int j=dparams.Yp() ; j!=dparams.Yp() + dparams.Yl() ; ++j )
00237 {
00238 for( int i=dparams.Xp() ; i!=dparams.Xp() + dparams.Xl() ; ++i )
00239 {
00240 diff = pic_data[j][i]-( ( ref_data1[BChk(j+mv1.y , ymax1)][BChk(i+mv1.x , xmax1)] + 1 )>>1 );
00241 diff -= ( ( ref_data2[BChk(j+mv2.y , ymax2)][BChk(i+mv2.x , xmax2)] + 1 )>>1 );
00242
00243 sum += std::abs( diff );
00244 }
00245 }
00246
00247 return static_cast<float>( sum );
00248 }
00249
00250 float SimpleBlockDiffUp::Diff( const BlockDiffParams& dparams, const MVector& mv )
00251 {
00252
00253
00254 const ImageCoords StartPos(dparams.Xp(),dparams.Yp());
00255 const ImageCoords EndPos(StartPos.x+dparams.Xl(),StartPos.y+dparams.Yl());
00256
00257
00258
00259 const MVector roundvec(mv.x>>2,mv.y>>2);
00260
00261
00262 const MVector rmdr(mv.x-(roundvec.x<<2),mv.y-(roundvec.y<<2));
00263
00264
00265 const ImageCoords RefStart((StartPos.x<<1) + roundvec.x,(StartPos.y<<1) + roundvec.y);
00266
00267
00268
00269
00270 const ValueType TLweight((4-rmdr.x)*(4-rmdr.y));
00271 const ValueType TRweight(rmdr.x*(4-rmdr.y));
00272 const ValueType BLweight((4-rmdr.x)*rmdr.y);
00273 const ValueType BRweight(rmdr.x*rmdr.y);
00274
00275 CalcValueType sum( 0 );
00276
00277 ValueType temp;
00278
00279 for(int c = StartPos.y, uY = RefStart.y; c < EndPos.y; ++c, uY += 2){
00280 for(int l = StartPos.x, uX = RefStart.x; l < EndPos.x; ++l, uX += 2){
00281 temp = (
00282 TLweight * ref_data[uY][uX] +
00283 TRweight * ref_data[uY][uX+1] +
00284 BLweight * ref_data[uY+1][uX] +
00285 BRweight * ref_data[uY+1][uX+1] +
00286 8
00287 )>>4;
00288
00289 sum += std::abs( pic_data[c][l] - temp );
00290 }
00291 }
00292
00293 return static_cast<float>( sum );
00294 }
00295
00296 float BChkBlockDiffUp::Diff( const BlockDiffParams& dparams, const MVector& mv )
00297 {
00298
00299
00300 const int DoubleXdim=ref_data.LengthX();
00301 const int DoubleYdim=ref_data.LengthY();
00302
00303
00304 const ImageCoords StartPos(dparams.Xp(),dparams.Yp());
00305 const ImageCoords EndPos(StartPos.x+dparams.Xl(),StartPos.y+dparams.Yl());
00306
00307
00308
00309 const MVector roundvec(mv.x>>2,mv.y>>2);
00310
00311
00312 const MVector rmdr(mv.x-(roundvec.x<<2),mv.y-(roundvec.y<<2));
00313
00314
00315 const ImageCoords RefStart((StartPos.x<<1) + roundvec.x,(StartPos.y<<1) + roundvec.y);
00316
00317
00318
00319
00320 const ValueType TLweight((4-rmdr.x)*(4-rmdr.y));
00321 const ValueType TRweight(rmdr.x*(4-rmdr.y));
00322 const ValueType BLweight((4-rmdr.x)*rmdr.y);
00323 const ValueType BRweight(rmdr.x*rmdr.y);
00324
00325 CalcValueType sum( 0 );
00326
00327 ValueType temp;
00328
00329 for(int c = StartPos.y, uY = RefStart.y; c < EndPos.y; ++c, uY += 2)
00330 {
00331 for(int l = StartPos.x, uX = RefStart.x; l < EndPos.x; ++l, uX += 2)
00332 {
00333 temp = (
00334 TLweight * ref_data[BChk(uY,DoubleYdim)][BChk(uX,DoubleXdim)] +
00335 TRweight * ref_data[BChk(uY,DoubleYdim)][BChk(uX+1,DoubleXdim)] +
00336 BLweight * ref_data[BChk(uY+1,DoubleYdim)][BChk(uX,DoubleXdim)] +
00337 BRweight * ref_data[BChk(uY+1,DoubleYdim)][BChk(uX+1,DoubleXdim)] +
00338 8
00339 )>>4;
00340
00341 sum += ( std::abs( pic_data[c][l] - temp ) );
00342 }
00343 }
00344
00345 return static_cast<float>( sum );
00346
00347 }
00348
00349 float BiSimpleBlockDiffUp::Diff( const BlockDiffParams& dparams, const MVector& mv1, const MVector& mv2){
00350
00351
00352 const ImageCoords StartPos(dparams.Xp(),dparams.Yp());
00353 const ImageCoords EndPos(StartPos.x+dparams.Xl(),StartPos.y+dparams.Yl());
00354
00355
00356 const MVector roundvec1(mv1.x>>2,mv1.y>>2);
00357 const MVector roundvec2(mv2.x>>2,mv2.y>>2);
00358
00359
00360 const MVector rmdr1(mv1.x-(roundvec1.x<<2),mv1.y-(roundvec1.y<<2));
00361 const MVector rmdr2(mv2.x-(roundvec2.x<<2),mv2.y-(roundvec2.y<<2));
00362
00363
00364 const ImageCoords RefStart1((StartPos.x<<1) + roundvec1.x,(StartPos.y<<1) + roundvec1.y);
00365 const ImageCoords RefStart2((StartPos.x<<1) + roundvec2.x,(StartPos.y<<1) + roundvec2.y);
00366
00367
00368 const ValueType TLweight1((4-rmdr1.x)*(4-rmdr1.y));
00369 const ValueType TRweight1(rmdr1.x*(4-rmdr1.y));
00370 const ValueType BLweight1((4-rmdr1.x)*rmdr1.y);
00371 const ValueType BRweight1(rmdr1.x*rmdr1.y);
00372
00373 const ValueType TLweight2((4-rmdr2.x)*(4-rmdr2.y));
00374 const ValueType TRweight2(rmdr2.x*(4-rmdr2.y));
00375 const ValueType BLweight2((4-rmdr2.x)*rmdr2.y);
00376 const ValueType BRweight2(rmdr2.x*rmdr2.y);
00377
00378 CalcValueType temp;
00379
00380 CalcValueType sum( 0 );
00381
00382 for(int c = StartPos.y, uY1 = RefStart1.y,uY2=RefStart2.y; c < EndPos.y; ++c, uY1 += 2,uY2 += 2){
00383 for(int l = StartPos.x, uX1 = RefStart1.x,uX2=RefStart2.x; l < EndPos.x; ++l, uX1 += 2, uX2 += 2){
00384 temp = (
00385 TLweight1 * ref_data1[uY1][uX1] +
00386 TRweight1 * ref_data1[uY1][uX1+1] +
00387 BLweight1 * ref_data1[uY1+1][uX1] +
00388 BRweight1 * ref_data1[uY1+1][uX1+1] +
00389 16
00390 )>>5;
00391
00392 temp += (
00393 TLweight2 * ref_data2[uY2][uX2] +
00394 TRweight2 * ref_data2[uY2][uX2+1] +
00395 BLweight2 * ref_data2[uY2+1][uX2] +
00396 BRweight2 * ref_data2[uY2+1][uX2+1] +
00397 16
00398 )>>5;
00399
00400 sum += std::abs( pic_data[c][l] - temp );
00401 }
00402 }
00403
00404 return static_cast<float>( sum );
00405 }
00406
00407 float BiBChkBlockDiffUp::Diff( const BlockDiffParams& dparams, const MVector& mv1, const MVector& mv2)
00408 {
00409
00410
00411 const int xmax1 = ref_data1.LengthX();
00412 const int ymax1 = ref_data1.LengthY();
00413 const int xmax2 = ref_data2.LengthX();
00414 const int ymax2 = ref_data2.LengthY();
00415
00416
00417 const ImageCoords StartPos(dparams.Xp(),dparams.Yp());
00418 const ImageCoords EndPos(StartPos.x+dparams.Xl(),StartPos.y+dparams.Yl());
00419
00420
00421 const MVector roundvec1(mv1.x>>2,mv1.y>>2);
00422 const MVector roundvec2(mv2.x>>2,mv2.y>>2);
00423
00424
00425 const MVector rmdr1(mv1.x-(roundvec1.x<<2),mv1.y-(roundvec1.y<<2));
00426 const MVector rmdr2(mv2.x-(roundvec2.x<<2),mv2.y-(roundvec2.y<<2));
00427
00428
00429 const ImageCoords RefStart1((StartPos.x<<1) + roundvec1.x,(StartPos.y<<1) + roundvec1.y);
00430 const ImageCoords RefStart2((StartPos.x<<1) + roundvec2.x,(StartPos.y<<1) + roundvec2.y);
00431
00432
00433 const ValueType TLweight1((4-rmdr1.x)*(4-rmdr1.y));
00434 const ValueType TRweight1(rmdr1.x*(4-rmdr1.y));
00435 const ValueType BLweight1((4-rmdr1.x)*rmdr1.y);
00436 const ValueType BRweight1(rmdr1.x*rmdr1.y);
00437
00438 const ValueType TLweight2((4-rmdr2.x)*(4-rmdr2.y));
00439 const ValueType TRweight2(rmdr2.x*(4-rmdr2.y));
00440 const ValueType BLweight2((4-rmdr2.x)*rmdr2.y);
00441 const ValueType BRweight2(rmdr2.x*rmdr2.y);
00442
00443 CalcValueType temp;
00444
00445 CalcValueType sum( 0 );
00446
00447 for(int c = StartPos.y, uY1 = RefStart1.y,uY2=RefStart2.y; c < EndPos.y; ++c, uY1 += 2,uY2 += 2)
00448 {
00449 for(int l = StartPos.x, uX1 = RefStart1.x,uX2=RefStart2.x; l < EndPos.x; ++l, uX1 += 2, uX2 += 2)
00450 {
00451 temp = (
00452 TLweight1 * ref_data1[BChk(uY1,ymax1)][BChk(uX1,xmax1)] +
00453 TRweight1 * ref_data1[BChk(uY1,ymax1)][BChk(uX1+1,xmax1)] +
00454 BLweight1 * ref_data1[BChk(uY1+1,ymax1)][BChk(uX1,xmax1)] +
00455 BRweight1 * ref_data1[BChk(uY1+1,ymax1)][BChk(uX1+1,xmax1)] +
00456 16)>>5;
00457
00458 temp += (
00459 TLweight2 * ref_data2[BChk(uY2,ymax2)][BChk(uX2,xmax2)] +
00460 TRweight2 * ref_data2[BChk(uY2,ymax2)][BChk(uX2+1,xmax2)] +
00461 BLweight2 * ref_data2[BChk(uY2+1,ymax2)][BChk(uX2,xmax2)] +
00462 BRweight2 * ref_data2[BChk(uY2+1,ymax2)][BChk(uX2+1,xmax2)]+
00463 16)>>5;
00464
00465 sum += std::abs( pic_data[c][l] - temp );
00466 }
00467 }
00468
00469 return static_cast<float>( sum );
00470 }