按颜色排序10,000张图像

时间:2012-10-16 07:44:41

标签: php sorting image-processing

我有10,000张图像,我想按颜色排序以进行打印。

我已经走得很远了。我已经平均了他们的颜色,所以现在我有两个目录:一个包含所有原始图像(original_images /),另一个包含平均颜色的平均颜色(平均值/)。

接下来,我使用PHP对平均图像进行排序:

// $images is an array with all the filenames.
$sorted_images = array();
$loop_limit = count($images);
for($i = 0; $i < $loop_limit; $i++) {
    $image = imagecreatefromjpeg("averages/" . $images[$i]);
    $rgb = imagecolorat($image, 50, 50);
    imagedestroy($image);
    $r = ($rgb >> 16) & 0xFF;
    $g = ($rgb >> 8) & 0xFF;
    $b = $rgb & 0xFF;
    $hsv = rgb_to_hsv($r, $g, $b); // function to convert rgb to Hue/Sat/Value
    $h = (string) $hsv['H'];
    if(isset($sorted_h[$h])) {
        $duplicates++;
        echo("oh no! " . $h . " is a dupe! found " . $duplicates . " duplicates so far.<br>");
    }
    $sorted_h[$h] = $images[$i];
}

// sort the array by key:
ksort($sorted_images, SORT_NUMERIC);

编辑问题是,密钥$h的范围从(显然)-0.1666666667到1左右。我的直觉说,存在重复值的可能性很小,但是事实证明,有超过6000个重复的密钥。我尝试将$h值转换为字符串,因为我认为数组键可能是舍入的?

虽然没有用。这是将rgb转换为HSV的功能。我发现它没有任何文件......

function RGB_TO_HSV ($R, $G, $B) { 
    $HSV = array();

    $var_R = ($R / 255);
    $var_G = ($G / 255);
    $var_B = ($B / 255);

    $var_Min = min($var_R, $var_G, $var_B);
    $var_Max = max($var_R, $var_G, $var_B);
    $del_Max = $var_Max - $var_Min;

    $V = $var_Max;

    if ($del_Max == 0)
    {
        $H = 0;
        $S = 0;
    }
    else
    {
        $S = $del_Max / $var_Max;

        $del_R = ( ( ( $max - $var_R ) / 6 ) + ( $del_Max / 2 ) ) / $del_Max;
        $del_G = ( ( ( $max - $var_G ) / 6 ) + ( $del_Max / 2 ) ) / $del_Max;
        $del_B = ( ( ( $max - $var_B ) / 6 ) + ( $del_Max / 2 ) ) / $del_Max;

        if ($var_R == $var_Max) $H = $del_B - $del_G;
        else if ($var_G == $var_Max) $H = ( 1 / 3 ) + $del_R - $del_B;
        else if ($var_B == $var_Max) $H = ( 2 / 3 ) + $del_G - $del_R;

        if (H<0) $H++;
        if (H>1) $H--;
    }

    $HSV['H'] = $H;
    $HSV['S'] = $S;
    $HSV['V'] = $V;

    return $HSV;
}

现在的问题是:

  1. rgb_to_hsv() - 函数是否正确?
  2. 如何确保数组中的键没有被覆盖,但值是否(密切)保持?例如;如果两个图像的$ h值为0.01111111111,当第二个图像被推送到数组时,它的关键应该是0.01111111112?
  3. (旧编辑:) 修改:我已将rename()更改为copy(),这样每次出错时我都无需重新上传10,000张图片;-)。我还使用ini_set("max_execution_time", 300);将最高执行时间从60增加到300,添加imagedestroy($image)以减少内存使用量,并通过将$i < count($images)更改为$loop_limit = count($images)来改进for for循环

    编辑2:好的,所以我发现了一个问题。图像的$ h(Hue)值时不时相同。因此,使用sorted_images[$h] = $images[$i]会覆盖数组中该键的值。事实上;结果是超过6000个重复的值...我怎样才能解决这个问题,而不会过多地贬低$ h值?

2 个答案:

答案 0 :(得分:1)

您可能会遇到max_execution_time - 允许脚本运行的时间限制。尝试设置更高的值。

http://php.net/manual/de/function.set-time-limit.php

您是否收到任何错误消息?

答案 1 :(得分:1)

您是否尝试过启用错误消息?

error_reporting(E_ALL);
ini_set('display_errors', 1);

至于本地vs主值。 'local'表示当前运行的脚本使用300秒的超时。 'master'适用于所有其他请求(除非明确修改)

Cron是一种可行的方式,但我不认为这应该每X秒/分钟/小时执行多次?您可以自己使用命令行来执行此操作。在此处查看更多信息:http://www.php.net/manual/en/features.commandline.usage.php

看到脚本有效,它很可能是以下问题之一:

memory_limit不够高。应该在启用错误的情况下给出PHP错误。 执行时间不够高。应该在启用错误的情况下给出PHP错误。

使用init_set方法增加两者,如果你只是想让脚本运行,将timeout设置为0秒,内存限制尽可能高。如果你想真正了解究竟是什么原因,你可能会考虑查找'xdebug'以查看是否存在任何内存泄漏或哪些命令执行时间最长。看一下代码,我假设复制命令需要一段时间才能执行(超过1ms,10000次迭代后很多)

如果无法修改这些值,或者您只是想使用资源有限的高内存,长执行时脚本,请尝试重写脚本以批量执行重命名并将cron设置为每隔X分钟执行一次脚本(只需在完成所有图像后删除cron)

祝你好运:)