如何缩放以及通过哪个因子将dctmtx系数从float缩放到以下整数值:
浮动dctmtx:
( (0.3536 0.3536 0.3536 0.3536 0.3536 0.3536 0.3536 0.3536),
(0.4904 0.4157 0.2778 0.0975 -0.0975 -0.2778 -0.4157 -0.4904),
(0.4619 0.1913 -0.1913 -0.4619 -0.4619 -0.1913 0.1913 0.4619),
(0.4157 -0.0975 -0.4904 -0.2778 0.2778 0.4904 0.0975 -0.4157),
(0.3536 -0.3536 -0.3536 0.3536 0.3536 -0.3536 -0.3536 0.3536),
(0.2778 -0.4904 0.0975 0.4157 -0.4157 -0.0975 0.4904 -0.2778),
(0.1913 -0.4619 0.4619 -0.1913 -0.1913 0.4619 -0.4619 0.1913),
(0.0975 -0.2778 0.4157 -0.4904 0.4904 -0.4157 0.2778 -0.0975)
)
整数dctmtx:
(( 125, 122, 115, 103, 88, 69, 47, 24 ),
( 125, 103, 47, -24, -88, -122, -115, -69 ),
( 125, 69, -47, -122, -88, 24, 115, 103 ),
( 125, 24, -115, -69, 88, 103, -47, -122 ),
( 125, -24, -115, 69, 88, -103, -47, 122 ),
( 125, -69, -47, 122, -88, -24, 115, -103 ),
( 125, -103, 47, 24, -88, 122, -115, 69 ),
( 125, -122, 115, -103, 88, -69, 47, -24 )
);
答案 0 :(得分:1)
除了旋转的两个矩阵中的一个之外,两个矩阵似乎没有直接的线性关系:
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
int main (int argc, char *argv[])
{
float dctmtx[8][8] =
{ 0.3536, 0.3536, 0.3536, 0.3536, 0.3536, 0.3536, 0.3536, 0.3536,
0.4904, 0.4157, 0.2778, 0.0975, -0.0975, -0.2778, -0.4157, -0.4904,
0.4619, 0.1913, -0.1913, -0.4619, -0.4619, -0.1913, 0.1913, 0.4619,
0.4157, -0.0975, -0.4904, -0.2778, 0.2778, 0.4904, 0.0975, -0.4157,
0.3536, -0.3536, -0.3536, 0.3536, 0.3536, -0.3536, -0.3536, 0.3536,
0.2778, -0.4904, 0.0975, 0.4157, -0.4157, -0.0975, 0.4904, -0.2778,
0.1913, -0.4619, 0.4619, -0.1913, -0.1913, 0.4619, -0.4619, 0.1913,
0.0975, -0.2778, 0.4157, -0.4904, 0.4904, -0.4157, 0.2778, -0.0975
};
int j,k, i;
float m;
for ( j = 0; j < 8; j++) {
for ( k = 0; k < 8; k++) {
if ( k == 0)
m = (dctmtx[k][j] * 354) ;
else
m = (dctmtx[k][j] * 248) ;
i = lroundf(m);
printf("%4d ",i);
}
printf("\n");
}
}
每行中的第一个系数似乎与剩余的不同:
%% convftoi
125 122 115 103 88 69 47 24
125 103 47 -24 -88 -122 -115 -69
125 69 -47 -122 -88 24 115 103
125 24 -115 -69 88 103 -47 -122
125 -24 -115 69 88 -103 -47 122
125 -69 -47 122 -88 -24 115 -103
125 -103 47 24 -88 122 -115 69
125 -122 115 -103 88 -69 47 -24
稍微调整一下,找到确实匹配的缩放因子。
<强>附录强>
在LutzL的回答之后,我通过算法得出了浮点系数矩阵:
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#define PI 3.14159265359
int main (int argc, char *argv[])
{
float calcmtx[8][8];
int j,k, i;
float m;
printf("float coefficients calculated\n");
for ( j = 0; j < 8; j++) {
for ( k = 0; k < 8; k++) {
if ( j == 0)
m = cos(PI*j*(2*k+1)/16)/(sqrt(2)*2) ;
else
m = cos(PI*j*(2*k+1)/16)/2 ;
calcmtx[k][j] = floorf(m*10000 + 0.5)/10000;
}
}
for ( j = 0; j < 8; j++) {
for ( k = 0; k < 8; k++) {
printf("% 2.4f ", calcmtx[k][j]);
}
printf("\n");
}
printf("\n") ;
printf("integer coefficients derived\n");
for ( j = 0; j < 8; j++) {
for ( k = 0; k < 8; k++) {
if (k == 0)
m = sqrt(2);
else
m = 1;
i = (int) (calcmtx[j][k] * 250 * m);
printf("%4d ", i);
}
printf("\n");
}
printf("\n") ;
printf("approximated integer coefficients\n");
for ( j = 0; j < 8; j++) {
for ( k = 0; k < 8; k++) {
if ( k == 0)
m = calcmtx[j][k] * 354 ;
else
m = calcmtx[j][k] * 248 ;
i = lroundf(m);
printf("%4d ", i);
}
printf("\n");
}
}
我们看到整数矩阵第一系数乘以2的平方根:
%% gencoeffi
float coefficients calculated
0.3536 0.3536 0.3536 0.3536 0.3536 0.3536 0.3536 0.3536
0.4904 0.4157 0.2778 0.0975 -0.0975 -0.2778 -0.4157 -0.4904
0.4619 0.1913 -0.1913 -0.4619 -0.4619 -0.1913 0.1913 0.4619
0.4157 -0.0975 -0.4904 -0.2778 0.2778 0.4904 0.0975 -0.4157
0.3536 -0.3536 -0.3536 0.3536 0.3536 -0.3536 -0.3536 0.3536
0.2778 -0.4904 0.0975 0.4157 -0.4157 -0.0975 0.4904 -0.2778
0.1913 -0.4619 0.4619 -0.1913 -0.1913 0.4619 -0.4619 0.1913
0.0975 -0.2778 0.4157 -0.4904 0.4904 -0.4157 0.2778 -0.0975
integer coefficients derived
125 122 115 103 88 69 47 24
125 103 47 -24 -88 -122 -115 -69
125 69 -47 -122 -88 24 115 103
125 24 -115 -69 88 103 -47 -122
125 -24 -115 69 88 -103 -47 122
125 -69 -47 122 -88 -24 115 -103
125 -103 47 24 -88 122 -115 69
125 -122 115 -103 88 -69 47 -24
approximated integer coefficients
125 122 115 103 88 69 47 24
125 103 47 -24 -88 -122 -115 -69
125 69 -47 -122 -88 24 115 103
125 24 -115 -69 88 103 -47 -122
125 -24 -115 69 88 -103 -47 122
125 -69 -47 122 -88 -24 115 -103
125 -103 47 24 -88 122 -115 69
125 -122 115 -103 88 -69 47 -24
当浮点精度有限时,它与近似值匹配。
答案 1 :(得分:0)
如果你读过离散余弦变换,你会发现基本系数是
cos(pi*i*(2*j+1)/16), i,j=0..7
然后第一个表包含这些按0.5缩放的值,除了第一行/列,其缩放为0.25 * sqrt(2)= 1 / sqrt(8)。这是获得正交矩阵的正确方法。第一列的平方和为8,其他为4。
第二个表是将余弦值与125相乘时的舍入结果。在使用转置矩阵计算逆变换时,必须注意正确地重新缩放矢量。
第一张表格转载,第一栏除外:
> [[ Cos(pi*i*(2*j+1)/16)/2 : i in [0..7] ]: j in [0..7] ];
[
[ 0.5, 0.49039264, 0.46193977, 0.41573481, 0.35355339, 0.27778512, 0.19134172, 0.09754516 ],
[ 0.5, 0.41573481, 0.19134172, -0.09754516, -0.35355339, -0.49039264, -0.46193977, -0.27778512 ],
[ 0.5, 0.27778512, -0.19134172, -0.49039264, -0.35355339, 0.09754516, 0.46193977, 0.41573481 ],
[ 0.5, 0.09754516, -0.46193977, -0.27778512, 0.35355339, 0.41573481, -0.19134172, -0.49039264 ],
[ 0.5, -0.09754516, -0.46193977, 0.27778512, 0.35355339, -0.41573481, -0.19134172, 0.49039264 ],
[ 0.5, -0.27778512, -0.19134172, 0.49039264, -0.35355339, -0.09754516, 0.46193977, -0.41573481 ],
[ 0.5, -0.41573481, 0.19134172, 0.09754516, -0.35355339, 0.49039264, -0.46193977, 0.27778512 ],
[ 0.5, -0.49039264, 0.46193977, -0.41573481, 0.35355339, -0.27778512, 0.19134172, -0.09754516 ]
]
第二个表,在整数舍入之前
> [[ Cos( pi*i*(2*j+1)/16 ) *125 : i in [0..7] ]: j in [0..7] ];
[
[ 125, 122.5982, 115.4849, 103.9337, 88.3883, 69.4463, 47.8354, 24.3863 ],
[ 125, 103.9337, 47.8354, -24.3863, -88.3883, -122.5982, -115.4849, -69.4463 ],
[ 125, 69.4463, -47.8354, -122.5982, -88.3883, 24.3863, 115.4849, 103.9337 ],
[ 125, 24.3863, -115.4849, -69.4463, 88.3883, 103.9337, -47.8354, -122.5982 ],
[ 125, -24.3863, -115.4849, 69.4463, 88.3883, -103.9337, -47.8354, 122.5982 ],
[ 125, -69.4463, -47.8354, 122.5982, -88.3883, -24.3863, 115.4849, -103.9337 ],
[ 125, -103.9337, 47.8354, 24.3863, -88.3883, 122.5982, -115.4849, 69.4463 ],
[ 125, -122.5982, 115.4849, -103.9337, 88.3883, -69.4463, 47.8354, -24.3863 ]
]