Php 如何修复我的radon转换?

Php 如何修复我的radon转换?,php,math,transformation,php-gd,Php,Math,Transformation,Php Gd,在PHP中,我正在构建radon转换 但我的输出并不是预期的结果 输入: 预期结果: 实际结果: 我有意使用RGB而不是灰度,因为我想使用这种方法进行图像指纹。最终,频道的数量应该不会太重要,对吧 现在是编写代码的时候了 主要功能: 这是主要功能,做了很多实际工作: function RadonTransform($filename) { $i = imagecreatefromjpeg($filename); $size = getimagesize($filenam

在PHP中,我正在构建radon转换

但我的输出并不是预期的结果

输入

预期结果

实际结果

我有意使用RGB而不是灰度,因为我想使用这种方法进行图像指纹。最终,频道的数量应该不会太重要,对吧


现在是编写代码的时候了

主要功能
这是主要功能,做了很多实际工作:

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;
}
imageGetColorAt()
只检索给定位置的像素颜色:

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
    );
}
可以在此处查看
Vector2
类:


我面临的一个问题是,在
imageGetColorAt()
中,我得到了一些
超出范围的
(因为GD显然从
0
计数到
n-1
)错误,我只是用
@
静音,然后让它返回
false
跳过,因为我不知道如何修复导致
imageGetLine()

这可能是我的大麻烦的原因吗

我的努力哪里出错了?我错过了什么吗


编辑2013-11-05 在自己摆弄了一段时间之后,我现在离它很近了:

我添加的是将我的颜色值剪切到
{0..255}
,并将线样本总和除以样本量(这样我就可以得到一条线的平均值):

但很明显,$z=3*$u2/4;$z<$u2*7/4;$z++)似乎仍然有问题……

{
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, ...);
  }
}
... $c4=…sin($w2+3*$w4)//是sin($w2+4*$w4) ... 对于($x=0;$x<$d;$x++){ imagesetpixel($r,$z-3*$u2/4,$x,…); } }

请发布一个真正的工作代码,包括
imageGetColorAt()
函数。我无法得到你的“实际结果”。@clover好的,我添加了更多的代码信息。@Cobra\u Fast:用它做指纹有什么想法?你能解释一下吗?@Phpdna的想法是简化结果,并将其用作识别类似图像的图像指纹。还有其他文章和参考资料将此作为一种可行的、健壮的技术用于此任务。所以我只是想试试。@Cobra_Fast:我明白了。还有更简单的算法,比如phash。谢谢。到目前为止,这是可行的。你能解释一下吗?此外,当将结果与原始文章的预期结果进行比较时,您的结果会倒转并向左移动。在笛卡尔坐标系中,Y轴朝上,在计算机图形学中,Y轴朝下。您可以使用
imagesetpixel($r,$z-3*$u2/4,$d-$x,…)修复它按Y轴反转。根据文章
X轴=0到π的角度
,但它不在这个实现(=Pi*3/4…Pi*7/4)中,我不知道为什么。是的,您的更改
3*$u2/4$我不明白u2*7/4是什么。那是从哪里来的?我可以看到它右移了1/4。。。所以你们需要用y轴倒转第一个1/4的部分,然后把它追加到右边。我刚在尝试时注意到它,
$r=ImageCreateTureColor($u2*2,$d);对于($z=0;$z<$u2*2;$z++)…
...
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']));
}
...
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']))))
);
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, ...);
  }
}