gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-10-31 23:41:56 24 4
gpt4 key购买 nike

我想要的是我当前代码的有效优化版本。虽然我的函数确实返回了一个包含实际结果的数组,但我不知道它们是否正确(我不是数学大师,我不知道 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;
}

我的 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;
}

我在互联网上找到的大多数算法都假设输入矩阵是 8x8。这就是你乘以 0.25 的原因。一般来说,你应该乘以 sqrt(2/N) 一个一维矩阵,这里我们是二维的,所以 sqrt(2/N1) * sqrt(2/N2)。如果您对 N1 = 8 和 N2 = 8 执行此操作:平方根(2/8)^2 = 2/8 = 1/4 = 0.25

另一件事是乘以 1/sqrt(2) X0 它是一维矩阵,我们在二维矩阵中,所以当 k1 = 0 或 k2 = 0 时你要乘以。当 k1 = 0 和 k2 = 0 时你必须做两次。

关于php - 如何在 PHP 中计算离散余弦变换 (DCT)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14106984/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com