寻找8x8(或nxn)离散余弦变换(DCT)/反离散余弦变换(IDCT)伪代码

5
我已经在谷歌上搜索了一段时间,试图找到一个效率较高的8x8(或nxn)离散余弦变换算法的伪代码,但我找不到任何东西!
我已经实现了朴素方法,但执行时间太长。
如果您能发布一些伪代码或参考一本好书/文档/网站,那将非常有帮助。
最好提供C或C ++示例!

很奇怪,一个相当天真的方法在这里运行得非常快,"太长"指的是多长时间? - harold
我正在处理一张大小为512x512,有3个通道的图像,但它花费了好几分钟时间,最终我只能关掉程序。可能是我实现有误或者陷入了某种无限循环中。让我再试一次。 - user904963
我当然预先计算了余弦表,但除此之外,它只是按照定义建议的那样进行的天真方法。但即使有这些余弦值,也不应该花费很长时间。 - harold
你在使用可分离性吗?@哈罗德 - user904963
说实话,我不是DCT方面的专家,我使用两个嵌套循环,从0到8进行迭代,而不是先在一个维度上进行,然后再在另一个维度上进行。这就是你所说的意思吗? - harold
是的。你能发一下你的源代码吗?我正在尝试进行一些隐写术,并需要一个简单的DCT和IDCT来隐藏在那个空间中的信息。@哈罗德 - user904963
2个回答

5

根据评论要求,提供源码(稍作警告,它是用C#编写的,但与C ++的区别应该很小,我知道代码很糟糕):

主循环(A = 结果,B = 输入):

for (int y = 0; y < 8; y++)
{
    for (int x = 0; x < 8; x++)
    {
        A[y * 8 + x] = 0;
        for (int u = 0; u < 8; u++)
            for (int v = 0; v < 8; v++)
                A[y * 8 + x] += alpha(u) * alpha(v) * B[u, v] *
                    cosine[u, x] * cosine[v, y];
    }
}

支持人员:

static double alpha(int i)
{
    if (i == 0)
        return SQRT2o2 * 0.5;
    return 0.5;
}
const double SQRT2o2 = 1.414213562373095048801688724209 * 0.5;
cosine = new double[8, 8];
const double inv16 = 1.0 / 16.0;
for (int i = 0; i < 8; i++)
{
     for (int j = 0; j < 8; j++)
     {
         cosine[j, i] = Math.Cos(Math.PI * j * (2.0 * i + 1) * inv16);
     }
}

编辑:我计时了 - 对于512×512像素(单通道)它需要半秒钟。当然,这很慢,但远非“永远”。


是的,谢谢。我不需要超高性能。 - user904963
@user904963,你知道将其转换为iDCT所需的更改吗?我也可以发布那个。 - harold
是的,看起来它正在工作。 - user904963

1

FFTW有一个开源的高效实现


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接