hadamard变换

Hadamard变换是一种正交变换,其性质包括矩阵元素为1/-1,正交且对称。变换具有奇偶对称性,并满足Paserval定理。相比余弦变换,Hadamard变换仅涉及加减运算,易于递归快速实现,且正反变换形式相同,算法实现简便。此外,它有递推公式,计算过程简单,尤其在求SATD时,与余弦变换效果接近但计算更快。因此,Hadamard变换在简化计算和保持效果方面表现出色。
性质
  1. 矩阵元素都为1/-1
  2. 正交矩阵、对称矩阵。hadamard变换为正交变换
  3. 奇数行/列偶对称,偶数行/列奇对称
  4. 满足Paserval定理
优点
  1. 仅含有加减运算,可用递归快速实现。(比余弦变换简单了太多了)
  2. 正变换和反变换具有相同形式,算法实现起来简单(变换是HXH)
  3. 具有递推公式,算法实现简单(体验一下实际代码就能发现,真的很简单易计算,而且不用浮点数运算)
  4. hadamard变换后求SATD和余弦变换后求SATD,结果差距不大,但是如果直接残差不变换求SAD,就和余弦变换后求SATD差距很大。所以,他和余弦变换有相似效果,但是算的快又简单
// 函数功能是计算8×8块的哈达玛变换,并计算其SAD值,m2[8][8]存放最终的变换结果
Int xCalcHADs8x8_ISlice(Pel *piOrg, Int iStrideOrg)
{
  Int k, i, j, jj;
  Int diff[64], m1[8][8], m2[8][8], m3[8][8], iSumHad = 0;

  for( k = 0; k < 64; k += 8 )
  {
    diff[k+0] = piOrg[0] ;
    diff[k+1] = piOrg[1] ;
    diff[k+2] = piOrg[2] ;
    diff[k+3] = piOrg[3] ;
    diff[k+4] = piOrg[4] ;
    diff[k+5] = piOrg[5] ;
    diff[k+6] = piOrg[6] ;
    diff[k+7] = piOrg[7] ;

    piOrg += iStrideOrg;
    //piOrg每次增加一行的偏移
  }

  //horizontal
  for (j=0; j < 8; j++)
  {
    jj = j << 3;//每次+8
    m2[j][0] = diff[jj  ] + diff[jj+4];
    m2[j][1] = diff[jj+1] + diff[jj+5];
    m2[j][2] = diff[jj+2] + diff[jj+6];
    m2[j][3] = diff[jj+3] + diff[jj+7];
    m2[j][4] = diff[jj  ] - diff[jj+4];
    m2[j][5] = diff[jj+1] - diff[jj+5];
    m2[j][6] = diff[jj+2] - diff[jj+6];
    m2[j][7] = diff[jj+3] - diff[jj+7];
    /*
    m2=diff*Backstep_matrix
    the derivation of Backstep_matrix 
    H0=[1]
    H1=[1  1
        1 -1]

      / 0/ 1/  2/ 3/          / 0/ 1/  2/ 3/            / 0/ 1/  2/ 3/
    /0/ 1/ 1/* 1/ 1/       /0/ 1/ 0/* 1/ 0/           /0/ H1  /* 0   /
    /1/ 1/-1/* 1/-1/       /1/ 0/ 1/* 0/ 1/           /1/     /*     /
     * * * * * * * *     = * * * * * * * *     *      * * * * * * * * 
    /2/ 1/ 1/*-1/-1/       /2/ 1/ 0/*-1/ 0/           /2/ 0   /* H1  /
    /3/ 1/-1/*-1/ 1/       /3/ 0/ 1/* 0/-1/           /3/     /*     /
    
    所以这个结果就是,diff分别乘以Backstep_matrix[2->3]、Backstep_matrix[1->2]、Backstep_matrix[H1->1]
    **/

    m1[j][0] = m2[j][0] + m2[j][2];
    m1[j][1] = m2[j][1] + m2[j][3];
    m1[j][2] = m2[j][0] - m2[j][2];
    m1[j][3] = m2[j][1] - m2[j][3];
    m1[j][4] = m2[j][4] + m2[j][6];
    m1[j][5] = m2[j][5] + m2[j][7];
    m1[j][6] = m2[j][4] - m2[j][6];
    m1[j][7] = m2[j][5] - m2[j][7];

    m2[j][0] = m1[j][0] + m1[j][1];
    m2[j][1] = m1[j][0] - m1[j][1];
    m2[j][2] = m1[j][2] + m1[j][3];
    m2[j][3] = m1[j][2] - m1[j][3];
    m2[j][4] = m1[j][4] + m1[j][5];
    m2[j][5] = m1[j][4] - m1[j][5];
    m2[j][6] = m1[j][6] + m1[j][7];
    m2[j][7] = m1[j][6] - m1[j][7];
  }

  //vertical
  for (i=0; i < 8; i++)
  {
    m3[0][i] = m2[0][i] + m2[4][i];
    m3[1][i] = m2[1][i] + m2[5][i];
    m3[2][i] = m2[2][i] + m2[6][i];
    m3[3][i] = m2[3][i] + m2[7][i];
    m3[4][i] = m2[0][i] - m2[4][i];
    m3[5][i] = m2[1][i] - m2[5][i];
    m3[6][i] = m2[2][i] - m2[6][i];
    m3[7][i] = m2[3][i] - m2[7][i];

    m1[0][i] = m3[0][i] + m3[2][i];
    m1[1][i] = m3[1][i] + m3[3][i];
    m1[2][i] = m3[0][i] - m3[2][i];
    m1[3][i] = m3[1][i] - m3[3][i];
    m1[4][i] = m3[4][i] + m3[6][i];
    m1[5][i] = m3[5][i] + m3[7][i];
    m1[6][i] = m3[4][i] - m3[6][i];
    m1[7][i] = m3[5][i] - m3[7][i];

    m2[0][i] = m1[0][i] + m1[1][i];
    m2[1][i] = m1[0][i] - m1[1][i];
    m2[2][i] = m1[2][i] + m1[3][i];
    m2[3][i] = m1[2][i] - m1[3][i];
    m2[4][i] = m1[4][i] + m1[5][i];
    m2[5][i] = m1[4][i] - m1[5][i];
    m2[6][i] = m1[6][i] + m1[7][i];
    m2[7][i] = m1[6][i] - m1[7][i];
  }

  for (i = 0; i < 8; i++)
  {
    for (j = 0; j < 8; j++)
    {
      iSumHad += abs(m2[i][j]);
    }
  }
  iSumHad -= abs(m2[0][0]);
  //减去直流分量
  iSumHad =(iSumHad+2)>>2;
  //?????为什么加2除以4
  return(iSumHad);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值