2016-07-02 1 views
2

Я пытаюсь реализовать sobel фильтр в PHP GD, но что-то случилось с моим кодом:Что не так с этим кодом на фильтре Sobel?

$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); 

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

enter image description here

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

enter image description here

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

enter image description here

Для этого изображения край содержит 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)); 

} 

enter image description here

+0

Это огромное спасибо! На стороне: Любая идея, почему мой алгоритм выглядит ярче, чем в wikipedia? – kosinix

+0

Не знаете, почему разница в яркости - возможно, они использовали разные весы RGB, чтобы получить серый цвет, или, может быть, их нормализовать, так что самый яркий пиксель выходит на 255 и все остальные относительно этого, тогда как вы просто снимаете самые яркие пиксели и оставьте другие не затронуты. В любом случае, пожалуйста, подумайте о том, чтобы принять ответ - нажав на вышитую галочку (галочку) рядом с подсчетом голосов и удачи в вашем проекте! –

+0

'return round ($ r * 0.3 + $ g * 0.59 + $ b * 0.11);' в чем причина веса 0.3.0.59 и 0.11. Я не мог понять код здесь –

Смежные вопросы