1

我正在开发一个 PHP 图像处理库,该库处理来自游戏的渲染图像,在 PHP 网络主机上进行处理。为了处理图像,我需要找到红色岛屿(色调在 x 0 或 360 的范围内),并在其中找到一个点(不一定是中心,但最好靠近中心)。大约有 100 个这样的岛屿,大小不一。它们是梯形或接近梯形。由于图像是 PNG,并且未压缩且没有抗锯齿,因此边缘清晰到像素,但某些区域可能比其他区域更暗。

目前,我尝试imagecolorat(在 GD 中使用并在转换后测试 HSV 值,然后尝试围绕它的点,直到我到达非红色像素,但该过程似乎需要一些时间才能完成,并且似乎遇到 PHP 超时到 5 秒的限制,如果我正在处理一个大图像。有没有更有效的方法来检测所述岛屿并获得一个不一定在中心的点,但最好在附近?

我也尝试过,我知道梯形的大小,假设没有人进入一定的距离并跳过该距离以节省时间。

我不一定需要代码,只需要一个指向正确方向的指针。

我当前的代码:

function RGBToHSL($RGB) {
    $r = 0xFF & ($RGB >> 0x10);
    $g = 0xFF & ($RGB >> 0x8);

//截图 }

$image=imagecreatefrompng($filename);
$redislands=[];
for($xpos=0; $xpos<=imagesx($image); $xpos++){
    for($ypos=0; $ypos<=imagesy($image); $ypos++){
        if (RGBToHSL(imagecolorat(xpos, ypos)->saturation<=20||RGBToHSL(imagecolorat(xpos, ypos)->saturation>=350){
            $redislands[]=[xpos, ypos]
            }
        }
    }
4

1 回答 1

0

我还没有真正使用过gd,但我只是简单地看了看,我明白了

imagefilter()IMG_FILTER_EDGEDETECT标志。

似乎在那之后,您可以使用一个简单的循环识别所有对象(如果对象具有最小大小,您可以使循环使用此条带大小,并且仍然可以保证您会遇到每个对象)。只需寻找带有边缘颜色的像素,当你找到一个时,递归地探索带有边缘颜色的相邻像素。例如,如果一个对象保证至少有 7 个像素高,则在突出显示边缘后,您只需循环遍历第 0、7、14、21 行等中的像素...

一旦你通过使用它周围的边缘提取了组件,我认为你可以很容易地识别它的形状、颜色和中心。

如果边缘没有被可靠地检测到,您可能需要对图像进行阈值处理(gd 可以这样做)。

另一个需要认真考虑的选择是不使用 php,而是使用 php 的 exec() 函数执行外部程序。这开启了使用各种库(如 opencv)和用于这些东西的程序的可能性。它还可以让你用 c 之类的东西编写代码……你会惊讶于你可以在包含几百万个表示像素颜色的整数的 ac 数组上循环的速度有多快。但是,我觉得这对你来说不是一个可行的选择。

您可能会调查的其他事情是访问像素的 php 数组(或字符串)。函数调用开销很大,与像$pixels[$i]. 我对图像格式一无所知,但也许您可以保存为位图,然后将其加载到字符串中,然后只使用字符串偏移量。我敢打赌,如果位图具有合适的类似数组的二进制表示形式,那它就会飞起来。

于 2012-12-29T17:33:21.977 回答