Hardmard 变换

阿达马(Hadamard)矩阵是由+1和-1元素构成的正交方阵。阿达马变换多被用来计算SATD(一种视频残差信号大小的衡量)。

这里介绍三个内容,1. SATD 2. H264中阿达马的应用 3. 阿达马变换的构建 

1. SATD

SATD是一种视频残差信号大小的衡量标准。

SATD即将残差经哈德曼变换的4×4块的预测残差绝对值总和,可以将其看作简单的时频变换,其值在一定程度上可以反映生成码流的大小。

SATD(Sum of Absolute Transformed Difference)即hadamard变换后再绝对值求和。

2. 在H264中使用4阶和8阶的阿达马变换来计算SATD,变换矩阵为:

 H_4 = \begin{bmatrix} 1 &  1 &  1 &  1 \\ 1 & -1 &  1 & -1 \\ 1 &  1 & -1 & -1 \\ 1 & -1 & -1 &  1 \end{bmatrix}

当计算4x4块\begin{bmatrix}L_4\end{bmatrix}的SATD时,先使用下面的方法进行二维的阿达马变换:

 

  \begin{bmatrix}    L_4'  \end{bmatrix}=  \begin{bmatrix}    H_4  \end{bmatrix}\times  \begin{bmatrix}    L_4  \end{bmatrix}\times  \begin{bmatrix}    H_4  \end{bmatrix}

 

然后计算\begin{bmatrix}L_4'\end{bmatrix}所有系数绝对值之和并归一化。

 H_8 = \begin{bmatrix}  1 &  1 &  1 &  1 &  1 &  1 &  1 &  1 \\ 1 & -1 &  1 & -1 &  1 & -1 &  1 & -1 \\ 1 &  1 & -1 & -1 &  1 &  1 & -1 & -1 \\ 1 & -1 & -1 &  1 &  1 & -1 & -1 &  1 \\ 1 &  1 &  1 &  1 & -1 & -1 & -1 & -1 \\ 1 & -1 &  1 & -1 & -1 &  1 & -1 &  1 \\ 1 &  1 & -1 & -1 & -1 & -1 &  1 &  1 \\ 1 & -1 & -1 &  1 & -1 &  1 &  1 & -1 \end{bmatrix}

类似的,当计算8x8块\begin{bmatrix}L_8\end{bmatrix}的SATD时,先使用下面的方法进行二维的Hadamard变换:

  \begin{bmatrix}    L_8'  \end{bmatrix}=  \begin{bmatrix}    H_8  \end{bmatrix}\times  \begin{bmatrix}    L_8  \end{bmatrix}\times  \begin{bmatrix}    H_8  \end{bmatrix}

然后计算\begin{bmatrix}L_8'\end{bmatrix}所有系数绝对值之和并归一化。

3. 阿达马变换的构建

阿达马变换转换主要型式为  \boldsymbol{2^k}  点的转换矩阵,其最小单位矩阵为 2x2 的阿达马变换矩阵,以下分别为二点、四点与如何产生  \boldsymbol{2^k}  点的阿达马变换转换步骤。

  • 二点阿达马变换转换:

 \boldsymbol{W_2} = \begin{bmatrix} 1 & 1 \\ 1 & -1 \end{bmatrix}

  • 产生  \boldsymbol{2^k}  点阿达马变换的步骤:

步骤一:  \boldsymbol{V_{2^{k+1}}} = \begin{bmatrix} \boldsymbol{W_{2^k}} & \boldsymbol{W_{2^k}} \\ \boldsymbol{W_{2^k}} & \boldsymbol{-W_{2^k}} \end{bmatrix}


步骤二: 根据正负号次序 (Sign change,正负号改变次数) 将矩阵 (Matrix) 内的列向量座顺序上的重新排列。

 \boldsymbol{V_{2^{k+1}}} \longrightarrow  \boldsymbol{W_{2^{k+1}}}

Hadmard 的 4x4变换,不难理解

  \begin{bmatrix}    L_4'  \end{bmatrix}=  \begin{bmatrix}    H_4  \end{bmatrix}\times  \begin{bmatrix}    L_4  \end{bmatrix}\times  \begin{bmatrix}    H_4  \end{bmatrix}

 1 void hadamard4x4(int **block, int **tblock)
 2 {
 3   int i;
 4   int tmp[16];
 5   int *pTmp = tmp, *pblock;
 6   int p0,p1,p2,p3;
 7   int t0,t1,t2,t3;
 8 
 9   // Horizontal
10   for (i = 0; i < BLOCK_SIZE; i++)
11   {
12     pblock = block[i];
13     p0 = *(pblock++);
14     p1 = *(pblock++);
15     p2 = *(pblock++);
16     p3 = *(pblock  );
17 
18     t0 = p0 + p3;
19     t1 = p1 + p2;
20     t2 = p1 - p2;
21     t3 = p0 - p3;
22 
23     *(pTmp++) = t0 + t1;
24     *(pTmp++) = t3 + t2;
25     *(pTmp++) = t0 - t1;    
26     *(pTmp++) = t3 - t2;
27   }
28 
29   // Vertical 
30   for (i = 0; i < BLOCK_SIZE; i++)
31   {
32     pTmp = tmp + i;
33     p0 = *pTmp;
34     p1 = *(pTmp += BLOCK_SIZE);
35     p2 = *(pTmp += BLOCK_SIZE);
36     p3 = *(pTmp += BLOCK_SIZE);
37 
38     t0 = p0 + p3;
39     t1 = p1 + p2;
40     t2 = p1 - p2;
41     t3 = p0 - p3;
42 
43     tblock[0][i] = (t0 + t1) >> 1;
44     tblock[1][i] = (t2 + t3) >> 1;
45     tblock[2][i] = (t0 - t1) >> 1;
46     tblock[3][i] = (t3 - t2) >> 1;
47   }
48 }
49 
50 
51 void ihadamard4x4(int **tblock, int **block)
52 {
53   int i;  
54   int tmp[16];
55   int *pTmp = tmp, *pblock;
56   int p0,p1,p2,p3;
57   int t0,t1,t2,t3;
58 
59   // Horizontal
60   for (i = 0; i < BLOCK_SIZE; i++)
61   {
62     pblock = tblock[i];
63     t0 = *(pblock++);
64     t1 = *(pblock++);
65     t2 = *(pblock++);
66     t3 = *(pblock  );
67 
68     p0 = t0 + t2;
69     p1 = t0 - t2;
70     p2 = t1 - t3;
71     p3 = t1 + t3;
72 
73     *(pTmp++) = p0 + p3;
74     *(pTmp++) = p1 + p2;
75     *(pTmp++) = p1 - p2;
76     *(pTmp++) = p0 - p3;
77   }
78 
79   //  Vertical 
80   for (i = 0; i < BLOCK_SIZE; i++)
81   {
82     pTmp = tmp + i;
83     t0 = *pTmp;
84     t1 = *(pTmp += BLOCK_SIZE);
85     t2 = *(pTmp += BLOCK_SIZE);
86     t3 = *(pTmp += BLOCK_SIZE);
87 
88     p0 = t0 + t2;
89     p1 = t0 - t2;
90     p2 = t1 - t3;
91     p3 = t1 + t3;
92     
93     block[0][i] = p0 + p3;
94     block[1][i] = p1 + p2;
95     block[2][i] = p1 - p2;
96     block[3][i] = p0 - p3;
97   }
98 }
Hadmard 变换和反变换(JM18.6)

在JM18.6当中有用到4x2的Hadmard变换。

 

posted @ 2014-11-17 15:25  追随技术  阅读(2261)  评论(0编辑  收藏  举报