gpt4 book ai didi

php - 我的双线性插值算法有什么问题?

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:18:35 24 4
gpt4 key购买 nike

我正在使用 PHP 来测试我的双线性算法。为清晰起见,代码未优化。

下面是代码的作用:

  1. 绘制从 2x2 图像到 10x10 目标的原始像素图像。这些将留下空白像素。

注意:此处的图像已从 10x10 调整为 100x100,以便更好地观看。

resized

  1. 对像素行进行插值。

enter image description here

  1. 使用步骤 2 中的像素行从左到右、从上到下对剩余像素进行插值:

enter image description here

但是,它与我在 Photoshop 中使用双线性重采样得到的结果不匹配:

enter image description here

完整源代码:

<?php
$image1 = imagecreatefrompng( 'test.png' );

$w1 = imagesx( $image1 );
$h1 = imagesy( $image1 );

$w2 = 10;
$h2 = 10;
$image2 = imagecreatetruecolor( $w2, $h2 );

imagefill($image2, 0, 0, imagecolorallocate($image2, 0x4c, 0x4c, 0x8e)); // added bg for pixels to stand-out

function lerp($v0, $v1, $t) {
return $v0 + $t*($v1-$v0);
}

function getPixel($image, $x, $y){
$rgb = imagecolorat( $image, $x, $y );
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;
return array($r,$g,$b);
}

$maxY1 = $h1 - 1;
$maxX1 = $w1 - 1;
$maxY2 = $h2 - 1;
$maxX2 = $w2 - 1;

// plot original pixels from source to destination
for($y = 0; $y <= $maxY1; $y++) { // loop thru src height

$newY = floor(($y/$maxY1) * $maxY2);

for ($x = 0; $x <= $maxX1; $x++) { // loop thru src width

$newX = floor(($x/$maxX1) * $maxX2);
$rgb = imagecolorat( $image1, $x, $y );
$r1 = ($rgb >> 16) & 0xFF;
$g1 = ($rgb >> 8) & 0xFF;
$b1 = $rgb & 0xFF;

imagesetpixel( $image2, $newX, $newY, imagecolorallocate( $image2, $r1, $g1, $b1 ) );

}
}
imagepng( $image2, 'out1.png' );

// interpolate pixels from pixel[1,0] to pixel[8,0]
$y = 0;
$rgb = imagecolorat( $image2, 0, $y );
$r0 = ($rgb >> 16) & 0xFF;
$g0 = ($rgb >> 8) & 0xFF;
$b0 = $rgb & 0xFF;

$rgb = imagecolorat( $image2, 9, $y );
$r1 = ($rgb >> 16) & 0xFF;
$g1 = ($rgb >> 8) & 0xFF;
$b1 = $rgb & 0xFF;
for($x=1; $x <= 8; $x++){
$t = $x / 9;
$r = lerp($r0, $r1, $t);
$g = lerp($g0, $g1, $t);
$b = lerp($b0, $b1, $t);
imagesetpixel( $image2, $x, $y, imagecolorallocate( $image2, $r, $g, $b ) );
}
imagepng( $image2, 'out2.png' );

// interpolate pixels from pixel[1,9] to pixel[8,9]
$y = 9;
$rgb = imagecolorat( $image2, 0, $y );
$r0 = ($rgb >> 16) & 0xFF;
$g0 = ($rgb >> 8) & 0xFF;
$b0 = $rgb & 0xFF;

$rgb = imagecolorat( $image2, 9, $y );
$r1 = ($rgb >> 16) & 0xFF;
$g1 = ($rgb >> 8) & 0xFF;
$b1 = $rgb & 0xFF;

for($x=1; $x <= 8; $x++){
$t = $x / 9;
$r = lerp($r0, $r1, $t);
$g = lerp($g0, $g1, $t);
$b = lerp($b0, $b1, $t);
imagesetpixel( $image2, $x, $y, imagecolorallocate( $image2, $r, $g, $b ) );
}
imagepng( $image2, 'out3.png' );

// interpolate remaining pixels
for($x=0; $x <= 9; $x++){
$rgb = imagecolorat( $image2, $x, 0 );
$r0 = ($rgb >> 16) & 0xFF;
$g0 = ($rgb >> 8) & 0xFF;
$b0 = $rgb & 0xFF;

$rgb = imagecolorat( $image2, $x, 9 );
$r1 = ($rgb >> 16) & 0xFF;
$g1 = ($rgb >> 8) & 0xFF;
$b1 = $rgb & 0xFF;
for($y = 1; $y <= 8; $y++){
$t = $y / 9;
$r = lerp($r0, $r1, $t);
$g = lerp($g0, $g1, $t);
$b = lerp($b0, $b1, $t);
imagesetpixel( $image2, $x, $y, imagecolorallocate( $image2, $r, $g, $b ) );
}
}
imagepng( $image2, 'out4.png' );

header('Content-type: image/png');
imagepng( $image2);
imagedestroy( $image1 );

我错过了什么?

最佳答案

Photoshop 是正确的。在您的版本中,原始 4 个像素值最终出现在新图像的极端角落,但在正确的双线性插值中,它们最终出现在新图像 4 个象限的中心。原始图像的边缘之外没有任何信息,因此 photoshop 在边缘进行不断的外推:

2x2:

enter image description here

10x10 插值前:

enter image description here

如果您从 3x3 图像而不是 2x2 图像开始,您的方法将导致原始边缘像素相对于中心像素对最终图像的贡献减少,从而使结果产生偏差。

关于php - 我的双线性插值算法有什么问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39876239/

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