xvid搜索算法

 

今天看了下xvid的搜索算法,总结一下。

xvid_me_AdvDiamondSearch,顾名思义是高级钻石搜索算法。它所使用的搜索模板是大钻石。

*

     *     *

* * *

     *     *

*

   (图1)

如图1所示,大钻石搜索模板一共有8个方向:left , right, top, down, left-top, left-down, right-top, right-down

由于图像的坐标系如图2所示:

x -->

y

|

v

(图2)

xvid中将这8个方向分加用以下数字表示

Top(4)

TL(5) TR(6 )

Left(1) Right(2)

DL(9)  DR(10)

Down(8)

而这个算法的主要思想是:

bDirection代表sad满足条件的方向,

算法在初始化时,bDirection被设为255,以确保先对left, right, top, down四个方向都进行一遍搜索。然后查看iDirection是否非零,非零则说明有更好的方向,将该方向记录到bDirection中,然后更新坐标(x,y), 再在(x,y)进行与bDirection方向正交的搜索。同样,如果搜到更好的方向,也相应更新bDirection和(x,y)。

如果*iDirection为0

那么说明已经搜索到了一个局部的最小点了。但这个点不一定是全局最小。

所以在退出之前还要在斜线方向上进行搜索(left-top, left-down, right-top, right-down)。

具体搜索哪些方向是要看情况的。

//xvid 高级钻石搜索算法

void xvid_me_AdvDiamondSearch(int x, int y, SearchData * const data,

int bDirection, CheckFunc * const CheckCandidate)

{

/* directions: 1 - left (x-1); 2 - right (x+1), 4 - up (y-1); 8 - down (y+1) */

unsigned int * const iDirection = &data->dir;

for(;;) { /* forever */

*iDirection = 0; //记录下一步要搜索的方向

if (bDirection & 1) CHECK_CANDIDATE(x - iDiamondSize, y, 1); //left

if (bDirection & 2) CHECK_CANDIDATE(x + iDiamondSize, y, 2); //right

if (bDirection & 4) CHECK_CANDIDATE(x, y - iDiamondSize, 4); //top

if (bDirection & 8) CHECK_CANDIDATE(x, y + iDiamondSize, 8); //down

/* now we're doing diagonal checks near our candidate */

if (*iDirection) { /* if anything found */

bDirection = *iDirection; //先保存一下

*iDirection = 0;    //清零以便重新搜索

x = data->currentMV->x; y = data->currentMV->y; //更新搜索坐标

//以下在新的坐标点处搜索正交方向

if (bDirection & 3) { /* our candidate is left or right */

CHECK_CANDIDATE(x, y + iDiamondSize, 8); //down

CHECK_CANDIDATE(x, y - iDiamondSize, 4); //up

} else { /* what remains here is up or down */

CHECK_CANDIDATE(x + iDiamondSize, y, 2);

CHECK_CANDIDATE(x - iDiamondSize, y, 1);

}

if (*iDirection) { //如果该方向的sad也在域值以内

bDirection += *iDirection; //添加上该方向

x = data->currentMV->x; y = data->currentMV->y;

}

} else { /* about to quit, eh? not so fast.... */

switch (bDirection) { //HKY: bDirection: the best direction

//在退出之前分别对上,下,左,右,左上,左下,右上,右下共8个方向进行搜索

case 2:

CHECK_CANDIDATE(x + iDiamondSize, y - iDiamondSize, 2 + 4);

CHECK_CANDIDATE(x + iDiamondSize, y + iDiamondSize, 2 + 8);

break;

case 1:

CHECK_CANDIDATE(x - iDiamondSize, y - iDiamondSize, 1 + 4);

CHECK_CANDIDATE(x - iDiamondSize, y + iDiamondSize, 1 + 8);

break;

case 2 + 4:

CHECK_CANDIDATE(x - iDiamondSize, y - iDiamondSize, 1 + 4);

CHECK_CANDIDATE(x + iDiamondSize, y - iDiamondSize, 2 + 4);

CHECK_CANDIDATE(x + iDiamondSize, y + iDiamondSize, 2 + 8);

break;

case 4:

CHECK_CANDIDATE(x + iDiamondSize, y - iDiamondSize, 2 + 4);

CHECK_CANDIDATE(x - iDiamondSize, y - iDiamondSize, 1 + 4);

break;

case 8:

CHECK_CANDIDATE(x + iDiamondSize, y + iDiamondSize, 2 + 8);

CHECK_CANDIDATE(x - iDiamondSize, y + iDiamondSize, 1 + 8);

break;

case 1 + 4:

CHECK_CANDIDATE(x - iDiamondSize, y + iDiamondSize, 1 + 8);

CHECK_CANDIDATE(x - iDiamondSize, y - iDiamondSize, 1 + 4);

CHECK_CANDIDATE(x + iDiamondSize, y - iDiamondSize, 2 + 4);

break;

case 2 + 8:

CHECK_CANDIDATE(x + iDiamondSize, y - iDiamondSize, 2 + 4);

CHECK_CANDIDATE(x + iDiamondSize, y + iDiamondSize, 2 + 8);

CHECK_CANDIDATE(x - iDiamondSize, y + iDiamondSize, 1 + 8);

break;

case 1 + 8:

CHECK_CANDIDATE(x - iDiamondSize, y - iDiamondSize, 1 + 4);

CHECK_CANDIDATE(x - iDiamondSize, y + iDiamondSize, 1 + 8);

CHECK_CANDIDATE(x + iDiamondSize, y + iDiamondSize, 2 + 8);

break;

default: /* 1+2+4+8 == we didn't find anything at all */

CHECK_CANDIDATE(x - iDiamondSize, y - iDiamondSize, 1 + 4);

CHECK_CANDIDATE(x - iDiamondSize, y + iDiamondSize, 1 + 8);

CHECK_CANDIDATE(x + iDiamondSize, y - iDiamondSize, 2 + 4);

CHECK_CANDIDATE(x + iDiamondSize, y + iDiamondSize, 2 + 8);

break;

}

//8个方向都没有合适的,*iDirection为零值,此时可以结束搜索

if (!*iDirection) break; /* ok, the end. really */

bDirection = *iDirection; //记录下新搜索到的方向

x = data->currentMV->x; y = data->currentMV->y; //更新下一步要搜索的坐标

}

}

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值