You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何对2型DCT结果去正交化以匹配scipy默认dctn输出?

自定义2D DCT匹配Scipy默认输出的解决方法

你的自定义DCT实现对应的是Scipy中dctn指定norm="ortho"的正交归一化版本,而Scipy默认的dctn(norm=None)没有做归一化处理,只需通过缩放调整即可让结果匹配,有两种简单方式:


方式一:修改自定义DCT矩阵,直接生成非归一化结果

调整dct_mat函数的系数,去掉正交归一化的缩放因子,生成标准DCT-II变换矩阵:

import numpy as np
import scipy.fftpack

def dct_mat_non_ortho(data):
    (n, m) = data.shape
    assert(m == n)

    mat = np.zeros((n, n))

    # 第一行无缩放因子
    for i in range(n):
        mat[0][i] = 1.0

    # 其余行使用2倍余弦系数(标准DCT-II无归一化的定义)
    for r in range(1, n):
        for c in range(n):
            mat[r][c] = 2.0 * np.cos((np.pi * (2.0 * float(c) + 1.0) * float(r)) / (2.0 * float(n)))

    return mat

test_data = np.array([
    [13.4, 13.9, 0.1],
    [20.1, -20.3, 88.2],
    [0, 4.2, -53.5]
])

# Scipy默认结果
scipy_result = scipy.fftpack.dctn(test_data)
# 自定义非归一化DCT结果
mat = dct_mat_non_ortho(test_data)
custom_result = np.matmul(np.matmul(mat, test_data), mat.T)

print("Scipy默认结果:")
print(scipy_result)
print("自定义匹配结果:")
print(custom_result)

方式二:对现有正交归一化结果做后处理缩放

针对你已经生成的res(正交归一化结果),构造维度缩放向量,对每个元素按位置进行缩放:

n = test_data.shape[0]
# 构造缩放向量:第一个元素为sqrt(n),其余为sqrt(n/2)
scale = np.zeros(n)
scale[0] = np.sqrt(n)
scale[1:] = np.sqrt(n / 2.0)

# 对正交结果进行缩放,匹配Scipy默认输出
scaled_result = (scale.reshape(-1, 1) * res) * scale.reshape(1, -1)

print("Scipy默认结果:")
print(scipy)
print("缩放后自定义结果:")
print(scaled_result)

原理说明

Scipy默认的dctn(norm=None)实现的是标准DCT-II变换,没有施加正交归一化的缩放因子;而你的自定义矩阵是正交归一化版本,两者的差异在于:

  • 正交归一化版本对变换矩阵的第一行乘以1/sqrt(n),其余行乘以sqrt(2/n)
  • 标准DCT-II版本第一行无缩放,其余行乘以2

通过反向调整缩放因子,就能让两者结果完全匹配。

内容的提问来源于stack exchange,提问作者John Smith

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 21:23:15