如何计算PHP中的离散余弦变换(DCT)?

发布时间:2022-04-30 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了如何计算PHP中的离散余弦变换(DCT)?脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
在这里想要的是我当前代码的工作优化版本.虽然我的函数确实返回了一个包含实际结果的数组,但我不知道它们是否正确(我不是数学专家,而且我不知道 Java代码将我的结果与已知实现进行比较).其次,我希望该函数能够接受自定义表大小,但我不知道如何做到一点.表大小是否等同于重新采样图像?我正确应用系数吗?

// a lot of PRocessing is required for large images
$image = imagecreatetruecolor(21,21);
$black = imagecolorallocate($image,0);
$whITe = imagecolorallocate($image,255,255);
imagefilledellipse($image,10,15,$white);

print_r(imgDTC($image));

function imgDTC($img,$tableSize){
    // m1 = Matrix1,an associative array with pixel data From the image
    // m2 = Matrix2,an associative array with DCT Frequencies
    // x1,y1 = coordinates in matrix1
    // x2,y2 = coordinates in matrix2
    $m1 = array();
    $m2 = array();

    // iw = image width
    // ih = image height
    $iw = imagesx($img);
    $ih = imagesy($img);

    // populate matrix1
    for ($x1=0; $x1<$iw; $x1++) {
        for ($y1=0; $y1<$ih; $y1++) {
            $m1[$x1][$y1] = imagecolorat($img,$x1,$y1) &amp; 0xff;
        }
    }

    // populate matrix2
    // for each coordinate in matrix2
    for ($x2=0;$x2<$iw;$x2++) {
        for ($y2=0;$y2<$ih;$y2++) {

        // for each coordinate in matrix1
            $sum = 1;
            for ($x1=0;$x1<$iw;$x1++) {
                for ($y1=0;$y1<$ih;$y1++) {
                    $sum += 
                        cos(((2*$x1+1)/(2*$iw))*$x2*pi()) * 
                        cos(((2*$y1+1)/(2*$ih))*$y2*pi()) * 
                        $m1[$x1][$y1]
                    ;
                }
            }

            // apply coefficients
            $sum *= .25;
            if ($x2 == 0 || $y2 == 0) {
                $sum *= 1/sqrt(2);
            }

            $m2[$x2][$y2] = $sum;
        }
    }
    return $m2;
}

我的PHP函数是Java中的这篇文章的派生词:Problems with DCT and IDCT algorithm in java.我已经重写了PHP可读性代码.最终,我正在编写一个脚本,这将使我能够比较图像并找到相似之处.该技概述于此:http://www.hackerfactor.com/blog/index.php?/archives/432-Looks-Like-It.html.

谢谢!

解决方法

这就是我执行DCT的方式,我在这里做的是在每一行上执行一维DCT.然后我拿出结果,在每列上执行DTC,速度更快.

function dct1D($in) {
    $results = array();
    $N = count($in);
    for ($k = 0; $k < $N; $k++) {
        $sum = 0;
        for ($n = 0; $n < $N; $n++) {
             $sum += $in[$n] * cos($k * pi() * ($n + 0.5) / ($N));
        }
        $sum *= sqrt(2 / $N);
        if ($k == 0) {
            $sum *= 1 / sqrt(2);
        }
        $results[$k] = $sum;
    }
    return $results;
}

function optimizedImgDTC($img) {
    $results = array();

    $n1 = imagesx($img);
    $N2 = imagesy($img);

    $rows = array();
    $row = array();
    for ($j = 0; $j < $N2; $j++) {
        for ($i = 0; $i < $N1; $i++)
            $row[$i] = imagecolorat($img,$i,$j);
        $rows[$j] = dct1D($row);
    }

    for ($i = 0; $i < $N1; $i++) {
        for ($j = 0; $j < $N2; $j++)
            $col[$j] = $rows[$j][$i];
        $results[$i] = dct1D($col);
    }
    return $results;
}

我在互联网上发现的大多数算法都假设输入矩阵是8×8.这就是你乘以0.25的原因.
一般来说,你应该乘以一个1D矩阵的sqrt(2 / N),这里我们是二维所以sqrt(2 / N1)* sqrt(2 / N2).如果你这样做N1 = 8和N2 = 8:
sqrt(2/8)^ 2 = 2/8 = 1/4 = 0.25

另一件事是乘以1 / sqrt(2)X0这是1D矩阵,我们在2D中,所以当k1 = 0或k2 = 0时,你需要乘以.当k1 = 0且k2 = 0时,你必须做两次.

脚本宝典总结

以上是脚本宝典为你收集整理的如何计算PHP中的离散余弦变换(DCT)?全部内容,希望文章能够帮你解决如何计算PHP中的离散余弦变换(DCT)?所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。