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,变换矩阵为:
当计算4x4块的SATD时,先使用下面的方法进行二维的阿达马变换:
然后计算所有系数绝对值之和并归一化。
类似的,当计算8x8块的SATD时,先使用下面的方法进行二维的Hadamard变换:
然后计算所有系数绝对值之和并归一化。
3. 阿达马变换的构建
阿达马变换转换主要型式为 点的转换矩阵,其最小单位矩阵为 2x2 的阿达马变换矩阵,以下分别为二点、四点与如何产生
点的阿达马变换转换步骤。
- 二点阿达马变换转换:
- 产生
点阿达马变换的步骤:
步骤一:
步骤二: 根据正负号次序 (Sign change,正负号改变次数) 将矩阵 (Matrix) 内的列向量座顺序上的重新排列。
Hadmard 的 4x4变换,不难理解
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变换。