for (j=0;j<16;j)
{
for (i=0;i<16;i)
{
M1[ i ][j]=imgY_org[img->opix_y+j][img->opix_x+i]-img->mprr_2[k][j][ i ]; 计算当前宏块残差块
M0[i%4][i/4][j%4][j/4]=M1[ i ][j];
}
}
current_intra_sad_2=0; // no SAD start handicap here
for (jj=0;jj<4;jj)
{
for (ii=0;ii<4;ii)
{
for (j=0;j<4;j) 第一次一维Hadamard变换
{
M3[0]=M0[0][ii][j][jj]+M0[3][ii][j][jj];
M3[1]=M0[1][ii][j][jj]+M0[2][ii][j][jj];
M3[2]=M0[1][ii][j][jj]-M0[2][ii][j][jj];
M3[3]=M0[0][ii][j][jj]-M0[3][ii][j][jj];
M0[0][ii][j][jj]=M3[0]+M3[1];
M0[2][ii][j][jj]=M3[0]-M3[1];
M0[1][ii][j][jj]=M3[2]+M3[3];
M0[3][ii][j][jj]=M3[3]-M3[2];
}
for (i=0;i<4;i)
{
M3[0]=M0[ i ][ii][0][jj]+M0[ i ][ii][3][jj];
M3[1]=M0[ i ][ii][1][jj]+M0[ i ][ii][2][jj];
M3[2]=M0[ i ][ii][1][jj]-M0[ i ][ii][2][jj];
M3[3]=M0[ i ][ii][0][jj]-M0[ i ][ii][3][jj];
第二次一维Hadamard变换
M0[ i ][ii][0][jj]=M3[0]+M3[1];
M0[ i ][ii][2][jj]=M3[0]-M3[1];
M0[ i ][ii][1][jj]=M3[2]+M3[3];
M0[ i ][ii][3][jj]=M3[3]-M3[2];
for (j=0;j<4;j)
if ((i+j)!=0)
current_intra_sad_2 += abs(M0[ i ][ii][j][jj]); 变换后的AC残差值取绝对值求和作为代价
}
}
}
for (j=0;j<4;j)
for (i=0;i<4;i)
M4[ i ][j]=M0[0][ i ][0][j]/4;
// Hadamard of DC koeff
for (j=0;j<4;j) 后面两个for循环对当前宏块的DC残差进行Hadamard变换并将变换后的值取绝对值求和作为代价
{
M3[0]=M4[0][j]+M4[3][j];
M3[1]=M4[1][j]+M4[2][j];
M3[2]=M4[1][j]-M4[2][j];
M3[3]=M4[0][j]-M4[3][j];
M4[0][j]=M3[0]+M3[1];
M4[2][j]=M3[0]-M3[1];
M4[1][j]=M3[2]+M3[3];
M4[3][j]=M3[3]-M3[2];
}
for (i=0;i<4;i)
{
M3[0]=M4[ i ][0]+M4[ i ][3];
M3[1]=M4[ i ][1]+M4[ i ][2];
M3[2]=M4[ i ][1]-M4[ i ][2];
M3[3]=M4[ i ][0]-M4[ i ][3];
M4[ i ][0]=M3[0]+M3[1];
M4[ i ][2]=M3[0]-M3[1];
M4[ i ][1]=M3[2]+M3[3];
M4[ i ][3]=M3[3]-M3[2];
for (j=0;j<4;j)
current_intra_sad_2 += abs(M4[ i ][j]);
}
if(current_intra_sad_2 < best_intra_sad2)
{
best_intra_sad2=current_intra_sad_2;
*intra_mode = k; // update best intra mode
}
}
}
best_intra_sad2 = best_intra_sad2/2;
return best_intra_sad2;
}
以上是源程序里的一段,intra_16*16并不是计算SAD值,而是计算SATD。
其中M1中放的是宏块的残差,M0也是,不过为了下面计算HADAMARD变换方便,他表示成M0[4][4][4][4]的形式,前2个[4][4]表示8X8块坐标,后2个[4][4]表示一个8X8里的4X4块坐标。
程序先对残差进行HADAMARD变换,然后把所有的DC分量提出来,再对DC分量做HADAMARD变换,
最后得到的是SATD。
有两点不明白,谁知道的解释一下:
1 在提取DC分量时为什么要除以4?
2 最后的best_intra_sad2 为什么要除以2?
这主要是由于SATD变换不是归一化矩阵,变换后的系数值幅值增加,因此要相应的/2和/4
hadamard 变换本身就有一个 /2 的操作,因此每次变换都要对所有系数进行 /2。而 find_sad_16x16 函数执行了两次 hadamard 变换:首先对 256 个系数进行一次,其次对所有 DC 系数再做一次,因此对 DC 系数应该 /4,而对 AC 系数应该 /2。find_sad_16x16 函数中的:M4[ i ][j]=M0[0][ i ][0][j]/4;就是对 DC 系数 /4,而最后的:best_intra_sad2 = best_intra_sad2/2;可以认为是对 AC 系数的变相 /2。但这里相当于是对所有系数 /2,所以 DC 系数多了一次 /2。这个多的一次就不知道原因了。
264乐园群里探讨过这个问题。对于hadamard变换的/2已经有了结论。但是对DC系数多除的那一次2,目前尚未找到根据。
4阶hadamard变换的定义式本身就是包含了这个/2的。可以见http://en.wikipedia.org/wiki/Hadamard_transform 。这里再多解释一点
假设hadamard变换没有/2, 变换矩阵为:
1 1 1 1
1 -1 1 -1
1 1 -1 -1
1 -1 -1 1
这时对一个列向量v = (1, 1, 1, 1)'做变换,即用变换矩阵左乘列向量v,得到的变换后向量v' = (4, 0, 0, 0)'。
现在观察v和v',在欧氏空间中,对一个向量的“大小”的衡量就是其长度,通过计算内积得到。那么
len(v) = sqrt( 1^2 + 1^2 + 1^2 + 1^2) = 2
len(v') = sqrt( 4^2 + 0^2 + 0^2 + 0^2) = 4
由此可见如果没有那个/2,变换前后,该向量的长度发生了变化。这样的变换是违背正交变换的定义的。
所以,作为正交变换的hadamard变换,必须要有这个/2的归一化。
A:推而广之,整数 DCT 变换在变换前后向量的长度也发生了变化,为什么没有除以 2 呢?
DCT变换(非整数)也是归一化的整数变换也是正交变换,所以也一定会满足归一化的。firstime是不是忘记把scaling matrix考虑进来了啊。
按照毕厚杰书上 113 页,变换矩阵为公式 6.15(这个时候 scaling matrix 还没分离出来吧?):
a a a a
b c -c -b
a -a -a a
c -b b -c
其中 a = 1/2,b = (2/5)^0.5。这个矩阵对列向量v = (1, 1, 1, 1)'做变换前后的向量长度并不相等啊。
分享到:
相关推荐
用于卷积码的盲识别,现在对于盲识别技术是前沿技术
1.版本:matlab2021a,我录制了仿真操作录像,可以跟着...2.领域:Haar变换/hadamard变换/KL变换/slant变换 3.内容:图像的Haar变换,hadamard变换,KL变换,slant变换matlab对比仿真 4.适合人群:本,硕等教研学习使用
2.领域:haar变换,hadamard变换,KL变换以及Slant变换 3.内容:图像的haar变换,hadamard变换,KL变换以及Slant变换对比和重建matlab仿真 4.运行注意事项:注意MATLAB左侧当前文件夹路径,必须是程序所在文件夹位置,...
利用Nega-Hadamard变换的性质,研究了bent函数与其对偶函数Nega-Hadamard变换的关系,得出bent函数为negabent函数,其对偶函数也是negabent函数的结果;同时,得到了布尔函数在某个仿射子空间上Nega-Hadamard变换的...
Hadamard变换光谱仪光谱复原算法的FPGA实现.pdf
matlab_图像的Haar变换,hadamard变换,KL变换,slant变换matlab对比仿真_源码
数字图像处理方法中的Walsh-Hadamard变换,对图像进行复原和增强。
matlab_(含教程)图像的haar变换,hadamard变换,KL变换以及Slant变换对比和重建matlab仿真
基于Arnold置乱和Hadamard变换的双水印信号预处理算法pdf,基于Arnold置乱和Hadamard变换的双水印信号预处理算法
具有主动星座扩展和Hadamard变换的OFDM中的PAPR降低
提出了一种基于分块Hadamard变换的鲁棒图像水印算法。水印图像先进行置乱和扩展得到水印序列。原始图像进行8×8分块的Hadamard变换,在中频系数里按不同强度嵌入水印。水印提取时,先计算与原始图像在对应的变换域...
Walsh-Hadamard 变换 fastwht是快速 Walsh-Hadamard 变换的 C++ 实现(使用 ),并绑定到 MATLAB 和 Python。 该算法在 O( N log(N) ) 操作中就地执行变换。 当前版本比 MATLAB 自己的实现fwht快fwht 。 由于 Python...
利用matlab编程实现哈达玛变换(hadamard变换)
针对半脆弱水印能区别正常的图像处理操作和恶意篡改的特点,提出一种基于Hadamard变换和SVD分解相结合的半脆弱水印算法。该算法首先对载体图像进行SVD分解,对所有的图像子块进行Hadamard变换,利用量化的方法将水印...
Hadamard变换(也称为Walsh-Hadamard变换, Hadamard-Rademacher-Walsh变换, Walsh变换或Walsh-Fourier变换)是广义Fourier变换的示例。 它对2m个实数(或复数,尽管Hadamard矩阵本身是纯实数)执行正交,对称,对...
从文件中复制和粘贴: %WAT3D 3D Walsh 或 Hadamard 变换% WAT3D(X, order) 将 3D 矩阵 X 转换为 Walsh 或 Hadmard % 域取决于参数“顺序”。 % 如果 order == 'sequency' 或 'walsh' % 该函数将使用有序的序列转换...
该函数实现了二维二元(Paley)有序快速原位 Walsh-Hadamard 变换,可用于信号处理、模式识别和遗传算法。 该算法使用 Cooley-Tukey 类型的信号流图并在 N log2 N 中实现加法和减法。 数据序列长度必须是 2 的整数次...
提出一种利用FPGA实现Hadamard变换光谱仪光谱复原算法的方案。利用具备数字信号处理功能的FPGA对Hadamard编码图像,可以快速地进行 Hadamard逆变换并得到复原图像。根据复原图像可以知道被测目标在各个波段的信息从而...
针对离散Hadamard变换在实时信号处理中具有广泛应用,但其运算速度受到DSP器件性能限制这一实际情况,进行了离散Hadamard变换的并行性研究及并行性能分析;并在基于并行多处理机平台——TMS320C80的编程结构基础上,...
通过采用改进的沃尔什—哈达马变换(Walsh-Hadamard translate,WHT),识别出删除卷积码的高维校验矩阵;再基于源卷积码的生成矩阵与校验矩阵间的约束关系,求出了源卷积码的最佳生成多项式和删除模式,并提出了码字...