Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在PHP中计算离散余弦变换(DCT)?_Php_Algorithm_Image Processing_Dct - Fatal编程技术网

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

如何在PHP中计算离散余弦变换(DCT)?,php,algorithm,image-processing,dct,Php,Algorithm,Image Processing,Dct,这里我想要的是我当前代码的工作优化版本。虽然我的函数返回一个带有实际结果的数组,但我不知道它们是否正确(我不是数学大师,也不知道用Java代码将结果与已知实现进行比较)。其次,我希望该函数能够接受自定义表大小,但我不知道如何做到这一点。表格大小是否等同于对图像重新采样?我是否正确应用了系数 // a lot of processing is required for large images $image = imagecreatetruecolor(21, 21); $black = imag

这里我想要的是我当前代码的工作优化版本。虽然我的函数返回一个带有实际结果的数组,但我不知道它们是否正确(我不是数学大师,也不知道用Java代码将结果与已知实现进行比较)。其次,我希望该函数能够接受自定义表大小,但我不知道如何做到这一点。表格大小是否等同于对图像重新采样?我是否正确应用了系数

// a lot of processing is required for large images
$image = imagecreatetruecolor(21, 21);
$black = imagecolorallocate($image, 0, 0, 0);
$white = imagecolorallocate($image, 255, 255, 255);
imagefilledellipse($image, 10, 10, 15, 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) & 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;
}
//大型图像需要大量处理
$image=imagecreatetruecolor(21,21);
$black=imagecolorallocate($image,0,0,0);
$white=imagecolorallocate($image,255,255);
ImageFilleDelipse($image,10,10,15,15,$white);
打印(imgDTC($image));
函数imgDTC($img,$tableSize){
//m1=Matrix1,一个与图像中的像素数据相关的数组
//m2=矩阵X2,具有DCT频率的关联数组
//x1,y1=矩阵x1中的坐标
//x2,y2=矩阵x2中的坐标
$m1=数组();
$m2=数组();
//iw=图像宽度
//ih=图像高度
$iw=imagesx($img);
$ih=imagesy($img);
//填充矩阵1

对于($x1=0;$x1首先,您需要测试您的函数,以便找到任何工作实现。并将您的实现的结果与工作实现的结果(使用相同的输入)进行比较

如果你想让你的代码更快,你可以看看这篇文章(前两部分)


在您的情况下,您不能使用自定义表大小,因为它应该与图像大小匹配(可能是错误的)。

这就是我执行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;
}
函数dct1D($in){
$results=array();
$N=计数($in);
对于($k=0;$k<$N;$k++){
$sum=0;
对于($n=0;$n<$n;$n++){
$sum+=$in[$n]*cos($k*pi()*($n+0.5)/($n));
}
$sum*=sqrt(2/$N);
如果($k==0){
$sum*=1/平方米(2);
}
$results[$k]=$sum;
}
返回$results;
}
功能优化DIMGDTC($img){
$results=array();
$N1=图像x($img);
$N2=图像系统($img);
$rows=array();
$row=array();
对于($j=0;$j<$N2;$j++){
对于($i=0;$i<$N1;$i++)
$row[$i]=imagecolorat($img,$i,$j);
$rows[$j]=dct1D($row);
}
对于($i=0;$i<$N1;$i++){
对于($j=0;$j<$N2;$j++)
$col[$j]=$rows[$j][$i];
$results[$i]=dct1D($col);
}
返回$results;
}
我在网上找到的大多数算法都假设输入矩阵是8x8。这就是为什么要乘以0.25。 一般来说,你应该乘以sqrt(2/N)一个1D矩阵,这里我们是2D so 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时,你必须做两次。

很明显,人们似乎觉得TinyEye是一个很好的服务(就像一个相关结果的制作者给出的查询一样好)。我希望上一个链接中描述的方法会产生许多误报,而且它似乎并不特别关心所提到的每个步骤背后的原因。你为什么要故意造成如此糟糕的结果?我会将关于图像比较的提及与所指出的链接一起删除,只留下关于实现的正确性。现在,要将实现与已知实现进行比较,只需检查一下。JPEG使用DCT压缩图像,如果您想查看源代码,这就是问题所在。我只知道javascript和php。您知道这些语言中的任何实现吗?就优化而言,我需要特定的代码指针,因为我不是数学教授。那么表大小是否等于图像大小?在这种情况下,对图像重新采样将改变表大小?此外,我是否正确应用了系数?不,您没有正确应用系数,因为如果$x2和$y2都等于0,则必须乘以1/sqrt(2)两倍。此外,你的总和等于1。我稍后会给你发一个代码。我假设
dct1D(数组(8,7,6,5,4,3,2,1))
将有类似
array(12.7279,6.4423,0,0.6735,0,0.2009,0,0.0507)的内容
但是索引1和以上太小了。@罗伊,我不明白你说了什么。你能解释一下吗?我更新了dct 1函数,但没有出错。它不是[$k]中的$in,而是[$n]中的$in,不是2*$n+1,而是$n+0.5