Math 将浮点转换为整数
如何缩放以及通过哪个因子从浮点缩放dctmtx系数以获得以下整数值: 浮动dctmtx:Math 将浮点转换为整数,math,image-processing,vhdl,dct,Math,Image Processing,Vhdl,Dct,如何缩放以及通过哪个因子从浮点缩放dctmtx系数以获得以下整数值: 浮动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.46
( (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 )
);
除了旋转的两个矩阵中的一个之外,这两个矩阵似乎没有直接的线性关系:
#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");
}
}
经过一点微调,找到了匹配的比例因子
附录
在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");
}
}
它与浮点精度受限时的近似值相匹配。如果您阅读离散余弦变换,您会发现基本系数为
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 ]
]
这似乎不可能回答,因为-0.0975和-0.4619都映射到-88。请提供更多关于两个数组的来源和连接的信息。但是,如果要转置第二个矩阵,并独立地重新缩放行,那么至少会提供一个匹配。但是,0.3536仍然被映射到tp125,第五行被映射到88。
> [[ 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 ]
]