c# - 32x32 矩阵的 BinDCT 实现

标签 c# algorithm math matrix dct

因此,我尝试了一些 DCT 实现,并注意到由于必要的乘数计算,它们(相对)较慢。

在谷歌搜索了一下之后,我遇到了 BinDCT,它产生了非常好的 DCT 近似值,并且只使用位移位。

在浏览有关它的论文(http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.7.834&rep=rep1&type=pdfhttp://www.docstoc.com/docs/130118150/Image-Compression-Using-BinDCT)并阅读我在 ohlo(http://code.ohloh.net/file?fid=vz-HijUWVLFS65NRaGZpLZwZFq8&cid=mt_ZjvIU0Us&s=&fp=461906&projSelected=true#L0)上找到的一些代码时,我注意到只有 8x8 矩阵的实现。

我正在为 32x32 矩阵寻找此 BinDCT 的实现,以便我可以将其用于感知哈希算法 (phash) 的更快变体。

我不是数学家,虽然我试图理解论文中发生的事情和我发现的 C 代码,但我还是无法理解如何转换此实现以应用于 32x32 矩阵。

有人写过吗?有可能吗?

我知道扩展实现需要更多的移位和 tmp 变量。但是,虽然我可以尝试和错误地尝试,但我连理论都不懂,所以我永远不知道我是否得到了正确的结果。

我是用 C# 写的,但是任何语言都可以,因为它都是基本操作,而且很容易翻译。

最佳答案

1.你有固定的输入大小

  • 所以你一直乘以相同的权重
  • 预先计算一次,然后只使用它们
  • 这个沟渠所有的罪恶,因果操作

2.2D DCT 可以计算为 1D DCT(类似于 FFT)

  • 首先对行进行 DCT
  • 然后在 DCTed 行的列上
  • 乘以归一化常数
  • 所以这将 O(N^4) 转换为 O(N^3)

3.使用FastDCT

  • 这很棘手
  • 快速算法是 (I)DST 和 (I)DCT 的融合
  • 关于它的论文很少
  • 但是有模糊的(而且所有的方程在不同的论文中都是不同的而不是完整的)
  • 实际上我最近看到了一个函数方程式,也没有为它编程
  • 唯一几乎可行的方法是使用 FFT
  • 但是对于小 N 来说,因为切换到复杂域没有任何好处
  • 并且这些值并不是真正的 DCT,而是非常接近它。
  • 当然我不是这个领域的专家所以我可以忽略一些东西
  • 在所有数百页纸的方程式中
  • 无论如何在快速算法实现 2D (I)DCT 和 bullet 2 之后
  • 复杂度为 O((N^2).log(N))

4.放弃 FPU 乘法

  • 你可以把所有的权重转换成a1=a0*1024
  • 或任何其他面具
  • 所以:

    x*a0 = (x*a1)/1024 = (x*a1)>>10
    
  • 输入数据也可以这样做

  • 所以现在只剩下整数运算了
  • 但在现代机器上,这种方法可能比 FPU 使用速度慢(取决于平台和实现)

4.放弃整数乘法

  • 您可以通过移位和加法运算(寻找二进制乘法)放弃所有乘法
  • 但是在现代机器上这实际上会减慢速度吗
  • 当然,如果您将其连接到某些逻辑板/IO 上,那么它有其优点

关于c# - 32x32 矩阵的 BinDCT 实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21068020/

相关文章:

c# - 希伯来语/犹太语日期转换

algorithm - 极小极大评价函数

arrays - 找到具有给定约束的最大总和的对

java - 从我能做的 L * B block 面包中找出最大正方形的多少片

iOS 将极坐标定义的区域转换为 NxN 矩阵

c# - Entity Framework : Passing String Parameter to FromSql Statement in Version 2. 2

c# - 如何在 TreeView 中获取当前选定的节点

c# - 执行此 LINQ to XML 查询的更好方法?

c++ - 给定磁盘上的 1 TB 数据集,每个数据记录大约 1 KB,如何使用 512 MB RAM 和无限磁盘空间找到重复项?

PHP 检查一个值是否是具有公差的数字序列的一部分