Что не так с этим кодом на фильтре Собеля?

Я пытаюсь реализовать Собела фильтр в PHP GD, но что-то не так с моим кодом:

$gd = imagecreatefrompng('base.png');
$width = imagesx($gd);
$height = imagesx($gd);

for($i=1; $i<$width-1;$i++){
for($j=1;$j<$height-1; $j++){
$pixelMatrix[0][0]= getColor($gd, $i-1,$j-1);
$pixelMatrix[0][1]= getColor($gd, $i-1,$j);
$pixelMatrix[0][2]= getColor($gd, $i-1,$j+1);
$pixelMatrix[1][0]= getColor($gd, $i,$j-1);
$pixelMatrix[1][2]= getColor($gd, $i,$j+1);
$pixelMatrix[2][0]= getColor($gd, $i+1,$j-1);
$pixelMatrix[2][1]= getColor($gd, $i+1,$j);
$pixelMatrix[2][2]= getColor($gd, $i+1,$j+1);

$edge=(int) convolution($pixelMatrix);
if($edge>255) $edge = 255;
imagesetpixel($gd, $i, $j, imagecolorallocate($gd,$edge,$edge,$edge));
}

}

function getColor($gd, $x, $y){
$rgb = @imagecolorat($gd, $x, $y);
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;
return round($r * 0.3 + $g * 0.59 + $b * 0.11); // gray
}

function convolution($pixelMatrix){

$gy=($pixelMatrix[0][0]*-1)+($pixelMatrix[0][1]*-2)+($pixelMatrix[0][2]*-1)+($pixelMatrix[2][0])+($pixelMatrix[2][1]*2)+($pixelMatrix[2][2]*1);
$gx=($pixelMatrix[0][0])+($pixelMatrix[0][2]*-1)+($pixelMatrix[1][0]*2)+($pixelMatrix[1][2]*-2)+($pixelMatrix[2][0])+($pixelMatrix[2][2]*-1);
return sqrt(pow($gy,2)+pow($gx,2));

}// send PNG to browser
header("Content-type: image/png");
imagepng($gd);

Базовое изображение:

введите описание изображения здесь

Правильный результат изображения:

введите описание изображения здесь

Мой результат:

введите описание изображения здесь

Для этого изображения ребро содержит значение int от 0 до 990, поэтому я ограничиваю его значением 255. Если я снимаю крышку, все, что я получаю, это шум. Я предполагаю, что ошибка в переводе края в значения RGB (я не понимаю эту часть) в imagesetpixel, нет?

2

Решение

Есть несколько неправильных вещей, как отмечено в комментариях, но большая часть вашего кода довольно правильна.

Основные вещи:

  • Исходное изображение может быть в палитре
  • Невозможно сделать Собеля на месте — вам нужно вывести изображение
  • У вас есть опечатка, где получение высоты

И это главным образом, я думаю!

$gd = imagecreatefrompng('base.png');
imagepalettetotruecolor($gd);        // IN CASE PALETTISED
$width = imagesx($gd);
$height = imagesy($gd);              // NOT imagesx()
$result=imagecreatetruecolor($width,$height); // CREATE OUTPUT IMAGE

for($i=1; $i<$width-1;$i++){
for($j=1;$j<$height-1; $j++){
$pixelMatrix[0][0]= getColor($gd, $i-1,$j-1);
$pixelMatrix[0][1]= getColor($gd, $i-1,$j);
$pixelMatrix[0][2]= getColor($gd, $i-1,$j+1);
$pixelMatrix[1][0]= getColor($gd, $i,$j-1);
$pixelMatrix[1][2]= getColor($gd, $i,$j+1);
$pixelMatrix[2][0]= getColor($gd, $i+1,$j-1);
$pixelMatrix[2][1]= getColor($gd, $i+1,$j);
$pixelMatrix[2][2]= getColor($gd, $i+1,$j+1);

$edge=(int) convolution($pixelMatrix);
if($edge>255) $edge = 255;
imagesetpixel($result, $i, $j, imagecolorallocate($result,$edge,$edge,$edge));
}
}

imagepng($result,"result.png");

function getColor($gd, $x, $y){
$rgb = @imagecolorat($gd, $x, $y);
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;
return round($r * 0.3 + $g * 0.59 + $b * 0.11); // gray
}

function convolution($pixelMatrix){

$gy=($pixelMatrix[0][0]*-1)+($pixelMatrix[0][1]*-2)+($pixelMatrix[0][2]*-1)+($pixelMatrix[2][0])+($pixelMatrix[2][1]*2)+($pixelMatrix[2][2]*1);
$gx=($pixelMatrix[0][0])+($pixelMatrix[0][2]*-1)+($pixelMatrix[1][0]*2)+($pixelMatrix[1][2]*-2)+($pixelMatrix[2][0])+($pixelMatrix[2][2]*-1);
return sqrt(pow($gy,2)+pow($gx,2));

}

введите описание изображения здесь

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]