我正在尝试实现双三次插值算法来从高度图中重建更高分辨率的数据。经过一些错误和包含几乎无法理解的数学的指令集(我已经有几年没有微积分了,除了基础知识我不再记得太多了),我发现 Paul Bourke 的文章“图像缩放的双三次插值”包含什么似乎是一个相当简单且易于实现的算法。http://paulbourke.net/texture_colour/imageprocess/
但是,我并没有产生与维基百科上的插值结果很相似的插值结果,而是得到了这个(来自相同的输入数据):
是什么导致了错误,更重要的是 - 如何修复它?
下面的 PHP 代码(是的,这可能应该 - 并且将会 - 在 C 中重新实现;当它工作时)
class BicubicInterpolator
{
private $data;
public function Set_data($d)
{
$this->data=$this->denull($d);
}
public function Interpolate($dx,$dy)
{
$r=0;
for ($m=-1; $m<2; $m++)
for ($n=-1; $n<2; $n++)
$r+=$this->data[$m+1][$n+1] * $this->R($m-$dx) * $this->R($dy-$n);
return $r;
}
private function denull($d)
{
//Substituting null values with nearest known values as per "A Review of Some Image Pixel Interpolation Algorithms" by Don Lancaster (supposed to produce same output as example image)
if ($d[0][1]===null) for ($i=0; $i<4; $i++) $d[0][$i]=$d[1][$i];
if ($d[1][0]===null) for ($i=0; $i<4; $i++) $d[$i][0]=$d[$i][1];
if ($d[3][1]===null) for ($i=0; $i<4; $i++) $d[3][$i]=$d[2][$i];
if ($d[1][3]===null) for ($i=0; $i<4; $i++) $d[$i][3]=$d[$i][2];
return $d;
}
function R($x)
{
return ( $this->P($x+2)
- 4 * $this->P($x+1)
+ 6 * $this->P($x)
- 4 * $this->P($x-1) )/6;
}
function P($x)
{
if ($x>0) return $x*$x*$x;
return 0;
}