Я пытаюсь реализовать алгоритм бикубической интерполяции для восстановления данных с более высоким разрешением из карты высот. После некоторых фальстартов и наборов инструкций, содержащих почти непонятную математику (прошло несколько лет с тех пор, как я занимался исчислением, и я больше не помню ничего, кроме основ), я нашел статью «Бикубическая интерполяция для масштабирования изображения» Пола Бурка, содержащую то, что оказался довольно простым и легко реализуемым алгоритмом. 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;
}