How to fix my radon transformation?

I am creating a radon conversion after this article in PHP.

But my result does not match the expected result.

Input :

Expected Result :

Actual result :

...

I intentionally work with RGB instead of grayscale because I want to use this method for the fingerprint of an image. In the end, the number of channels should not matter much, right?


Time for a code.

The main function :
This is the main function that does most of the work:

function RadonTransform($filename) { $i = imagecreatefromjpeg($filename); $size = getimagesize($filename); $center = new Vector2($size[0] / 2, $size[1] / 2); $d = min(array($size[0], $size[1])); $u2 = round(M_PI * ($d / 2.0)); $r = imagecreatetruecolor($u2, $d); for ($z = 0; $z < $u2; $z++) { $w2 = M_PI * ($z / $u2); $w4 = M_PI / 2.0; $c1 = new Vector2(cos($w2), sin($w2)); $c1->Multiply($d / 2.0)->Add($center); $c2 = new Vector2(cos($w2 + M_PI), sin($w2 + M_PI)); $c2->Multiply($d / 2.0)->Add($center); $c3 = new Vector2(cos($w2 + $w4), sin($w2 + $w4)); $c3->Multiply($d / 2.0)->Add($center); $c4 = new Vector2(cos($w2 + 3 * $w4), sin($w2 + 4 * $w4)); $c4->Multiply($d / 2.0)->Add($center); $c = Vector2::sSubstract($c2, $c1)->Divide(2); $m = Vector2::sSubstract($c4, $c3); for ($x = 0; $x < $d; $x++) { $p1 = Vector2::sAdd($c3, Vector2::sMultiply($m, ($x / $d)))->Substract($c); $p2 = Vector2::sAdd($c3, Vector2::sMultiply($m, ($x / $d)))->Add($c); $color = imageGetLine($i, round($p1->x), round($p1->y), round($p2->x), round($p2->y)); imagesetpixel($r, $z + 1, $x + 1, imagecolorallocate($r, array_sum($color['r']), array_sum($color['g']), array_sum($color['b']))); } } return $r; } 

Additional functions :
This is imageGetLine() to get a straight (but possibly diagonal) sample line from the input image.

 function imageGetLine($i, $sx, $sy, $tx, $ty) { $r = array( 'r' => array(), 'g' => array(), 'b' => array() ); if (abs($tx - $sx) > abs($ty - $sy)) { if ($sx > $tx) { $tmp = $sx; $sx = $tx; $tx = $tmp; } for ($x = $sx; $x < $tx; $x++) { $y = $sy + ($x - $sx) / ($tx - $sx) * ($ty - $sy); $color = imageGetColorAt($i, $x, $y); $r['r'][] = $color['r']; $r['g'][] = $color['g']; $r['b'][] = $color['b']; } } else { if ($sy > $ty) { $tmp = $sy; $sy = $ty; $ty = $tmp; } for ($y = $sy; $y < $ty; $y++) { $x = $sx + ($y - $sy) / ($ty - $sy) * ($tx - $sx); $color = imageGetColorAt($i, $x, $y); if ($color === false) continue; $r['r'][] = $color['r']; $r['g'][] = $color['g']; $r['b'][] = $color['b']; } } return $r; } 

imageGetColorAt() does nothing but get the color of the pixel at a given position:

 function imageGetColorAt($i, $x, $y) { // @todo nearest resampling instead of rounding $color = @imagecolorat($i, round($x), round($y)); if ($color === false) return false; return array( 'r' => ($color >> 16) & 0xFF, 'g' => ($color >> 8) & 0xFF, 'b' => $color & 0xFF ); } 

The Vector2 class can be viewed here: https://github.com/cobrafast/prophp/blob/master/Math/vector2.class.php


One of the problems I am facing is that inside imageGetColorAt() I get a few out of bounds (because apparently GD is calculated from 0 to n-1 ) which I just disabled using @ and let it return false to skip, since I have no idea how to fix all the math that leads to the coordinates given for imageGetLine() .
Could this be the cause of my serious problems?

Where did I go wrong in my endeavors? Did I miss something?


Edit 2013-11-05

After doing this for a while with me, I’m close now:

What I added cut off my color values ​​to {0..255} and divided the number of rows selected by the number of samples (so that I get the average row value):

 ... for ($x = 0; $x < $d; $x++) { $p1 = Vector2::sAdd($c3, Vector2::sMultiply($m, ($x / $d)))->Substract($c); $p2 = Vector2::sAdd($c3, Vector2::sMultiply($m, ($x / $d)))->Add($c); $color = imageGetLine($i, round($p1->x), round($p1->y), round($p2->x), round($p2->y)); $color = normalizeColor(array( 'r' => array_sum($color['r']) / count($color['r']), 'g' => array_sum($color['g']) / count($color['g']), 'b' => array_sum($color['b']) / count($color['b']) )); imagesetpixel($r, $z + 1, $x + 1, imagecolorallocate($r, $color['r'], $color['g'], $color['b'])); } ... 

As normalizeColor says nothing but:

 return array( 'r' => min(array(255, max(array(0, $color['r'])))), 'g' => min(array(255, max(array(0, $color['g'])))), 'b' => min(array(255, max(array(0, $color['b'])))) ); 

But obviously, something still seems wrong ...

+6
source share
1 answer
 for ($z = 3*$u2/4; $z < $u2*7/4; $z++) { ... $c4 = ... sin($w2 + 3 * $w4) ... // it was sin($w2 + 4 * $w4) ... for ($x = 0; $x < $d; $x++) { imagesetpixel($r, $z - 3*$u2/4, $x, ...); } } 

Actual result

+1
source

Source: https://habr.com/ru/post/957061/


All Articles